@aalis/runtime 0.4.0 → 0.5.0
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/dist/bootstrap-buffer.d.ts +33 -0
- package/dist/bootstrap-buffer.d.ts.map +1 -0
- package/dist/bootstrap-buffer.js +42 -0
- package/dist/bootstrap-buffer.js.map +1 -0
- package/dist/console-sink.d.ts +35 -0
- package/dist/console-sink.d.ts.map +1 -0
- package/dist/console-sink.js +102 -0
- package/dist/console-sink.js.map +1 -0
- package/dist/file-logger.d.ts +8 -0
- package/dist/file-logger.d.ts.map +1 -0
- package/dist/file-logger.js +39 -0
- package/dist/file-logger.js.map +1 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -6
- package/dist/index.js.map +1 -1
- package/dist/node-modules-loader.d.ts +2 -2
- package/dist/node-modules-loader.d.ts.map +1 -1
- package/dist/node-modules-loader.js +9 -15
- package/dist/node-modules-loader.js.map +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.d.ts.map +1 -1
- package/dist/providers.js +35 -7
- package/dist/providers.js.map +1 -1
- package/dist/start.d.ts +17 -4
- package/dist/start.d.ts.map +1 -1
- package/dist/start.js +68 -4
- package/dist/start.js.map +1 -1
- package/dist/subcommand.d.ts +13 -0
- package/dist/subcommand.d.ts.map +1 -0
- package/dist/subcommand.js +32 -0
- package/dist/subcommand.js.map +1 -0
- package/dist/terminal.d.ts +3 -0
- package/dist/terminal.d.ts.map +1 -0
- package/dist/terminal.js +24 -0
- package/dist/terminal.js.map +1 -0
- package/package.json +4 -2
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type LogEntry, LogHub } from '@aalis/core';
|
|
2
|
+
/**
|
|
3
|
+
* 启动期 bootstrap buffer:在任何 sink(file/console)装好之前订阅 LogHub,
|
|
4
|
+
* 把启动期产生的所有 LogEntry 暂存。等所有 sink 装好后调用 `dispose()`
|
|
5
|
+
* 解除订阅并清空——之后所有日志直接通过 LogHub.onEntry 走 sink 实时落盘 / 渲染。
|
|
6
|
+
*
|
|
7
|
+
* 设计要点:
|
|
8
|
+
* - **进程级单例**:通过 module-level state 实现,必须由 `src/index.ts` 在最早
|
|
9
|
+
* 时机调用 `installBootstrapBuffer()` 一次(在 Logger 第一次被调用之前)。
|
|
10
|
+
* - **多 sink 共享**:每个 sink 装载时调用 `snapshot()` 拿到当前已捕获条目副本
|
|
11
|
+
* 并自行消费(写文件 / 渲染 stdout);snapshot 不改变状态,可任意次。
|
|
12
|
+
* - **显式 dispose**:所有 sink 装好后由 host 显式 `dispose()` —— 之后 buffer
|
|
13
|
+
* 不再接收新条目,但已订阅的 sink 通过 `LogHub.onEntry` 继续收实时事件。
|
|
14
|
+
* - **核心零状态**:LogHub 自身不再持有 buffer,bootstrap 这种"短暂状态"是
|
|
15
|
+
* runtime 关注点,不污染 core。
|
|
16
|
+
*/
|
|
17
|
+
interface BootstrapBuffer {
|
|
18
|
+
/** 当前已捕获 entries 的副本。可重复调用。 */
|
|
19
|
+
snapshot(): LogEntry[];
|
|
20
|
+
/** 解除订阅 + 清空。重复调用幂等。 */
|
|
21
|
+
dispose(): void;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 安装 bootstrap buffer。必须在所有日志产生之前调用(即 `src/index.ts` 顶部)。
|
|
25
|
+
* 重复调用返回同一实例。
|
|
26
|
+
*/
|
|
27
|
+
export declare function installBootstrapBuffer(hub?: LogHub): BootstrapBuffer;
|
|
28
|
+
/** 获取已安装的 bootstrap buffer。未安装则返回空 stub(snapshot 永远空)。 */
|
|
29
|
+
export declare function getBootstrapBuffer(): BootstrapBuffer;
|
|
30
|
+
/** 测试钩子:重置 installed 状态。仅供单元测试使用。 */
|
|
31
|
+
export declare function __resetBootstrapBufferForTests(): void;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=bootstrap-buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-buffer.d.ts","sourceRoot":"","sources":["../src/bootstrap-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAEpD;;;;;;;;;;;;;;GAcG;AACH,UAAU,eAAe;IACvB,+BAA+B;IAC/B,QAAQ,IAAI,QAAQ,EAAE,CAAC;IACvB,wBAAwB;IACxB,OAAO,IAAI,IAAI,CAAC;CACjB;AAID;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAuB,GAAG,eAAe,CAuBpF;AAED,0DAA0D;AAC1D,wBAAgB,kBAAkB,IAAI,eAAe,CAGpD;AAED,qCAAqC;AACrC,wBAAgB,8BAA8B,IAAI,IAAI,CAGrD"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { LogHub } from '@aalis/core';
|
|
2
|
+
let installed = null;
|
|
3
|
+
/**
|
|
4
|
+
* 安装 bootstrap buffer。必须在所有日志产生之前调用(即 `src/index.ts` 顶部)。
|
|
5
|
+
* 重复调用返回同一实例。
|
|
6
|
+
*/
|
|
7
|
+
export function installBootstrapBuffer(hub = LogHub.default) {
|
|
8
|
+
if (installed)
|
|
9
|
+
return installed;
|
|
10
|
+
let entries = [];
|
|
11
|
+
let disposed = false;
|
|
12
|
+
const off = hub.onEntry(entry => {
|
|
13
|
+
if (!disposed)
|
|
14
|
+
entries.push(entry);
|
|
15
|
+
});
|
|
16
|
+
const handle = {
|
|
17
|
+
snapshot() {
|
|
18
|
+
return entries.slice();
|
|
19
|
+
},
|
|
20
|
+
dispose() {
|
|
21
|
+
if (disposed)
|
|
22
|
+
return;
|
|
23
|
+
disposed = true;
|
|
24
|
+
entries = [];
|
|
25
|
+
off();
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
installed = handle;
|
|
29
|
+
return handle;
|
|
30
|
+
}
|
|
31
|
+
/** 获取已安装的 bootstrap buffer。未安装则返回空 stub(snapshot 永远空)。 */
|
|
32
|
+
export function getBootstrapBuffer() {
|
|
33
|
+
if (installed)
|
|
34
|
+
return installed;
|
|
35
|
+
return { snapshot: () => [], dispose: () => { } };
|
|
36
|
+
}
|
|
37
|
+
/** 测试钩子:重置 installed 状态。仅供单元测试使用。 */
|
|
38
|
+
export function __resetBootstrapBufferForTests() {
|
|
39
|
+
installed?.dispose();
|
|
40
|
+
installed = null;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=bootstrap-buffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap-buffer.js","sourceRoot":"","sources":["../src/bootstrap-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,MAAM,EAAE,MAAM,aAAa,CAAC;AAwBpD,IAAI,SAAS,GAA2B,IAAI,CAAC;AAE7C;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAc,MAAM,CAAC,OAAO;IACjE,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAEhC,IAAI,OAAO,GAAe,EAAE,CAAC;IAC7B,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QAC9B,IAAI,CAAC,QAAQ;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAoB;QAC9B,QAAQ;YACN,OAAO,OAAO,CAAC,KAAK,EAAE,CAAC;QACzB,CAAC;QACD,OAAO;YACL,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,EAAE,CAAC;QACR,CAAC;KACF,CAAC;IAEF,SAAS,GAAG,MAAM,CAAC;IACnB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,kBAAkB;IAChC,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAChC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;AACnD,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,8BAA8B;IAC5C,SAAS,EAAE,OAAO,EAAE,CAAC;IACrB,SAAS,GAAG,IAAI,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Context } from '@aalis/core';
|
|
2
|
+
/**
|
|
3
|
+
* 运行时层注入的事件——`@aalis/core` 不感知"终端归属"这件事,
|
|
4
|
+
* 仅靠 EventBus 的字符串事件名传递。
|
|
5
|
+
*
|
|
6
|
+
* - `terminal:claimed`:某 UI(CLI/TUI)开始独占 stdout(alt-screen/raw-mode)
|
|
7
|
+
* - `terminal:released`:归还 stdout
|
|
8
|
+
*/
|
|
9
|
+
declare module '@aalis/core' {
|
|
10
|
+
interface AalisEvents {
|
|
11
|
+
'terminal:claimed': [owner: string];
|
|
12
|
+
'terminal:released': [owner: string];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export interface ConsoleSinkHandle {
|
|
16
|
+
dispose(): void;
|
|
17
|
+
/**
|
|
18
|
+
* 在 App 构造完成后绑定其事件总线:sink 开始监听 `terminal:claimed/released`,
|
|
19
|
+
* 当任何 UI 接管终端时自动停止写 stdout。
|
|
20
|
+
*
|
|
21
|
+
* 必须显式调用——`installConsoleSink()` 在 App 之前运行(需要捕获最早期日志),
|
|
22
|
+
* 此时没有 ctx 可订阅。
|
|
23
|
+
*/
|
|
24
|
+
bindEvents(ctx: Context): void;
|
|
25
|
+
/** 当前是否染色输出(供调试 / 状态视图使用) */
|
|
26
|
+
readonly colorized: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 安装 console sink:先冲洗启动前缓冲的日志,然后订阅后续 LogEntry。
|
|
30
|
+
*
|
|
31
|
+
* 与 CLI/TUI 等"独占终端 UI"的协调通过事件 `terminal:claimed/released` 完成,
|
|
32
|
+
* sink 自己根据事件决定是否写 stdout——UI 不直接干预 sink。
|
|
33
|
+
*/
|
|
34
|
+
export declare function installConsoleSink(): ConsoleSinkHandle;
|
|
35
|
+
//# sourceMappingURL=console-sink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console-sink.d.ts","sourceRoot":"","sources":["../src/console-sink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAK3C;;;;;;GAMG;AACH,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,WAAW;QACnB,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACpC,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;KACtC;CACF;AAwDD,MAAM,WAAW,iBAAiB;IAChC,OAAO,IAAI,IAAI,CAAC;IAChB;;;;;;OAMG;IACH,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,6BAA6B;IAC7B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,iBAAiB,CAyCtD"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { LogHub } from '@aalis/core';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { getBootstrapBuffer } from './bootstrap-buffer.js';
|
|
4
|
+
/**
|
|
5
|
+
* Console sink —— 运行时层的 stdout 输出(按需染色)。
|
|
6
|
+
*
|
|
7
|
+
* 与 file-logger 对偶:core 仅产生 LogEntry(零 I/O 知识),染色 / 终端假设全在本宿主层。
|
|
8
|
+
* 所有 stdout 输出都从这里走;webui-only / 嵌入式部署不装本 sink 即无需 chalk。
|
|
9
|
+
*
|
|
10
|
+
* 染色检测顺序(命中即决定):
|
|
11
|
+
* FORCE_COLOR=0 / FORCE_COLOR=false → 关闭
|
|
12
|
+
* FORCE_COLOR=其余值 → 开启
|
|
13
|
+
* NO_COLOR 非空 → 关闭
|
|
14
|
+
* process.stdout.isTTY === true → 开启
|
|
15
|
+
* 其余(重定向到文件 / CI / journald / Docker -d) → 关闭
|
|
16
|
+
*
|
|
17
|
+
* 这样 `node dist/index.js > app.log` 文件里不会留 ANSI escape codes。
|
|
18
|
+
*/
|
|
19
|
+
function shouldColorize() {
|
|
20
|
+
const force = process.env.FORCE_COLOR;
|
|
21
|
+
if (force !== undefined) {
|
|
22
|
+
if (force === '0' || force === 'false')
|
|
23
|
+
return false;
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
if (process.env.NO_COLOR)
|
|
27
|
+
return false;
|
|
28
|
+
return Boolean(process.stdout.isTTY);
|
|
29
|
+
}
|
|
30
|
+
const IDENTITY = (s) => s;
|
|
31
|
+
const COLORIZE = shouldColorize();
|
|
32
|
+
const LEVEL_COLORS = COLORIZE
|
|
33
|
+
? {
|
|
34
|
+
debug: chalk.gray,
|
|
35
|
+
info: chalk.cyan,
|
|
36
|
+
warn: chalk.yellow,
|
|
37
|
+
error: chalk.red,
|
|
38
|
+
}
|
|
39
|
+
: {
|
|
40
|
+
debug: IDENTITY,
|
|
41
|
+
info: IDENTITY,
|
|
42
|
+
warn: IDENTITY,
|
|
43
|
+
error: IDENTITY,
|
|
44
|
+
};
|
|
45
|
+
const dim = COLORIZE ? chalk.gray : IDENTITY;
|
|
46
|
+
const accent = COLORIZE ? chalk.magenta : IDENTITY;
|
|
47
|
+
function formatEntry(entry) {
|
|
48
|
+
const colorFn = LEVEL_COLORS[entry.level];
|
|
49
|
+
// LogEntry.timestamp 是完整 ISO(YYYY-MM-DDTHH:mm:ss.sssZ);stdout 只看当前运行,
|
|
50
|
+
// 取 HH:mm:ss.sss 部分即可(与原有显示一致),完整日期保留在 file/webui。
|
|
51
|
+
const shortTs = entry.timestamp.slice(11, 23);
|
|
52
|
+
const prefix = `${dim(shortTs)} ${colorFn(entry.level.toUpperCase().padEnd(5))} ${accent(entry.scope)}`;
|
|
53
|
+
return `${prefix} ${entry.message}`;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* 安装 console sink:先冲洗启动前缓冲的日志,然后订阅后续 LogEntry。
|
|
57
|
+
*
|
|
58
|
+
* 与 CLI/TUI 等"独占终端 UI"的协调通过事件 `terminal:claimed/released` 完成,
|
|
59
|
+
* sink 自己根据事件决定是否写 stdout——UI 不直接干预 sink。
|
|
60
|
+
*/
|
|
61
|
+
export function installConsoleSink() {
|
|
62
|
+
const hub = LogHub.default;
|
|
63
|
+
// 冲洗启动期 bootstrap buffer
|
|
64
|
+
for (const entry of getBootstrapBuffer().snapshot()) {
|
|
65
|
+
console.log(formatEntry(entry));
|
|
66
|
+
}
|
|
67
|
+
let paused = false;
|
|
68
|
+
const off = hub.onEntry(entry => {
|
|
69
|
+
if (paused)
|
|
70
|
+
return;
|
|
71
|
+
console.log(formatEntry(entry));
|
|
72
|
+
});
|
|
73
|
+
let unbind;
|
|
74
|
+
return {
|
|
75
|
+
dispose() {
|
|
76
|
+
off();
|
|
77
|
+
unbind?.();
|
|
78
|
+
},
|
|
79
|
+
bindEvents(ctx) {
|
|
80
|
+
// 多终端 owner(理论上不会同时)用计数器避免一个 release 提前解锁
|
|
81
|
+
let owners = 0;
|
|
82
|
+
const onClaim = () => {
|
|
83
|
+
owners += 1;
|
|
84
|
+
paused = true;
|
|
85
|
+
};
|
|
86
|
+
const onRelease = () => {
|
|
87
|
+
if (owners > 0)
|
|
88
|
+
owners -= 1;
|
|
89
|
+
if (owners === 0)
|
|
90
|
+
paused = false;
|
|
91
|
+
};
|
|
92
|
+
const offClaim = ctx.on('terminal:claimed', onClaim);
|
|
93
|
+
const offRelease = ctx.on('terminal:released', onRelease);
|
|
94
|
+
unbind = () => {
|
|
95
|
+
offClaim();
|
|
96
|
+
offRelease();
|
|
97
|
+
};
|
|
98
|
+
},
|
|
99
|
+
colorized: COLORIZE,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=console-sink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"console-sink.js","sourceRoot":"","sources":["../src/console-sink.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** 默认日志文件路径。webui-server 等下游目前各自硬编码同一相对路径。 */
|
|
2
|
+
export declare const DEFAULT_LOG_FILE = "data/latest.log";
|
|
3
|
+
export interface FileLoggerHandle {
|
|
4
|
+
flush(): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
export declare function appendCrashLog(label: string, err: unknown, logFile?: string): Promise<void>;
|
|
7
|
+
export declare function setupFileLogger(logFile?: string): Promise<FileLoggerHandle>;
|
|
8
|
+
//# sourceMappingURL=file-logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-logger.d.ts","sourceRoot":"","sources":["../src/file-logger.ts"],"names":[],"mappings":"AAKA,8CAA8C;AAC9C,eAAO,MAAM,gBAAgB,oBAAoB,CAAC;AAIlD,MAAM,WAAW,gBAAgB;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAOD,wBAAsB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,SAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAY3G;AAED,wBAAsB,eAAe,CAAC,OAAO,SAAmB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkB3F"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { appendFile, mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
import { formatLogLine, LogHub } from '@aalis/core';
|
|
4
|
+
import { getBootstrapBuffer } from './bootstrap-buffer.js';
|
|
5
|
+
/** 默认日志文件路径。webui-server 等下游目前各自硬编码同一相对路径。 */
|
|
6
|
+
export const DEFAULT_LOG_FILE = 'data/latest.log';
|
|
7
|
+
const RUNTIME_SCOPE = 'aalis:runtime';
|
|
8
|
+
function formatUnknownError(err) {
|
|
9
|
+
if (err instanceof Error)
|
|
10
|
+
return err.stack || err.message;
|
|
11
|
+
return typeof err === 'string' ? err : JSON.stringify(err);
|
|
12
|
+
}
|
|
13
|
+
export async function appendCrashLog(label, err, logFile = DEFAULT_LOG_FILE) {
|
|
14
|
+
await mkdir(dirname(logFile), { recursive: true });
|
|
15
|
+
await appendFile(logFile, formatLogLine({
|
|
16
|
+
seq: LogHub.default.allocSeq(),
|
|
17
|
+
timestamp: new Date().toISOString(),
|
|
18
|
+
level: 'error',
|
|
19
|
+
scope: RUNTIME_SCOPE,
|
|
20
|
+
message: `${label}: ${formatUnknownError(err)}`,
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
export async function setupFileLogger(logFile = DEFAULT_LOG_FILE) {
|
|
24
|
+
let queue = Promise.resolve();
|
|
25
|
+
await mkdir(dirname(logFile), { recursive: true });
|
|
26
|
+
const hub = LogHub.default;
|
|
27
|
+
// 启动期 entries 由 bootstrap-buffer 持有;作为文件初始内容写入。
|
|
28
|
+
const initial = getBootstrapBuffer().snapshot().map(formatLogLine).join('');
|
|
29
|
+
await writeFile(logFile, initial);
|
|
30
|
+
hub.onEntry(entry => {
|
|
31
|
+
queue = queue.then(() => appendFile(logFile, formatLogLine(entry))).catch(() => { });
|
|
32
|
+
});
|
|
33
|
+
return {
|
|
34
|
+
async flush() {
|
|
35
|
+
await queue.catch(() => { });
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=file-logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-logger.js","sourceRoot":"","sources":["../src/file-logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,8CAA8C;AAC9C,MAAM,CAAC,MAAM,gBAAgB,GAAG,iBAAiB,CAAC;AAElD,MAAM,aAAa,GAAG,eAAe,CAAC;AAMtC,SAAS,kBAAkB,CAAC,GAAY;IACtC,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,OAAO,CAAC;IAC1D,OAAO,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,KAAa,EAAE,GAAY,EAAE,OAAO,GAAG,gBAAgB;IAC1F,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,MAAM,UAAU,CACd,OAAO,EACP,aAAa,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE;QAC9B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,KAAK,EAAE,OAAO;QACd,KAAK,EAAE,aAAa;QACpB,OAAO,EAAE,GAAG,KAAK,KAAK,kBAAkB,CAAC,GAAG,CAAC,EAAE;KAChD,CAAC,CACH,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAO,GAAG,gBAAgB;IAC9D,IAAI,KAAK,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAE7C,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC;IAC3B,gDAAgD;IAChD,MAAM,OAAO,GAAG,kBAAkB,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5E,MAAM,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAElC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;QAClB,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,KAAK,CAAC,KAAK;YACT,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC9B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
export { getBootstrapBuffer, installBootstrapBuffer } from './bootstrap-buffer.js';
|
|
2
|
+
export { type ConsoleSinkHandle, installConsoleSink } from './console-sink.js';
|
|
3
|
+
export { appendCrashLog, DEFAULT_LOG_FILE, type FileLoggerHandle, setupFileLogger } from './file-logger.js';
|
|
1
4
|
export { createNodeModulesPluginLoader } from './node-modules-loader.js';
|
|
2
|
-
export { createFsPluginLoader, createFsYamlConfigProvider, createProcessRespawnStrategy
|
|
5
|
+
export { createFsPluginLoader, createFsYamlConfigProvider, createProcessRespawnStrategy } from './providers.js';
|
|
3
6
|
export { type StartAalisOptions, startAalis } from './start.js';
|
|
7
|
+
export { tryDispatchSubcommand } from './subcommand.js';
|
|
8
|
+
export { installTerminalStateRestorer, restoreTerminalState } from './terminal.js';
|
|
4
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,KAAK,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAChH,OAAO,EAAE,KAAK,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
// @aalis/runtime —— Aalis
|
|
1
|
+
// @aalis/runtime —— Aalis 默认 Node 宿主层(独立部署与 monorepo 自托管共用)
|
|
2
2
|
//
|
|
3
|
-
//
|
|
3
|
+
// 两种部署模型的加载器 + YAML 配置/重启策略 + 一行启动 startAalis,以及可移植宿主件
|
|
4
|
+
// (日志 sink / 终端复原 / 子命令分发)。core 只产生 LogEntry,染色/TTY/文件落盘全在本层。
|
|
4
5
|
// - createNodeModulesPluginLoader:纯 npm 独立部署(从 node_modules 解析插件)
|
|
5
6
|
// - createFsPluginLoader:monorepo 自托管(扫描 packages/ 目录)
|
|
6
7
|
// - createFsYamlConfigProvider / createProcessRespawnStrategy:YAML 配置 + 进程级重启
|
|
7
|
-
// - startAalis
|
|
8
|
-
//
|
|
9
|
-
|
|
8
|
+
// - startAalis:组装以上 + 宿主件为实例并启动(带 options 开关,默认独立部署)
|
|
9
|
+
// - install*/setup*/tryDispatchSubcommand:宿主件,供高级 opt-in 组装
|
|
10
|
+
export { getBootstrapBuffer, installBootstrapBuffer } from './bootstrap-buffer.js';
|
|
11
|
+
export { installConsoleSink } from './console-sink.js';
|
|
12
|
+
export { appendCrashLog, DEFAULT_LOG_FILE, setupFileLogger } from './file-logger.js';
|
|
10
13
|
export { createNodeModulesPluginLoader } from './node-modules-loader.js';
|
|
11
|
-
export { createFsPluginLoader, createFsYamlConfigProvider, createProcessRespawnStrategy
|
|
14
|
+
export { createFsPluginLoader, createFsYamlConfigProvider, createProcessRespawnStrategy } from './providers.js';
|
|
12
15
|
export { startAalis } from './start.js';
|
|
16
|
+
export { tryDispatchSubcommand } from './subcommand.js';
|
|
17
|
+
export { installTerminalStateRestorer, restoreTerminalState } from './terminal.js';
|
|
13
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAC5D,EAAE;AACF,uDAAuD;AACvD,8DAA8D;AAC9D,oEAAoE;AACpE,yDAAyD;AACzD,gFAAgF;AAChF,uDAAuD;AACvD,8DAA8D;AAE9D,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAA0B,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAyB,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,6BAA6B,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAChH,OAAO,EAA0B,UAAU,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { PluginLoader } from '@aalis/core';
|
|
2
2
|
/**
|
|
3
3
|
* 判定一个已装依赖是否为可加载的 Aalis 插件。纯函数,便于单测。
|
|
4
|
-
*
|
|
4
|
+
* 唯一标准:keywords 含 'aalis-plugin'(真插件均带;契约/前端/核心/工具库带各自类型词,自然排除)。
|
|
5
5
|
*/
|
|
6
|
-
export declare function isLoadablePlugin(
|
|
6
|
+
export declare function isLoadablePlugin(meta: Record<string, unknown>): boolean;
|
|
7
7
|
/**
|
|
8
8
|
* 创建一个从项目 node_modules 解析插件的 PluginLoader。
|
|
9
9
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-modules-loader.d.ts","sourceRoot":"","sources":["../src/node-modules-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAoB,YAAY,EAAgB,MAAM,aAAa,CAAC;AAyBhF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"node-modules-loader.d.ts","sourceRoot":"","sources":["../src/node-modules-loader.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAoB,YAAY,EAAgB,MAAM,aAAa,CAAC;AAyBhF;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAGvE;AAED;;;;;;;;;GASG;AACH,wBAAgB,6BAA6B,CAAC,UAAU,GAAE,MAAsB,GAAG,YAAY,CAqD9F"}
|
|
@@ -12,11 +12,11 @@ import { pathToFileURL } from 'node:url';
|
|
|
12
12
|
// @aalis 插件并 dynamic import。与 monorepo 的 createFsPluginLoader 是「两种部署
|
|
13
13
|
// 模型的两个加载器」,非重复:前者扫目录,后者走 node 解析。
|
|
14
14
|
//
|
|
15
|
-
//
|
|
16
|
-
// -
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
// 与 express/yaml
|
|
15
|
+
// 插件识别(纯正向关键词门):
|
|
16
|
+
// - 唯一标准:package.json 的 keywords 含 'aalis-plugin'。
|
|
17
|
+
// 每类包各带自己的类型关键词(插件 aalis-plugin / 契约 aalis-api / 前端 aalis-interface / 工具库 aalis-util /
|
|
18
|
+
// 核心 aalis-core / 工具链 aalis-runtime,后几类均不带 aalis-plugin),所以 @aalis/core、各 *-api、webui-client、
|
|
19
|
+
// @aalis/runtime、各 util-* 与 express/yaml 等普通依赖都因不带 aalis-plugin 而自然不被加载——无需 marker 特判或名前缀/service 回退。
|
|
20
20
|
function readJson(path) {
|
|
21
21
|
try {
|
|
22
22
|
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
@@ -27,17 +27,11 @@ function readJson(path) {
|
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* 判定一个已装依赖是否为可加载的 Aalis 插件。纯函数,便于单测。
|
|
30
|
-
*
|
|
30
|
+
* 唯一标准:keywords 含 'aalis-plugin'(真插件均带;契约/前端/核心/工具库带各自类型词,自然排除)。
|
|
31
31
|
*/
|
|
32
|
-
export function isLoadablePlugin(
|
|
33
|
-
const aalis = (meta.aalis ?? {});
|
|
34
|
-
if (aalis.core || aalis.types || aalis.client || aalis.tooling)
|
|
35
|
-
return false;
|
|
32
|
+
export function isLoadablePlugin(meta) {
|
|
36
33
|
const keywords = Array.isArray(meta.keywords) ? meta.keywords : [];
|
|
37
|
-
return
|
|
38
|
-
/^@aalis\/plugin-/.test(name) ||
|
|
39
|
-
aalis.service !== undefined ||
|
|
40
|
-
aalis.subsystem !== undefined);
|
|
34
|
+
return keywords.includes('aalis-plugin');
|
|
41
35
|
}
|
|
42
36
|
/**
|
|
43
37
|
* 创建一个从项目 node_modules 解析插件的 PluginLoader。
|
|
@@ -72,7 +66,7 @@ export function createNodeModulesPluginLoader(projectDir = process.cwd()) {
|
|
|
72
66
|
continue; // 未安装或无法解析,跳过
|
|
73
67
|
}
|
|
74
68
|
const meta = readJson(metaPath);
|
|
75
|
-
if (!meta || !isLoadablePlugin(
|
|
69
|
+
if (!meta || !isLoadablePlugin(meta))
|
|
76
70
|
continue;
|
|
77
71
|
let entry;
|
|
78
72
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node-modules-loader.js","sourceRoot":"","sources":["../src/node-modules-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,+DAA+D;AAC/D,oDAAoD;AACpD,+DAA+D;AAC/D,EAAE;AACF,kDAAkD;AAClD,kEAAkE;AAClE,qEAAqE;AACrE,mCAAmC;AACnC,EAAE;AACF,
|
|
1
|
+
{"version":3,"file":"node-modules-loader.js","sourceRoot":"","sources":["../src/node-modules-loader.ts"],"names":[],"mappings":"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"}
|
package/dist/providers.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export declare function createFsYamlConfigProvider(configPath?: string): FsYamlC
|
|
|
20
20
|
/**
|
|
21
21
|
* 创建一个基于 packages 目录扫描的 PluginLoader。
|
|
22
22
|
*
|
|
23
|
-
* - `discover()`:读 dir 下每个子目录的 package.json,按
|
|
23
|
+
* - `discover()`:读 dir 下每个子目录的 package.json,按 aalis-plugin 关键词收录可加载插件
|
|
24
24
|
* - `load()`:用 `pathToFileURL(entry).href` 动态 import
|
|
25
25
|
* - `reload()`:用入口文件 mtime 作为 import URL 的 query 强制 ESM 缓存失效
|
|
26
26
|
*/
|
package/dist/providers.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EAEd,YAAY,EAEZ,eAAe,EAChB,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EAEd,YAAY,EAEZ,eAAe,EAChB,MAAM,aAAa,CAAC;AAqHrB,UAAU,0BAA0B;IAClC,qCAAqC;IACrC,MAAM,EAAE,WAAW,CAAC;IACpB,oDAAoD;IACpD,QAAQ,EAAE,cAAc,CAAC;IACzB,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,0BAA0B,CAkE1F;AAMD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,YAAY,CAmDvE;AAMD;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,IAAI,eAAe,CAyB9D"}
|
package/dist/providers.js
CHANGED
|
@@ -4,6 +4,7 @@ import { readdir, stat } from 'node:fs/promises';
|
|
|
4
4
|
import { dirname, resolve } from 'node:path';
|
|
5
5
|
import { pathToFileURL } from 'node:url';
|
|
6
6
|
import { parse as parseYaml, stringify as stringifyYaml } from 'yaml';
|
|
7
|
+
import { isLoadablePlugin } from './node-modules-loader.js';
|
|
7
8
|
// ============================================================
|
|
8
9
|
// FsYamlConfigProvider —— 从 YAML 文件加载+持久化配置
|
|
9
10
|
// ============================================================
|
|
@@ -16,6 +17,33 @@ function interpolateEnvVars(text) {
|
|
|
16
17
|
return process.env[varName.trim()] ?? '';
|
|
17
18
|
});
|
|
18
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* 在【解析后】的配置树上对字符串标量做 ${ENV} 替换(值级插值)。
|
|
22
|
+
* 不在 YAML 文本层插值——含 :/换行/{} 的 env 值也只成为该字段的字符串值,
|
|
23
|
+
* 注入不了 YAML 键、崩不了解析。含占位的纯数字/布尔结果安全恢复类型
|
|
24
|
+
* (保持 `port: ${PORT}` 仍解析为数字,与旧文本插值行为一致)。
|
|
25
|
+
*/
|
|
26
|
+
function interpolateEnvVarsDeep(value) {
|
|
27
|
+
if (typeof value === 'string') {
|
|
28
|
+
if (!value.includes('${'))
|
|
29
|
+
return value;
|
|
30
|
+
const s = interpolateEnvVars(value);
|
|
31
|
+
if (/^-?\d+(\.\d+)?$/.test(s))
|
|
32
|
+
return Number(s);
|
|
33
|
+
if (s === 'true' || s === 'false')
|
|
34
|
+
return s === 'true';
|
|
35
|
+
return s;
|
|
36
|
+
}
|
|
37
|
+
if (Array.isArray(value))
|
|
38
|
+
return value.map(interpolateEnvVarsDeep);
|
|
39
|
+
if (value && typeof value === 'object') {
|
|
40
|
+
const out = {};
|
|
41
|
+
for (const [k, v] of Object.entries(value))
|
|
42
|
+
out[k] = interpolateEnvVarsDeep(v);
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
19
47
|
const CORE_TOP_LEVEL_KEYS = new Set(['name', 'logLevel', 'plugins', 'disabledPlugins', 'servicePreferences']);
|
|
20
48
|
/**
|
|
21
49
|
* 恢复 ${ENV} 占位符:对比当前值与原始 raw 值,若相等则保留 raw。
|
|
@@ -109,8 +137,8 @@ export function createFsYamlConfigProvider(configPath) {
|
|
|
109
137
|
function loadFromDisk() {
|
|
110
138
|
if (existsSync(absPath)) {
|
|
111
139
|
rawYaml = readFileSync(absPath, 'utf-8');
|
|
112
|
-
|
|
113
|
-
const parsed = (parseYaml(
|
|
140
|
+
// 先 parse、再只在解析后的字符串值上插值 ${ENV}——env 值注入不了 YAML 结构、崩不了解析。
|
|
141
|
+
const parsed = interpolateEnvVarsDeep(parseYaml(rawYaml) ?? {});
|
|
114
142
|
return parsed;
|
|
115
143
|
}
|
|
116
144
|
rawYaml = null;
|
|
@@ -141,8 +169,7 @@ export function createFsYamlConfigProvider(configPath) {
|
|
|
141
169
|
return;
|
|
142
170
|
lastWrittenYaml = null;
|
|
143
171
|
rawYaml = current;
|
|
144
|
-
const
|
|
145
|
-
const parsed = (parseYaml(interpolated) ?? {});
|
|
172
|
+
const parsed = interpolateEnvVarsDeep(parseYaml(current) ?? {});
|
|
146
173
|
onChange(parsed);
|
|
147
174
|
}
|
|
148
175
|
catch {
|
|
@@ -172,7 +199,7 @@ export function createFsYamlConfigProvider(configPath) {
|
|
|
172
199
|
/**
|
|
173
200
|
* 创建一个基于 packages 目录扫描的 PluginLoader。
|
|
174
201
|
*
|
|
175
|
-
* - `discover()`:读 dir 下每个子目录的 package.json,按
|
|
202
|
+
* - `discover()`:读 dir 下每个子目录的 package.json,按 aalis-plugin 关键词收录可加载插件
|
|
176
203
|
* - `load()`:用 `pathToFileURL(entry).href` 动态 import
|
|
177
204
|
* - `reload()`:用入口文件 mtime 作为 import URL 的 query 强制 ESM 缓存失效
|
|
178
205
|
*/
|
|
@@ -198,8 +225,9 @@ export function createFsPluginLoader(packagesDir) {
|
|
|
198
225
|
catch {
|
|
199
226
|
continue;
|
|
200
227
|
}
|
|
201
|
-
|
|
202
|
-
|
|
228
|
+
// 与 node_modules 加载器同一标准:纯 aalis-plugin 关键词正向门(单一真相,防两处漂移)。
|
|
229
|
+
// 非插件(核心/契约/前端/工具链/工具库)各带自己的类型关键词、不带 aalis-plugin,自然不被收录。
|
|
230
|
+
if (!isLoadablePlugin(pkgJson))
|
|
203
231
|
continue;
|
|
204
232
|
const main = pkgJson.main || 'dist/index.js';
|
|
205
233
|
discovered.push({
|
package/dist/providers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAkB,KAAK,IAAI,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AASzC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAkB,KAAK,IAAI,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AASzC,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,SAAS,IAAI,aAAa,EAAE,MAAM,MAAM,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAE5D,+DAA+D;AAC/D,4CAA4C;AAC5C,+DAA+D;AAE/D,MAAM,mBAAmB,GAAG,mBAAmB,CAAC;AAEhD;;GAEG;AACH,SAAS,kBAAkB,CAAC,IAAY;IACtC,OAAO,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC,EAAE,OAAe,EAAE,EAAE;QAC1D,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAS,sBAAsB,CAAC,KAAc;IAC5C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACxC,MAAM,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACpC,IAAI,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;QAChD,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,OAAO;YAAE,OAAO,CAAC,KAAK,MAAM,CAAC;QACvD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACnE,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAC1G,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAS,CAAC,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,iBAAiB,EAAE,oBAAoB,CAAC,CAAC,CAAC;AAEtH;;GAEG;AACH,SAAS,cAAc,CAAC,OAAgC,EAAE,GAA4B;IACpF,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnD,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5D,MAAM,QAAQ,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gBACvB,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;gBACrB,SAAS;YACX,CAAC;QACH,CAAC;QACD,IACE,KAAK;YACL,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;YACrB,MAAM;YACN,OAAO,MAAM,KAAK,QAAQ;YAC1B,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EACtB,CAAC;YACD,MAAM,CAAC,GAAG,CAAC,GAAG,cAAc,CAAC,KAAgC,EAAE,MAAiC,CAAC,CAAC;QACpG,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,aAAa,CAAC,MAAmB,EAAE,OAAsB;IAChE,MAAM,GAAG,GAA4B;QACnC,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,SAAS,CAAC,OAAO,CAAmC,CAAC;QACvE,MAAM,UAAU,GAAG,CAAC,SAAS,EAAE,OAAO,IAAI,EAAE,CAA4C,CAAC;QACzF,MAAM,OAAO,GAA4C,EAAE,CAAC;QAC5D,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,GAAG,CAAC,OAAO,GAAG,OAAO,CAAC;IACxB,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/B,CAAC;IAED,GAAG,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,kBAAkB,IAAI,EAAE,CAAC;IAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClC,GAAG,CAAC,kBAAkB,GAAG,KAAK,CAAC;IACjC,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC3C,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACzC,CAAC;aAAM,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,KAAgC,CAAC,CAAC,MAAM,GAAG,CAAC;gBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACjF,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,aAAa,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;AAC9C,CAAC;AAWD;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CAAC,UAAmB;IAC5D,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,mBAAmB,CAAC,CAAC;IAC/F,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjC,IAAI,OAAO,GAAkB,IAAI,CAAC;IAClC,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,IAAI,OAAO,GAAqB,IAAI,CAAC;IACrC,IAAI,aAAa,GAAyC,IAAI,CAAC;IAE/D,SAAS,YAAY;QACnB,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YACzC,0DAA0D;YAC1D,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAA4B,CAAC;YAC3F,OAAO,MAAqB,CAAC;QAC/B,CAAC;QACD,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,aAAa,GAAG,YAAY,EAAE,CAAC;IAErC,MAAM,QAAQ,GAAmB;QAC/B,IAAI,CAAC,MAAM;YACT,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAC5C,eAAe,GAAG,IAAI,CAAC;YACvB,aAAa,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YACtC,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QAED,KAAK,CAAC,QAAQ;YACZ,IAAI,OAAO;gBAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,OAAO,GAAG,EAAE,GAAE,CAAC,CAAC;YAC1C,IAAI,CAAC;gBACH,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE;oBAC9B,IAAI,aAAa;wBAAE,YAAY,CAAC,aAAa,CAAC,CAAC;oBAC/C,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;wBAC9B,aAAa,GAAG,IAAI,CAAC;wBACrB,IAAI,CAAC;4BACH,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;4BAC/C,IAAI,eAAe,KAAK,IAAI,IAAI,OAAO,KAAK,eAAe;gCAAE,OAAO;4BACpE,eAAe,GAAG,IAAI,CAAC;4BACvB,OAAO,GAAG,OAAO,CAAC;4BAClB,MAAM,MAAM,GAAG,sBAAsB,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,CAA4B,CAAC;4BAC3F,QAAQ,CAAC,MAAqB,CAAC,CAAC;wBAClC,CAAC;wBAAC,MAAM,CAAC;4BACP,kBAAkB;wBACpB,CAAC;oBACH,CAAC,EAAE,GAAG,CAAC,CAAC;gBACV,CAAC,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,iBAAiB;YACnB,CAAC;YAED,OAAO,GAAG,EAAE;gBACV,IAAI,aAAa,EAAE,CAAC;oBAClB,YAAY,CAAC,aAAa,CAAC,CAAC;oBAC5B,aAAa,GAAG,IAAI,CAAC;gBACvB,CAAC;gBACD,OAAO,EAAE,KAAK,EAAE,CAAC;gBACjB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AACtD,CAAC;AAED,+DAA+D;AAC/D,0CAA0C;AAC1C,+DAA+D;AAE/D;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAoB;IACvD,MAAM,OAAO,GAAG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;IAElE,OAAO;QACL,KAAK,CAAC,QAAQ;YACZ,IAAI,OAAiB,CAAC;YACtB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACxF,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,MAAM,UAAU,GAAuB,EAAE,CAAC;YAC1C,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;gBAC5D,IAAI,OAAgC,CAAC;gBACrC,IAAI,CAAC;oBACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;gBAC3D,CAAC;gBAAC,MAAM,CAAC;oBACP,SAAS;gBACX,CAAC;gBACD,4DAA4D;gBAC5D,0DAA0D;gBAC1D,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC;oBAAE,SAAS;gBACzC,MAAM,IAAI,GAAI,OAAO,CAAC,IAAe,IAAI,eAAe,CAAC;gBACzD,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,OAAO,CAAC,IAAc;oBAC5B,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC;oBACrC,QAAQ,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;iBAC3C,CAAC,CAAC;YACL,CAAC;YACD,OAAO,UAAU,CAAC;QACpB,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,IAAI;YACb,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAiB,CAAC;YAC5E,OAAO,GAAG,CAAC;QACb,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,IAAI;YACf,IAAI,QAAQ,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC;gBACH,QAAQ,GAAG,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;YACvD,CAAC;YAAC,MAAM,CAAC;gBACP,kCAAkC;YACpC,CAAC;YACD,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,GAAG,QAAQ,CAAC,CAAiB,CAAC;YACvF,OAAO,GAAG,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC;AAED,+DAA+D;AAC/D,kDAAkD;AAClD,+DAA+D;AAE/D;;;;;;;;;GASG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE;YACpB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YACvD,MAAM,IAAI,EAAE,CAAC;YACb,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,IAAY,CAAC;YACjB,IAAI,IAAc,CAAC;YACnB,IAAI,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAChC,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;gBACrE,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC3C,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC/B,CAAC;iBAAM,CAAC;gBACN,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;YACjC,CAAC;YACD,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE;gBAC9B,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;gBAClB,KAAK,EAAE,SAAS;gBAChB,QAAQ,EAAE,IAAI;gBACd,GAAG,EAAE,OAAO,CAAC,GAAG;aACjB,CAAC,CAAC;YACH,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/start.d.ts
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
|
-
import { App } from '@aalis/core';
|
|
1
|
+
import { App, type PluginLoader } from '@aalis/core';
|
|
2
2
|
export interface StartAalisOptions {
|
|
3
3
|
/** aalis.config.yaml 路径,默认 cwd 下的 aalis.config.yaml */
|
|
4
4
|
configPath?: string;
|
|
5
5
|
/** 项目根目录(含 package.json + node_modules),默认 process.cwd() */
|
|
6
6
|
projectDir?: string;
|
|
7
|
-
/**
|
|
8
|
-
|
|
7
|
+
/** 插件加载器,默认 createNodeModulesPluginLoader(projectDir);monorepo 传 createFsPluginLoader() 扫 packages/ */
|
|
8
|
+
pluginLoader?: PluginLoader;
|
|
9
|
+
/** 彩色 stdout 日志,默认 true(独立部署即有日志);webui-only/嵌入式可传 false */
|
|
10
|
+
consoleSink?: boolean;
|
|
11
|
+
/** 文件日志:true→data/latest.log,string→自定义路径,false→关。默认 true(webui/cli 尾读此文件)。 */
|
|
12
|
+
fileLog?: boolean | string;
|
|
13
|
+
/** 退出时复原终端 raw-mode/alt-screen,默认 true */
|
|
14
|
+
terminalRestore?: boolean;
|
|
15
|
+
/** `aalis <name> [args]` 子命令分发:命中即执行并干净退出、不进守护。默认 false(monorepo 传 true)。 */
|
|
16
|
+
subcommands?: boolean | string[];
|
|
17
|
+
/** 覆盖 dev/prod 判定,默认按 NODE_ENV !== 'production' */
|
|
18
|
+
devMode?: boolean;
|
|
9
19
|
}
|
|
10
20
|
/**
|
|
11
|
-
*
|
|
21
|
+
* 启动一个 Aalis 实例:YAML 配置 + 插件加载 + 进程级重启 + 日志/终端/子命令宿主件。
|
|
12
22
|
* 返回已启动的 App(便于测试或进一步操作)。
|
|
23
|
+
*
|
|
24
|
+
* 生命周期不变量:① `consoleHandle.bindEvents` 必须在 `new App` 之后(之前无 ctx);
|
|
25
|
+
* ② 子命令短路必须在 `app.start` 之前。
|
|
13
26
|
*/
|
|
14
27
|
export declare function startAalis(opts?: StartAalisOptions): Promise<App>;
|
|
15
28
|
//# sourceMappingURL=start.d.ts.map
|
package/dist/start.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAsBrD,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uGAAuG;IACvG,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,4DAA4D;IAC5D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,6EAA6E;IAC7E,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,EAAE,CAAC;IACjC,mDAAmD;IACnD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,CAqF3E"}
|
package/dist/start.js
CHANGED
|
@@ -1,23 +1,83 @@
|
|
|
1
1
|
import { App } from '@aalis/core';
|
|
2
|
+
import { installBootstrapBuffer } from './bootstrap-buffer.js';
|
|
3
|
+
import { installConsoleSink } from './console-sink.js';
|
|
4
|
+
import { appendCrashLog, DEFAULT_LOG_FILE, setupFileLogger } from './file-logger.js';
|
|
2
5
|
import { createNodeModulesPluginLoader } from './node-modules-loader.js';
|
|
3
6
|
import { createFsYamlConfigProvider, createProcessRespawnStrategy } from './providers.js';
|
|
7
|
+
import { tryDispatchSubcommand } from './subcommand.js';
|
|
8
|
+
import { installTerminalStateRestorer } from './terminal.js';
|
|
4
9
|
/**
|
|
5
|
-
*
|
|
10
|
+
* 启动一个 Aalis 实例:YAML 配置 + 插件加载 + 进程级重启 + 日志/终端/子命令宿主件。
|
|
6
11
|
* 返回已启动的 App(便于测试或进一步操作)。
|
|
12
|
+
*
|
|
13
|
+
* 生命周期不变量:① `consoleHandle.bindEvents` 必须在 `new App` 之后(之前无 ctx);
|
|
14
|
+
* ② 子命令短路必须在 `app.start` 之前。
|
|
7
15
|
*/
|
|
8
16
|
export async function startAalis(opts = {}) {
|
|
17
|
+
const { consoleSink = true, fileLog = true, terminalRestore = true, subcommands = false } = opts;
|
|
18
|
+
// ── 最早期:任何日志之前先装 bootstrap buffer,再装 terminal / console sink ──
|
|
19
|
+
const bootstrap = installBootstrapBuffer();
|
|
20
|
+
if (terminalRestore)
|
|
21
|
+
installTerminalStateRestorer();
|
|
22
|
+
// console sink 在 App 之前装:此时无 ctx,sink 处于「无条件写 stdout」状态以打印早期启动日志,
|
|
23
|
+
// 待 App 起来再 bindEvents 接管 terminal:claimed/released。
|
|
24
|
+
const consoleHandle = consoleSink ? installConsoleSink() : undefined;
|
|
25
|
+
const fileLogTarget = fileLog === false ? undefined : typeof fileLog === 'string' ? fileLog : DEFAULT_LOG_FILE;
|
|
26
|
+
// ── fatal handler(覆盖整个 async 启动过程)──
|
|
27
|
+
let fileLogger;
|
|
28
|
+
let handlingFatal = false;
|
|
29
|
+
const exitWithFatalLog = async (label, err) => {
|
|
30
|
+
if (handlingFatal)
|
|
31
|
+
process.exit(1);
|
|
32
|
+
handlingFatal = true;
|
|
33
|
+
console.error(`${label}:`, err);
|
|
34
|
+
try {
|
|
35
|
+
await fileLogger?.flush();
|
|
36
|
+
if (fileLogTarget)
|
|
37
|
+
await appendCrashLog(label, err, fileLogTarget);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* ignore */
|
|
41
|
+
}
|
|
42
|
+
process.exit(1);
|
|
43
|
+
};
|
|
44
|
+
process.on('uncaughtException', err => void exitWithFatalLog('未捕获异常', err));
|
|
45
|
+
process.on('unhandledRejection', reason => void exitWithFatalLog('未处理 Promise 拒绝', reason));
|
|
46
|
+
// ── file logger(async)+ 释放 bootstrap buffer ──
|
|
47
|
+
if (fileLogTarget)
|
|
48
|
+
fileLogger = await setupFileLogger(fileLogTarget);
|
|
49
|
+
// sink 全部装好;bootstrap buffer 完成使命,解除订阅并释放内存。
|
|
50
|
+
bootstrap.dispose();
|
|
51
|
+
// ── 组装 App:从 YAML 加载配置、按 loader 加载插件、用 spawn 重启 ──
|
|
9
52
|
const { config, provider, dataDir } = createFsYamlConfigProvider(opts.configPath);
|
|
10
53
|
const app = new App({
|
|
11
54
|
config,
|
|
12
55
|
configProvider: provider,
|
|
13
56
|
dataDir,
|
|
14
|
-
pluginLoader: createNodeModulesPluginLoader(opts.projectDir),
|
|
57
|
+
pluginLoader: opts.pluginLoader ?? createNodeModulesPluginLoader(opts.projectDir),
|
|
15
58
|
restartStrategy: createProcessRespawnStrategy(),
|
|
16
59
|
// 宿主层决定 dev/prod;core 不读 process.env
|
|
17
|
-
devMode: process.env.NODE_ENV !== 'production',
|
|
18
|
-
requiredServices: opts.requiredServices ?? [],
|
|
60
|
+
devMode: opts.devMode ?? process.env.NODE_ENV !== 'production',
|
|
19
61
|
});
|
|
62
|
+
// 不变量①:App 构造完成后再让 sink 监听终端归属事件——此前没有 ctx 可订阅。
|
|
63
|
+
consoleHandle?.bindEvents(app.ctx);
|
|
20
64
|
await app.autoLoadPlugins();
|
|
65
|
+
// ── 不变量②:子命令短路在 app.start 之前 ──
|
|
66
|
+
// `aalis <name> [args...]` 等价于聊天里 `/<name> args...`:命中则执行返回串并干净退出,
|
|
67
|
+
// 不命中则按正常守护进程模式继续启动。与具体命令解耦——各插件自行注册命令。
|
|
68
|
+
if (subcommands) {
|
|
69
|
+
const argv = Array.isArray(subcommands) ? subcommands : process.argv.slice(2);
|
|
70
|
+
if (argv.length > 0) {
|
|
71
|
+
const exitCode = await tryDispatchSubcommand(app, argv);
|
|
72
|
+
if (exitCode !== null) {
|
|
73
|
+
await app.stop();
|
|
74
|
+
await new Promise(r => setImmediate(r));
|
|
75
|
+
await fileLogger?.flush();
|
|
76
|
+
process.exit(exitCode);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// ── 启动 + 优雅退出(防止重复调用)──
|
|
21
81
|
await app.start();
|
|
22
82
|
let stopping = false;
|
|
23
83
|
const shutdown = async () => {
|
|
@@ -25,6 +85,10 @@ export async function startAalis(opts = {}) {
|
|
|
25
85
|
return;
|
|
26
86
|
stopping = true;
|
|
27
87
|
await app.stop();
|
|
88
|
+
// app.stop() 期间和之后插件可能仍在 logger.info('已停止') 等,给微任务一个 tick 把它们
|
|
89
|
+
// 入队,再等队列清空,确保 latest.log 含完整关闭日志。
|
|
90
|
+
await new Promise(r => setImmediate(r));
|
|
91
|
+
await fileLogger?.flush();
|
|
28
92
|
process.exit(0);
|
|
29
93
|
};
|
|
30
94
|
process.on('SIGINT', shutdown);
|
package/dist/start.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../src/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { App } from '@aalis/core';
|
|
2
|
+
/**
|
|
3
|
+
* 尝试把 argv 当作命令调用:`aalis <name> [args...]` ↔ chat 中的 `/<name> args`。
|
|
4
|
+
*
|
|
5
|
+
* - 返回 number 时表示命中并需要按该 exit code 结束进程;
|
|
6
|
+
* - 返回 null 表示未命中(commands 服务不存在或命令名未注册),调用方应继续守护进程模式。
|
|
7
|
+
*
|
|
8
|
+
* 不直接绑定任何具体命令;所有命令由插件向 commands 服务注册。
|
|
9
|
+
*
|
|
10
|
+
* 抽离到独立模块以便单测(src/index.ts 有顶层副作用,直接 import 会触发)。
|
|
11
|
+
*/
|
|
12
|
+
export declare function tryDispatchSubcommand(app: App, argv: string[], out?: (msg: string) => void): Promise<number | null>;
|
|
13
|
+
//# sourceMappingURL=subcommand.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subcommand.d.ts","sourceRoot":"","sources":["../src/subcommand.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAGvC;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAA8B,GACnD,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBxB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 尝试把 argv 当作命令调用:`aalis <name> [args...]` ↔ chat 中的 `/<name> args`。
|
|
3
|
+
*
|
|
4
|
+
* - 返回 number 时表示命中并需要按该 exit code 结束进程;
|
|
5
|
+
* - 返回 null 表示未命中(commands 服务不存在或命令名未注册),调用方应继续守护进程模式。
|
|
6
|
+
*
|
|
7
|
+
* 不直接绑定任何具体命令;所有命令由插件向 commands 服务注册。
|
|
8
|
+
*
|
|
9
|
+
* 抽离到独立模块以便单测(src/index.ts 有顶层副作用,直接 import 会触发)。
|
|
10
|
+
*/
|
|
11
|
+
export async function tryDispatchSubcommand(app, argv, out = msg => console.log(msg)) {
|
|
12
|
+
const commands = app.ctx.getService('commands');
|
|
13
|
+
if (!commands)
|
|
14
|
+
return null;
|
|
15
|
+
const [cmdName, ...rest] = argv;
|
|
16
|
+
if (!cmdName || !commands.has(cmdName))
|
|
17
|
+
return null;
|
|
18
|
+
const result = await commands.execute(cmdName, {
|
|
19
|
+
sessionId: 'cli',
|
|
20
|
+
platform: 'cli',
|
|
21
|
+
// userId 'console':本地终端 = 运维者本人,命中 authority 的 cli:console owner 快速通道。
|
|
22
|
+
// 一次性子命令模式无人可点交互确认,故 skipConfirm(authorize 仍生效,owner 直接放行)。
|
|
23
|
+
userId: 'console',
|
|
24
|
+
args: rest,
|
|
25
|
+
raw: `/${cmdName}${rest.length ? ` ${rest.join(' ')}` : ''}`,
|
|
26
|
+
skipConfirm: true,
|
|
27
|
+
});
|
|
28
|
+
if (result)
|
|
29
|
+
out(result);
|
|
30
|
+
return 0;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=subcommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subcommand.js","sourceRoot":"","sources":["../src/subcommand.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,GAAQ,EACR,IAAc,EACd,MAA6B,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;IAEpD,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,CAAiB,UAAU,CAAC,CAAC;IAChE,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAChC,IAAI,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE;QAC7C,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,KAAK;QACf,uEAAuE;QACvE,4DAA4D;QAC5D,MAAM,EAAE,SAAS;QACjB,IAAI,EAAE,IAAI;QACV,GAAG,EAAE,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;QAC5D,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IACH,IAAI,MAAM;QAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"AAIA,wBAAgB,oBAAoB,IAAI,IAAI,CAW3C;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAInD"}
|
package/dist/terminal.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const TERMINAL_RESTORE_SEQUENCE = '\x1b[?1006l\x1b[?1000l\x1b[?1007l\x1b[?25h\x1b[?1049l';
|
|
2
|
+
let installed = false;
|
|
3
|
+
export function restoreTerminalState() {
|
|
4
|
+
try {
|
|
5
|
+
if (process.stdin.isTTY)
|
|
6
|
+
process.stdin.setRawMode(false);
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
/* ignore */
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
process.stdout.write(TERMINAL_RESTORE_SEQUENCE);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
/* ignore */
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function installTerminalStateRestorer() {
|
|
19
|
+
if (installed)
|
|
20
|
+
return;
|
|
21
|
+
installed = true;
|
|
22
|
+
process.once('exit', restoreTerminalState);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../src/terminal.ts"],"names":[],"mappings":"AAAA,MAAM,yBAAyB,GAAG,uDAAuD,CAAC;AAE1F,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;IACD,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,IAAI,SAAS;QAAE,OAAO;IACtB,SAAS,GAAG,IAAI,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;AAC7C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aalis/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Aalis 独立部署运行时:node_modules 插件加载 + YAML 配置 + 一行启动 startAalis",
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
"dist"
|
|
15
15
|
],
|
|
16
16
|
"dependencies": {
|
|
17
|
+
"chalk": "^5.4.0",
|
|
17
18
|
"yaml": "^2.7.0"
|
|
18
19
|
},
|
|
19
20
|
"peerDependencies": {
|
|
@@ -22,7 +23,8 @@
|
|
|
22
23
|
"devDependencies": {
|
|
23
24
|
"typescript": "^5.7.0",
|
|
24
25
|
"@types/node": "^22.0.0",
|
|
25
|
-
"@aalis/
|
|
26
|
+
"@aalis/plugin-commands-api": "0.5.0",
|
|
27
|
+
"@aalis/core": "0.5.0"
|
|
26
28
|
},
|
|
27
29
|
"aalis": {
|
|
28
30
|
"tooling": true
|