@aipanel/core 1.2.0-beta.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/es/constants.d.ts +145 -0
- package/es/constants.mjs +124 -0
- package/es/file-log-watcher.d.ts +20 -0
- package/es/file-log-watcher.mjs +126 -0
- package/es/index.d.ts +7 -0
- package/es/index.mjs +7 -0
- package/es/logger-core.d.ts +37 -0
- package/es/logger-core.mjs +143 -0
- package/es/logger.d.ts +15 -0
- package/es/logger.mjs +127 -0
- package/es/node-logger.d.ts +38 -0
- package/es/node-logger.mjs +230 -0
- package/es/node-utils.d.ts +28 -0
- package/es/node-utils.mjs +56 -0
- package/es/node.d.ts +6 -0
- package/es/node.mjs +6 -0
- package/es/options.d.ts +63 -0
- package/es/options.mjs +30 -0
- package/es/process-logger.d.ts +97 -0
- package/es/process-logger.mjs +193 -0
- package/es/provider.d.ts +160 -0
- package/es/provider.mjs +0 -0
- package/es/types.d.ts +275 -0
- package/es/types.mjs +40 -0
- package/es/utils.d.ts +34 -0
- package/es/utils.mjs +53 -0
- package/lib/constants.cjs +188 -0
- package/lib/constants.d.ts +145 -0
- package/lib/file-log-watcher.cjs +160 -0
- package/lib/file-log-watcher.d.ts +20 -0
- package/lib/index.cjs +33 -0
- package/lib/index.d.ts +7 -0
- package/lib/logger-core.cjs +177 -0
- package/lib/logger-core.d.ts +37 -0
- package/lib/logger.cjs +145 -0
- package/lib/logger.d.ts +15 -0
- package/lib/node-logger.cjs +252 -0
- package/lib/node-logger.d.ts +38 -0
- package/lib/node-utils.cjs +93 -0
- package/lib/node-utils.d.ts +28 -0
- package/lib/node.cjs +31 -0
- package/lib/node.d.ts +6 -0
- package/lib/options.cjs +54 -0
- package/lib/options.d.ts +63 -0
- package/lib/process-logger.cjs +217 -0
- package/lib/process-logger.d.ts +97 -0
- package/lib/provider.cjs +15 -0
- package/lib/provider.d.ts +160 -0
- package/lib/types.cjs +64 -0
- package/lib/types.d.ts +275 -0
- package/lib/utils.cjs +80 -0
- package/lib/utils.d.ts +34 -0
- package/package.json +34 -0
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
const DEFAULT_MAX_SIZE = 500;
|
|
5
|
+
class ProcessLogBuffer {
|
|
6
|
+
constructor(options = {}) {
|
|
7
|
+
__publicField(this, "buffer", []);
|
|
8
|
+
__publicField(this, "maxSize");
|
|
9
|
+
__publicField(this, "enabled", true);
|
|
10
|
+
__publicField(this, "originalConsole", null);
|
|
11
|
+
this.maxSize = options.maxSize ?? DEFAULT_MAX_SIZE;
|
|
12
|
+
this.enabled = options.enabled ?? true;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 启动 console 拦截
|
|
16
|
+
*/
|
|
17
|
+
intercept() {
|
|
18
|
+
if (this.originalConsole) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
this.originalConsole = {
|
|
22
|
+
log: console.log,
|
|
23
|
+
info: console.info,
|
|
24
|
+
warn: console.warn,
|
|
25
|
+
error: console.error,
|
|
26
|
+
debug: console.debug
|
|
27
|
+
};
|
|
28
|
+
console.log = this.createInterceptor("log", this.originalConsole.log);
|
|
29
|
+
console.info = this.createInterceptor("info", this.originalConsole.info);
|
|
30
|
+
console.warn = this.createInterceptor("warn", this.originalConsole.warn);
|
|
31
|
+
console.error = this.createInterceptor("error", this.originalConsole.error);
|
|
32
|
+
console.debug = this.createInterceptor("debug", this.originalConsole.debug);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 停止拦截,恢复原始 console
|
|
36
|
+
*/
|
|
37
|
+
restore() {
|
|
38
|
+
if (!this.originalConsole) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
console.log = this.originalConsole.log;
|
|
42
|
+
console.info = this.originalConsole.info;
|
|
43
|
+
console.warn = this.originalConsole.warn;
|
|
44
|
+
console.error = this.originalConsole.error;
|
|
45
|
+
console.debug = this.originalConsole.debug;
|
|
46
|
+
this.originalConsole = null;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 创建拦截器函数
|
|
50
|
+
*/
|
|
51
|
+
createInterceptor(level, original) {
|
|
52
|
+
return (...args) => {
|
|
53
|
+
original.apply(console, args);
|
|
54
|
+
if (this.enabled) {
|
|
55
|
+
this.addEntry({
|
|
56
|
+
level,
|
|
57
|
+
message: this.serializeArgs(args),
|
|
58
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
59
|
+
source: "console"
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 序列化参数为字符串
|
|
66
|
+
*/
|
|
67
|
+
serializeArgs(args) {
|
|
68
|
+
return args.map((arg) => {
|
|
69
|
+
if (typeof arg === "string") {
|
|
70
|
+
return arg;
|
|
71
|
+
}
|
|
72
|
+
if (typeof arg === "number" || typeof arg === "boolean") {
|
|
73
|
+
return String(arg);
|
|
74
|
+
}
|
|
75
|
+
if (arg === null) {
|
|
76
|
+
return "null";
|
|
77
|
+
}
|
|
78
|
+
if (arg === void 0) {
|
|
79
|
+
return "undefined";
|
|
80
|
+
}
|
|
81
|
+
if (typeof arg === "object") {
|
|
82
|
+
try {
|
|
83
|
+
return JSON.stringify(arg, null, 2);
|
|
84
|
+
} catch {
|
|
85
|
+
return String(arg);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return String(arg);
|
|
89
|
+
}).join(" ");
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* 添加日志条目
|
|
93
|
+
*/
|
|
94
|
+
addEntry(entry) {
|
|
95
|
+
if (!this.enabled) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (this.buffer.length >= this.maxSize) {
|
|
99
|
+
this.buffer.shift();
|
|
100
|
+
}
|
|
101
|
+
this.buffer.push(entry);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 添加 Provider stdout 日志
|
|
105
|
+
*/
|
|
106
|
+
addProviderStdout(message) {
|
|
107
|
+
this.addEntry({
|
|
108
|
+
level: "info",
|
|
109
|
+
message,
|
|
110
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
111
|
+
source: "provider-stdout"
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 添加 Provider stderr 日志
|
|
116
|
+
*/
|
|
117
|
+
addProviderStderr(message) {
|
|
118
|
+
this.addEntry({
|
|
119
|
+
level: "error",
|
|
120
|
+
message,
|
|
121
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
122
|
+
source: "provider-stderr"
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* 获取日志
|
|
127
|
+
* @param options 过滤选项
|
|
128
|
+
*/
|
|
129
|
+
getLogs(options = {}) {
|
|
130
|
+
let logs = [...this.buffer];
|
|
131
|
+
if (options.level) {
|
|
132
|
+
const levels = Array.isArray(options.level) ? options.level : [options.level];
|
|
133
|
+
logs = logs.filter((log) => levels.includes(log.level));
|
|
134
|
+
}
|
|
135
|
+
if (options.source) {
|
|
136
|
+
logs = logs.filter((log) => log.source === options.source);
|
|
137
|
+
}
|
|
138
|
+
if (options.since) {
|
|
139
|
+
const sinceDate = new Date(options.since);
|
|
140
|
+
logs = logs.filter((log) => new Date(log.timestamp) >= sinceDate);
|
|
141
|
+
}
|
|
142
|
+
if (options.limit && options.limit > 0) {
|
|
143
|
+
logs = logs.slice(-options.limit);
|
|
144
|
+
}
|
|
145
|
+
return logs;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* 清空缓冲区
|
|
149
|
+
*/
|
|
150
|
+
clear() {
|
|
151
|
+
this.buffer = [];
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* 获取缓冲区大小
|
|
155
|
+
*/
|
|
156
|
+
size() {
|
|
157
|
+
return this.buffer.length;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 启用/禁用捕获
|
|
161
|
+
*/
|
|
162
|
+
setEnabled(enabled) {
|
|
163
|
+
this.enabled = enabled;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* 获取是否启用
|
|
167
|
+
*/
|
|
168
|
+
isEnabled() {
|
|
169
|
+
return this.enabled;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
let globalBuffer = null;
|
|
173
|
+
function getProcessLogBuffer(options) {
|
|
174
|
+
if (!globalBuffer) {
|
|
175
|
+
globalBuffer = new ProcessLogBuffer(options);
|
|
176
|
+
}
|
|
177
|
+
return globalBuffer;
|
|
178
|
+
}
|
|
179
|
+
function initProcessLogCapture(options) {
|
|
180
|
+
const buffer = getProcessLogBuffer(options);
|
|
181
|
+
buffer.intercept();
|
|
182
|
+
return buffer;
|
|
183
|
+
}
|
|
184
|
+
function stopProcessLogCapture() {
|
|
185
|
+
if (globalBuffer) {
|
|
186
|
+
globalBuffer.restore();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
export {
|
|
190
|
+
getProcessLogBuffer,
|
|
191
|
+
initProcessLogCapture,
|
|
192
|
+
stopProcessLogCapture
|
|
193
|
+
};
|
package/es/provider.d.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Provider 适配层契约
|
|
3
|
+
*
|
|
4
|
+
* 核心层只依赖本文件定义的通用协议;具体 Web UI(Provider)的实现细节
|
|
5
|
+
* 全部封装在 WebProvider 实现内。新增 Provider 时只需实现本接口。
|
|
6
|
+
*/
|
|
7
|
+
/** 通用会话模型(Provider 私有会话 → 归一化) */
|
|
8
|
+
export interface ChatSession {
|
|
9
|
+
/** 会话 ID */
|
|
10
|
+
id: string;
|
|
11
|
+
/** 会话标题 */
|
|
12
|
+
title: string;
|
|
13
|
+
/** 创建时间戳 */
|
|
14
|
+
createdAt?: number;
|
|
15
|
+
/** 更新时间戳 */
|
|
16
|
+
updatedAt?: number;
|
|
17
|
+
/** 是否已归档 */
|
|
18
|
+
archived?: boolean;
|
|
19
|
+
/** 父会话 ID(subagent 会话才有) */
|
|
20
|
+
parentId?: string;
|
|
21
|
+
/**
|
|
22
|
+
* 会话打开 URL(由 buildSessionUrl 填充)。
|
|
23
|
+
* 无 deepLink 能力时所有会话共用应用壳 URL(同一值),切换会话靠 FOCUS_SESSION 消息。
|
|
24
|
+
*/
|
|
25
|
+
url?: string;
|
|
26
|
+
}
|
|
27
|
+
/** 会话运行状态 */
|
|
28
|
+
export type SessionStatus = "idle" | "running" | "streaming" | "completed";
|
|
29
|
+
/** Provider 事件(Provider 私有事件 → 归一化,客户端只消费这些事件) */
|
|
30
|
+
export type ProviderEvent = {
|
|
31
|
+
type: "connected";
|
|
32
|
+
}
|
|
33
|
+
/** 会话信息更新(标题/摘要等) */
|
|
34
|
+
| {
|
|
35
|
+
type: "session.updated";
|
|
36
|
+
session: ChatSession;
|
|
37
|
+
}
|
|
38
|
+
/** 会话运行状态变化 */
|
|
39
|
+
| {
|
|
40
|
+
type: "session.status";
|
|
41
|
+
sessionId: string;
|
|
42
|
+
status: SessionStatus;
|
|
43
|
+
}
|
|
44
|
+
/** 会话思考状态(由 adapter 自行推导) */
|
|
45
|
+
| {
|
|
46
|
+
type: "thinking";
|
|
47
|
+
sessionId: string;
|
|
48
|
+
thinking: boolean;
|
|
49
|
+
};
|
|
50
|
+
/** Provider 环境检查结果 */
|
|
51
|
+
export interface ProviderEnvironmentInfo {
|
|
52
|
+
/** 环境是否就绪 */
|
|
53
|
+
ok: boolean;
|
|
54
|
+
/** Provider 版本号 */
|
|
55
|
+
version?: string;
|
|
56
|
+
/** 未就绪时的说明(如安装指引) */
|
|
57
|
+
message?: string;
|
|
58
|
+
}
|
|
59
|
+
/** Provider 启动选项(核心编排层提供的通用运行参数) */
|
|
60
|
+
export interface ProviderStartOptions {
|
|
61
|
+
/** 服务端口 */
|
|
62
|
+
port: number;
|
|
63
|
+
/** 服务主机名 */
|
|
64
|
+
hostname: string;
|
|
65
|
+
/** 工作目录 */
|
|
66
|
+
cwd: string;
|
|
67
|
+
/** CORS 允许的源 */
|
|
68
|
+
corsOrigins: string[];
|
|
69
|
+
/** 项目对应的 Vite 端口(用于回连 Vite 服务) */
|
|
70
|
+
vitePort: number;
|
|
71
|
+
/** 上下文 API URL(核心层提供的回连地址) */
|
|
72
|
+
contextApiUrl?: string;
|
|
73
|
+
/** 进程日志 API URL(核心层提供的回连地址) */
|
|
74
|
+
logsApiUrl?: string;
|
|
75
|
+
/** Vue DevTools API 地址(核心层提供的回连地址) */
|
|
76
|
+
vueDevtoolsApiUrl?: string;
|
|
77
|
+
/** 启用 verbose 模式 */
|
|
78
|
+
verbose?: boolean;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Provider 初始化上下文(核心层动态加载 Provider 时传入)
|
|
82
|
+
* Provider 专属配置通过 options 原样传递,schema 由 Provider 自行解析。
|
|
83
|
+
*/
|
|
84
|
+
export interface ProviderInitContext {
|
|
85
|
+
/** 服务主机名 */
|
|
86
|
+
hostname: string;
|
|
87
|
+
/** Chrome DevTools Protocol 端口 */
|
|
88
|
+
chromeDevtoolsPort: number;
|
|
89
|
+
/** 实际 Web 端口读取器 */
|
|
90
|
+
getWebPort(): number;
|
|
91
|
+
/** 实际代理端口读取器 */
|
|
92
|
+
getProxyPort(): number;
|
|
93
|
+
/** 用户完整插件配置(宽松对象,Provider 自解析所需字段) */
|
|
94
|
+
options?: Record<string, unknown>;
|
|
95
|
+
}
|
|
96
|
+
/** Provider 启动结果 */
|
|
97
|
+
export interface ProviderStartResult {
|
|
98
|
+
/** 就绪后的服务 URL */
|
|
99
|
+
url: string;
|
|
100
|
+
/** 进程句柄(供编排层做就绪等待与退出检测,不透明) */
|
|
101
|
+
processHandle?: unknown;
|
|
102
|
+
}
|
|
103
|
+
/** Provider 初始化配置(主题/语言/设置等,schema 由 Provider 定义) */
|
|
104
|
+
export interface ProviderConfig {
|
|
105
|
+
/** 主题模式 */
|
|
106
|
+
theme?: "light" | "dark" | "auto";
|
|
107
|
+
/** 界面语言 */
|
|
108
|
+
language?: string;
|
|
109
|
+
/** Provider 内部设置 */
|
|
110
|
+
settings?: unknown;
|
|
111
|
+
[key: string]: unknown;
|
|
112
|
+
}
|
|
113
|
+
/** Provider 能力描述(客户端据此自适应行为) */
|
|
114
|
+
export interface ProviderCapabilities {
|
|
115
|
+
/**
|
|
116
|
+
* 会话是否支持 URL 深链。
|
|
117
|
+
* true(默认):iframe 每次切换会话重载,src 直达该会话;
|
|
118
|
+
* false(SPA 型无深链 Provider):iframe 保持应用壳 URL 不重载,
|
|
119
|
+
* 切换会话通过 FOCUS_SESSION 消息完成。
|
|
120
|
+
*/
|
|
121
|
+
deepLink?: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* 是否支持代码审查面板(挂件右上角 </> 按钮)。
|
|
124
|
+
* true:点击按钮向 iframe 发送 REVIEW_PANEL_TOGGLE,由 Provider 渲染审查面板;
|
|
125
|
+
* 缺省/false:不支持,客户端隐藏该按钮,避免展示无功能的入口。
|
|
126
|
+
*/
|
|
127
|
+
reviewPanel?: boolean;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Web Provider 适配器接口
|
|
131
|
+
*/
|
|
132
|
+
export interface WebProvider {
|
|
133
|
+
/** 唯一标识(对应插件配置的 provider 字段) */
|
|
134
|
+
readonly id: string;
|
|
135
|
+
/** 展示名称 */
|
|
136
|
+
readonly displayName: string;
|
|
137
|
+
/** 校验运行环境(CLI 是否安装、版本) */
|
|
138
|
+
checkEnvironment(): Promise<ProviderEnvironmentInfo>;
|
|
139
|
+
/** 启动 Web 服务(含运行环境准备),返回就绪 URL */
|
|
140
|
+
start(options: ProviderStartOptions): Promise<ProviderStartResult>;
|
|
141
|
+
/** 停止服务 */
|
|
142
|
+
stop(): Promise<void>;
|
|
143
|
+
/** 清理孤儿进程(上次退出残留的 provider 进程),返回清理数量(可选) */
|
|
144
|
+
killOrphans?(): Promise<number>;
|
|
145
|
+
/** 会话管理(归一化到 ChatSession,过滤逻辑在此内部完成) */
|
|
146
|
+
listSessions(projectDir: string): Promise<ChatSession[]>;
|
|
147
|
+
createSession(projectDir: string, title?: string): Promise<ChatSession>;
|
|
148
|
+
/** 可选:部分 Provider 无删除语义;core 不支持时隐藏删除入口 */
|
|
149
|
+
deleteSession?(sessionId: string): Promise<void>;
|
|
150
|
+
/** 会话打开 URL(iframe src);无 deepLink 能力时返回应用壳 URL(所有会话相同) */
|
|
151
|
+
buildSessionUrl(projectDir: string, sessionId: string): string;
|
|
152
|
+
/** Provider 能力描述(客户端自适应行为;缺省按 deepLink=true 处理) */
|
|
153
|
+
readonly capabilities?: ProviderCapabilities;
|
|
154
|
+
/** 事件订阅:把 Provider 私有事件归一化为 ProviderEvent;返回取消订阅函数 */
|
|
155
|
+
subscribeEvents(handler: (e: ProviderEvent) => void): () => void;
|
|
156
|
+
/** 代理注入到 HTML 的 Provider 侧桥接脚本(可选) */
|
|
157
|
+
bridgeScript?: string;
|
|
158
|
+
/** Provider 初始化配置(主题/语言/设置,schema 由 Provider 定义) */
|
|
159
|
+
applyConfig?(config: ProviderConfig): void;
|
|
160
|
+
}
|
package/es/provider.mjs
ADDED
|
File without changes
|
package/es/types.d.ts
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 通用类型(Provider 无关)
|
|
3
|
+
* Provider 专属类型已下沉至 @aipanel/provider-opencode。
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 展示模式类型
|
|
7
|
+
*/
|
|
8
|
+
export type DisplayMode = "bubble" | "split" | "auto" | "extension" | "extension-selector";
|
|
9
|
+
/**
|
|
10
|
+
* 分屏模式配置
|
|
11
|
+
*/
|
|
12
|
+
export interface SplitModeOptions {
|
|
13
|
+
/** 面板宽度,默认 500 */
|
|
14
|
+
width?: number;
|
|
15
|
+
/** 最小宽度,默认 400 */
|
|
16
|
+
minWidth?: number;
|
|
17
|
+
/** 最大宽度,默认 800 */
|
|
18
|
+
maxWidth?: number;
|
|
19
|
+
/** 是否可调整宽度,默认 true */
|
|
20
|
+
resizable?: boolean;
|
|
21
|
+
/** 是否收缩主页面,默认 true */
|
|
22
|
+
shrinkPage?: boolean;
|
|
23
|
+
/** 默认是否展开,默认 true */
|
|
24
|
+
defaultOpen?: boolean;
|
|
25
|
+
/** 面板位置,默认 'right' */
|
|
26
|
+
position?: "left" | "right";
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* 挂件注入配置选项
|
|
30
|
+
*/
|
|
31
|
+
export interface WidgetOptions {
|
|
32
|
+
/** 主题模式 */
|
|
33
|
+
theme: string;
|
|
34
|
+
/** 是否自动打开 */
|
|
35
|
+
open: boolean;
|
|
36
|
+
/** 快捷键配置 */
|
|
37
|
+
hotkey?: string;
|
|
38
|
+
/** 代理服务端口 */
|
|
39
|
+
proxyPort?: number;
|
|
40
|
+
/** 代理服务主机名 */
|
|
41
|
+
proxyHost?: string;
|
|
42
|
+
/** 展示模式 */
|
|
43
|
+
displayMode?: DisplayMode;
|
|
44
|
+
/** 分屏模式配置 */
|
|
45
|
+
splitMode?: SplitModeOptions;
|
|
46
|
+
/** Vite 服务 Web 端口(扩展模式多实例场景用) */
|
|
47
|
+
vitePort?: string;
|
|
48
|
+
/** 服务实例唯一标识(扩展模式多实例隔离用) */
|
|
49
|
+
serviceInstanceId?: string;
|
|
50
|
+
/** 当前窗口 ID(扩展模式多窗口隔离用) */
|
|
51
|
+
myWindowId?: number;
|
|
52
|
+
/** Web 服务端口 */
|
|
53
|
+
webPort?: number;
|
|
54
|
+
/** 项目根目录 */
|
|
55
|
+
projectRoot?: string;
|
|
56
|
+
/** 是否开启 verbose 日志 */
|
|
57
|
+
verbose?: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 日志文件配置
|
|
61
|
+
* 给 Agent 提供查看外部服务日志的能力(MCP 工具配置,Provider 无关)
|
|
62
|
+
*/
|
|
63
|
+
export interface LogFileConfig {
|
|
64
|
+
/** 日志文件的唯一标识符,用于工具调用时指定 */
|
|
65
|
+
name: string;
|
|
66
|
+
/** 日志文件路径(绝对路径或相对于项目根目录的相对路径) */
|
|
67
|
+
path: string;
|
|
68
|
+
/** 工具描述,告诉 Agent 何时使用此工具查看日志 */
|
|
69
|
+
description: string;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 选中的元素信息
|
|
73
|
+
*/
|
|
74
|
+
export interface SelectedElement {
|
|
75
|
+
/** 文件路径 */
|
|
76
|
+
filePath: string | null;
|
|
77
|
+
/** 行号 */
|
|
78
|
+
line: number | null;
|
|
79
|
+
/** 列号 */
|
|
80
|
+
column: number | null;
|
|
81
|
+
/** 元素内部文本 */
|
|
82
|
+
innerText: string;
|
|
83
|
+
/** 元素描述(标签名+选择器) */
|
|
84
|
+
description?: string;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* 页面上下文数据
|
|
88
|
+
*/
|
|
89
|
+
export interface PageContext {
|
|
90
|
+
/** 当前页面 URL */
|
|
91
|
+
url: string;
|
|
92
|
+
/** 当前页面标题 */
|
|
93
|
+
title: string;
|
|
94
|
+
/** 页面唯一标识(sessionStorage 持久化,同 Tab 刷新不变,新 Tab 重生成) */
|
|
95
|
+
sessionId?: string;
|
|
96
|
+
/** Chrome DevTools 中的 pageId,通过 MCP list_pages 解析得到 */
|
|
97
|
+
pageId?: number;
|
|
98
|
+
/** 当前活跃的浏览器 Tab ID(扩展模式),用于在多 Tab 场景下标识具体是哪个 Tab */
|
|
99
|
+
tabId?: number;
|
|
100
|
+
/** Tab 在标签栏的位置索引(从 0 开始),用于 MCP 匹配 Page ID */
|
|
101
|
+
tabIndex?: number;
|
|
102
|
+
/** 选中的元素列表 */
|
|
103
|
+
selectedElements?: SelectedElement[];
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* 服务启动任务状态
|
|
107
|
+
*/
|
|
108
|
+
export type ServiceStartupTask = "checking_provider" | "allocating_port" | "preparing_runtime" | "starting_web" | "waiting_web_ready" | "starting_proxy" | "warming_up_chrome" | "creating_session" | "provider_not_installed" | "web_start_timeout" | "proxy_start_failed" | "session_creation_failed" | "chrome_mcp_failed" | "ready";
|
|
109
|
+
/**
|
|
110
|
+
* 服务启动任务状态映射
|
|
111
|
+
*/
|
|
112
|
+
export declare const SERVICE_STARTUP_TASKS: Record<ServiceStartupTask, string>;
|
|
113
|
+
/**
|
|
114
|
+
* 挂件主题选项
|
|
115
|
+
*/
|
|
116
|
+
export type AIPanelWidgetTheme = "light" | "dark" | "auto";
|
|
117
|
+
/**
|
|
118
|
+
* 服务状态
|
|
119
|
+
*/
|
|
120
|
+
export type ServiceStatus = "idle" | "starting" | "ready" | "partial" | "failed";
|
|
121
|
+
/**
|
|
122
|
+
* Session 状态类型
|
|
123
|
+
*/
|
|
124
|
+
export type AIPanelSessionStatusType = "idle" | "running" | "streaming" | "completed";
|
|
125
|
+
/**
|
|
126
|
+
* Session 思考状态
|
|
127
|
+
*/
|
|
128
|
+
export interface AIPanelSessionThinkingState {
|
|
129
|
+
thinking: boolean;
|
|
130
|
+
statusType: AIPanelSessionStatusType;
|
|
131
|
+
hasPending: boolean;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* 挂件会话信息
|
|
135
|
+
*/
|
|
136
|
+
export interface AIPanelWidgetSession {
|
|
137
|
+
id: string;
|
|
138
|
+
title?: string;
|
|
139
|
+
updatedAt?: string | number | Date;
|
|
140
|
+
meta?: string;
|
|
141
|
+
directory?: string;
|
|
142
|
+
url?: string;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* 挂件选中的元素
|
|
146
|
+
*/
|
|
147
|
+
export interface AIPanelSelectedElement {
|
|
148
|
+
filePath: string | null;
|
|
149
|
+
line: number | null;
|
|
150
|
+
column: number | null;
|
|
151
|
+
innerText: string;
|
|
152
|
+
description?: string;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* 删除选中节点的载荷
|
|
156
|
+
*/
|
|
157
|
+
export interface AIPanelRemoveSelectedPayload {
|
|
158
|
+
element: AIPanelSelectedElement;
|
|
159
|
+
index: number;
|
|
160
|
+
source: "panel" | "bubble";
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 挂件会话列表项
|
|
164
|
+
*/
|
|
165
|
+
export interface AIPanelWidgetSessionItem {
|
|
166
|
+
key: string;
|
|
167
|
+
id: string;
|
|
168
|
+
title: string;
|
|
169
|
+
meta: string;
|
|
170
|
+
active: boolean;
|
|
171
|
+
session: AIPanelWidgetSession;
|
|
172
|
+
[key: string]: any;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* 选中元素列表项
|
|
176
|
+
*/
|
|
177
|
+
export interface AIPanelSelectedElementItem {
|
|
178
|
+
key: string;
|
|
179
|
+
description: string;
|
|
180
|
+
bubbleFileText: string;
|
|
181
|
+
panelFileText: string;
|
|
182
|
+
element: AIPanelSelectedElement;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* 挂件组件 Props
|
|
186
|
+
*/
|
|
187
|
+
export interface AIPanelWidgetProps {
|
|
188
|
+
open?: boolean;
|
|
189
|
+
theme?: AIPanelWidgetTheme;
|
|
190
|
+
title?: string;
|
|
191
|
+
hotkeyLabel?: string;
|
|
192
|
+
selectShortcutLabel?: string;
|
|
193
|
+
selectMode?: boolean;
|
|
194
|
+
sessionListCollapsed?: boolean;
|
|
195
|
+
sessionKey?: string;
|
|
196
|
+
frameLoading?: boolean;
|
|
197
|
+
loadingSessionList?: boolean;
|
|
198
|
+
showSessionListSkeleton?: boolean;
|
|
199
|
+
showEmptyState?: boolean;
|
|
200
|
+
showError?: boolean;
|
|
201
|
+
emptyStateText?: string;
|
|
202
|
+
emptyStateActionText?: string;
|
|
203
|
+
iframeSrc?: string;
|
|
204
|
+
sessions?: AIPanelWidgetSession[];
|
|
205
|
+
currentSessionId?: string | null;
|
|
206
|
+
selectedElements?: AIPanelSelectedElement[];
|
|
207
|
+
showClearAll?: boolean;
|
|
208
|
+
selectEnabled?: boolean;
|
|
209
|
+
thinking?: boolean;
|
|
210
|
+
/** 所有 session 的状态映射 */
|
|
211
|
+
sessionStates?: Record<string, AIPanelSessionThinkingState>;
|
|
212
|
+
/** 展示模式 */
|
|
213
|
+
displayMode?: DisplayMode;
|
|
214
|
+
/** 分屏模式配置 */
|
|
215
|
+
splitMode?: SplitModeOptions;
|
|
216
|
+
/** 分屏面板宽度(运行时状态) */
|
|
217
|
+
splitPanelWidth?: number;
|
|
218
|
+
/** 隐藏悬浮气泡(浏览器扩展模式下使用) */
|
|
219
|
+
hideBubble?: boolean;
|
|
220
|
+
/** 是否支持代码审查面板(右上角 </> 按钮);由 Provider capabilities.reviewPanel 决定 */
|
|
221
|
+
reviewPanelEnabled?: boolean;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* 挂件组件事件
|
|
225
|
+
*/
|
|
226
|
+
export type AIPanelWidgetEmits = {
|
|
227
|
+
(e: "update:open", value: boolean): void;
|
|
228
|
+
(e: "update:selectMode", value: boolean): void;
|
|
229
|
+
(e: "update:sessionListCollapsed", value: boolean): void;
|
|
230
|
+
(e: "update:currentSessionId", value: string | null): void;
|
|
231
|
+
(e: "update:selectedElements", value: AIPanelSelectedElement[]): void;
|
|
232
|
+
(e: "update:theme", value: AIPanelWidgetTheme): void;
|
|
233
|
+
(e: "update:thinking", value: boolean): void;
|
|
234
|
+
(e: "update:splitPanelWidth", value: number): void;
|
|
235
|
+
(e: "toggle", value: boolean): void;
|
|
236
|
+
(e: "close"): void;
|
|
237
|
+
(e: "toggle-session-list", value: boolean): void;
|
|
238
|
+
(e: "toggle-select-mode", value: boolean): void;
|
|
239
|
+
(e: "toggle-theme", value: AIPanelWidgetTheme): void;
|
|
240
|
+
(e: "create-session"): void;
|
|
241
|
+
(e: "select-session", session: AIPanelWidgetSession): void;
|
|
242
|
+
(e: "delete-session", session: AIPanelWidgetSession): void;
|
|
243
|
+
(e: "click-selected-node", element: AIPanelSelectedElement): void;
|
|
244
|
+
(e: "remove-selected-node", payload: AIPanelRemoveSelectedPayload): void;
|
|
245
|
+
(e: "clear-selected-nodes"): void;
|
|
246
|
+
(e: "empty-action"): void;
|
|
247
|
+
(e: "frame-loaded"): void;
|
|
248
|
+
(e: "thinking-change", value: boolean): void;
|
|
249
|
+
(e: "split-panel-width-change", value: number): void;
|
|
250
|
+
};
|
|
251
|
+
export interface ModelInfo {
|
|
252
|
+
providerID: string;
|
|
253
|
+
modelID: string;
|
|
254
|
+
name?: string;
|
|
255
|
+
inputCost: number;
|
|
256
|
+
releaseDate: string;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Chrome MCP 预热错误类型
|
|
260
|
+
*/
|
|
261
|
+
export declare enum ChromeMcpWarmupErrorType {
|
|
262
|
+
CHROME_NOT_CONNECTED = "CHROME_NOT_CONNECTED",
|
|
263
|
+
AI_TIMEOUT = "AI_TIMEOUT",
|
|
264
|
+
AI_RESPONSE_ERROR = "AI_RESPONSE_ERROR",
|
|
265
|
+
SESSION_ERROR = "SESSION_ERROR",
|
|
266
|
+
UNKNOWN = "UNKNOWN"
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Chrome MCP 预热错误
|
|
270
|
+
*/
|
|
271
|
+
export declare class ChromeMcpWarmupError extends Error {
|
|
272
|
+
type: ChromeMcpWarmupErrorType;
|
|
273
|
+
details?: string | undefined;
|
|
274
|
+
constructor(type: ChromeMcpWarmupErrorType, message: string, details?: string | undefined);
|
|
275
|
+
}
|
package/es/types.mjs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
3
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
4
|
+
const SERVICE_STARTUP_TASKS = {
|
|
5
|
+
checking_provider: "\u68C0\u67E5 Provider \u73AF\u5883",
|
|
6
|
+
allocating_port: "\u5206\u914D\u670D\u52A1\u7AEF\u53E3",
|
|
7
|
+
preparing_runtime: "\u51C6\u5907\u8FD0\u884C\u73AF\u5883",
|
|
8
|
+
starting_web: "\u542F\u52A8 Web \u670D\u52A1",
|
|
9
|
+
waiting_web_ready: "\u7B49\u5F85\u670D\u52A1\u5C31\u7EEA",
|
|
10
|
+
starting_proxy: "\u542F\u52A8\u4EE3\u7406\u670D\u52A1",
|
|
11
|
+
warming_up_chrome: "\u9884\u70ED Chrome DevTools",
|
|
12
|
+
creating_session: "\u521B\u5EFA\u4F1A\u8BDD",
|
|
13
|
+
provider_not_installed: "Provider \u672A\u5B89\u88C5",
|
|
14
|
+
web_start_timeout: "\u670D\u52A1\u542F\u52A8\u8D85\u65F6",
|
|
15
|
+
proxy_start_failed: "\u4EE3\u7406\u670D\u52A1\u542F\u52A8\u5931\u8D25",
|
|
16
|
+
session_creation_failed: "\u4F1A\u8BDD\u521B\u5EFA\u5931\u8D25",
|
|
17
|
+
chrome_mcp_failed: "Chrome DevTools \u8FDE\u63A5\u5931\u8D25",
|
|
18
|
+
ready: "\u51C6\u5907\u5B8C\u6210"
|
|
19
|
+
};
|
|
20
|
+
var ChromeMcpWarmupErrorType = /* @__PURE__ */ ((ChromeMcpWarmupErrorType2) => {
|
|
21
|
+
ChromeMcpWarmupErrorType2["CHROME_NOT_CONNECTED"] = "CHROME_NOT_CONNECTED";
|
|
22
|
+
ChromeMcpWarmupErrorType2["AI_TIMEOUT"] = "AI_TIMEOUT";
|
|
23
|
+
ChromeMcpWarmupErrorType2["AI_RESPONSE_ERROR"] = "AI_RESPONSE_ERROR";
|
|
24
|
+
ChromeMcpWarmupErrorType2["SESSION_ERROR"] = "SESSION_ERROR";
|
|
25
|
+
ChromeMcpWarmupErrorType2["UNKNOWN"] = "UNKNOWN";
|
|
26
|
+
return ChromeMcpWarmupErrorType2;
|
|
27
|
+
})(ChromeMcpWarmupErrorType || {});
|
|
28
|
+
class ChromeMcpWarmupError extends Error {
|
|
29
|
+
constructor(type, message, details) {
|
|
30
|
+
super(message);
|
|
31
|
+
__publicField(this, "type", type);
|
|
32
|
+
__publicField(this, "details", details);
|
|
33
|
+
this.name = "ChromeMcpWarmupError";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
ChromeMcpWarmupError,
|
|
38
|
+
ChromeMcpWarmupErrorType,
|
|
39
|
+
SERVICE_STARTUP_TASKS
|
|
40
|
+
};
|
package/es/utils.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview 通用工具函数
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* 截断字符串到指定长度
|
|
6
|
+
* @param value - 要截断的字符串
|
|
7
|
+
* @param maxLength - 最大长度
|
|
8
|
+
* @returns 截断后的字符串,如果超出长度则添加省略号
|
|
9
|
+
*/
|
|
10
|
+
export declare function truncate(value: string, maxLength: number): string;
|
|
11
|
+
/**
|
|
12
|
+
* 延迟指定时间
|
|
13
|
+
* @param ms - 毫秒数
|
|
14
|
+
* @returns Promise
|
|
15
|
+
*/
|
|
16
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* 将字符串编码为 URL-safe Base64(与 Provider 兼容)
|
|
19
|
+
* 替换 + 为 -, / 为 _, 去掉 =
|
|
20
|
+
* @param str - 要编码的字符串
|
|
21
|
+
* @returns URL-safe Base64 编码的字符串
|
|
22
|
+
*/
|
|
23
|
+
export declare function base64Encode(str: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* 将 URL-safe Base64 解码为字符串
|
|
26
|
+
* @param base64 - URL-safe Base64 编码的字符串
|
|
27
|
+
* @returns 解码后的字符串
|
|
28
|
+
*/
|
|
29
|
+
export declare function base64Decode(base64: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* 从响应数据中提取文本内容
|
|
32
|
+
* 支持多种常见响应格式
|
|
33
|
+
*/
|
|
34
|
+
export declare function extractTextFromResponse(data: unknown): string | null;
|