@hopping-dev/hub 0.1.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/assets/hopping-skill/SKILL.md +221 -0
- package/dist/approval/manager.d.ts +60 -0
- package/dist/approval/manager.d.ts.map +1 -0
- package/dist/approval/manager.js +101 -0
- package/dist/approval/manager.js.map +1 -0
- package/dist/approval/session-memory.d.ts +37 -0
- package/dist/approval/session-memory.d.ts.map +1 -0
- package/dist/approval/session-memory.js +63 -0
- package/dist/approval/session-memory.js.map +1 -0
- package/dist/cli/config-writer.d.ts +57 -0
- package/dist/cli/config-writer.d.ts.map +1 -0
- package/dist/cli/config-writer.js +318 -0
- package/dist/cli/config-writer.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +82 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/path-resolver.d.ts +48 -0
- package/dist/cli/path-resolver.d.ts.map +1 -0
- package/dist/cli/path-resolver.js +212 -0
- package/dist/cli/path-resolver.js.map +1 -0
- package/dist/cli/setup.d.ts +10 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +268 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cloud/connector.d.ts +74 -0
- package/dist/cloud/connector.d.ts.map +1 -0
- package/dist/cloud/connector.js +524 -0
- package/dist/cloud/connector.js.map +1 -0
- package/dist/cloud/index.d.ts +3 -0
- package/dist/cloud/index.d.ts.map +1 -0
- package/dist/cloud/index.js +6 -0
- package/dist/cloud/index.js.map +1 -0
- package/dist/config/manager.d.ts +76 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +296 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/dev-mode.d.ts +30 -0
- package/dist/dev-mode.d.ts.map +1 -0
- package/dist/dev-mode.js +53 -0
- package/dist/dev-mode.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +354 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc/index.d.ts +12 -0
- package/dist/ipc/index.d.ts.map +1 -0
- package/dist/ipc/index.js +15 -0
- package/dist/ipc/index.js.map +1 -0
- package/dist/ipc/watcher.d.ts +226 -0
- package/dist/ipc/watcher.d.ts.map +1 -0
- package/dist/ipc/watcher.js +745 -0
- package/dist/ipc/watcher.js.map +1 -0
- package/dist/local/approval-dialog.d.ts +30 -0
- package/dist/local/approval-dialog.d.ts.map +1 -0
- package/dist/local/approval-dialog.js +214 -0
- package/dist/local/approval-dialog.js.map +1 -0
- package/dist/local/index.d.ts +8 -0
- package/dist/local/index.d.ts.map +1 -0
- package/dist/local/index.js +13 -0
- package/dist/local/index.js.map +1 -0
- package/dist/local/local-approval.d.ts +55 -0
- package/dist/local/local-approval.d.ts.map +1 -0
- package/dist/local/local-approval.js +125 -0
- package/dist/local/local-approval.js.map +1 -0
- package/dist/local/notifier.d.ts +19 -0
- package/dist/local/notifier.d.ts.map +1 -0
- package/dist/local/notifier.js +110 -0
- package/dist/local/notifier.js.map +1 -0
- package/dist/local/sanitize.d.ts +20 -0
- package/dist/local/sanitize.d.ts.map +1 -0
- package/dist/local/sanitize.js +28 -0
- package/dist/local/sanitize.js.map +1 -0
- package/dist/mcp/file-extractor.d.ts +11 -0
- package/dist/mcp/file-extractor.d.ts.map +1 -0
- package/dist/mcp/file-extractor.js +74 -0
- package/dist/mcp/file-extractor.js.map +1 -0
- package/dist/mcp/risk-level.d.ts +44 -0
- package/dist/mcp/risk-level.d.ts.map +1 -0
- package/dist/mcp/risk-level.js +127 -0
- package/dist/mcp/risk-level.js.map +1 -0
- package/dist/mcp/schemas.d.ts +83 -0
- package/dist/mcp/schemas.d.ts.map +1 -0
- package/dist/mcp/schemas.js +84 -0
- package/dist/mcp/schemas.js.map +1 -0
- package/dist/mcp/summary.d.ts +11 -0
- package/dist/mcp/summary.d.ts.map +1 -0
- package/dist/mcp/summary.js +150 -0
- package/dist/mcp/summary.js.map +1 -0
- package/dist/mcp/tools.d.ts +45 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +1217 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/pairing/auto-pairing.d.ts +37 -0
- package/dist/pairing/auto-pairing.d.ts.map +1 -0
- package/dist/pairing/auto-pairing.js +144 -0
- package/dist/pairing/auto-pairing.js.map +1 -0
- package/dist/pairing/binding-poller.d.ts +26 -0
- package/dist/pairing/binding-poller.d.ts.map +1 -0
- package/dist/pairing/binding-poller.js +108 -0
- package/dist/pairing/binding-poller.js.map +1 -0
- package/dist/pairing/pairing-server.d.ts +14 -0
- package/dist/pairing/pairing-server.d.ts.map +1 -0
- package/dist/pairing/pairing-server.js +277 -0
- package/dist/pairing/pairing-server.js.map +1 -0
- package/dist/pairing/qr-display.d.ts +14 -0
- package/dist/pairing/qr-display.d.ts.map +1 -0
- package/dist/pairing/qr-display.js +40 -0
- package/dist/pairing/qr-display.js.map +1 -0
- package/dist/policy/engine.d.ts +31 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +187 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/store.d.ts +26 -0
- package/dist/policy/store.d.ts.map +1 -0
- package/dist/policy/store.js +70 -0
- package/dist/policy/store.js.map +1 -0
- package/dist/policy/system-policies.d.ts +15 -0
- package/dist/policy/system-policies.d.ts.map +1 -0
- package/dist/policy/system-policies.js +265 -0
- package/dist/policy/system-policies.js.map +1 -0
- package/dist/policy/tool-mapping.d.ts +45 -0
- package/dist/policy/tool-mapping.d.ts.map +1 -0
- package/dist/policy/tool-mapping.js +88 -0
- package/dist/policy/tool-mapping.js.map +1 -0
- package/dist/policy/tool-registry.json +85 -0
- package/dist/store/db.d.ts +17 -0
- package/dist/store/db.d.ts.map +1 -0
- package/dist/store/db.js +193 -0
- package/dist/store/db.js.map +1 -0
- package/dist/store/index.d.ts +4 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +7 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/metadata.d.ts +31 -0
- package/dist/store/metadata.d.ts.map +1 -0
- package/dist/store/metadata.js +178 -0
- package/dist/store/metadata.js.map +1 -0
- package/dist/store/operations.d.ts +26 -0
- package/dist/store/operations.d.ts.map +1 -0
- package/dist/store/operations.js +171 -0
- package/dist/store/operations.js.map +1 -0
- package/dist/utils/json.d.ts +7 -0
- package/dist/utils/json.d.ts.map +1 -0
- package/dist/utils/json.js +33 -0
- package/dist/utils/json.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +58 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/open-browser.d.ts +8 -0
- package/dist/utils/open-browser.d.ts.map +1 -0
- package/dist/utils/open-browser.js +38 -0
- package/dist/utils/open-browser.js.map +1 -0
- package/node_modules/@hopping/shared/dist/types.d.ts +649 -0
- package/node_modules/@hopping/shared/dist/types.js +48 -0
- package/node_modules/@hopping/shared/dist/types.js.map +1 -0
- package/node_modules/@hopping/shared/package.json +14 -0
- package/node_modules/@hopping/shared/tsconfig.json +16 -0
- package/node_modules/@hopping/shared/types.d.ts +650 -0
- package/node_modules/@hopping/shared/types.d.ts.map +1 -0
- package/node_modules/@hopping/shared/types.js +48 -0
- package/node_modules/@hopping/shared/types.js.map +1 -0
- package/node_modules/@hopping/shared/types.ts +895 -0
- package/package.json +52 -0
|
@@ -0,0 +1,524 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CloudConnector = void 0;
|
|
4
|
+
const socket_io_client_1 = require("socket.io-client");
|
|
5
|
+
const shared_1 = require("@hopping/shared");
|
|
6
|
+
const json_1 = require("../utils/json");
|
|
7
|
+
// ============================================
|
|
8
|
+
// Constants
|
|
9
|
+
// ============================================
|
|
10
|
+
const DEFAULT_CONNECT_TIMEOUT_MS = 10_000;
|
|
11
|
+
// ============================================
|
|
12
|
+
// CloudConnector
|
|
13
|
+
// ============================================
|
|
14
|
+
/**
|
|
15
|
+
* CloudConnector — Hub 端的 socket.io-client 封裝
|
|
16
|
+
*
|
|
17
|
+
* 負責:
|
|
18
|
+
* 1. 使用 agent token 連接 Cloud Gateway
|
|
19
|
+
* 2. Hub → Cloud 事件發送(permission_prompt, agent_status, progress_update, detail_response, stats_response)
|
|
20
|
+
* 3. Cloud → Hub 事件接收(permission_response, detail_request, stats_request, command)
|
|
21
|
+
* 4. 優雅降級:連線失敗不阻擋 MCP Server 運行
|
|
22
|
+
*/
|
|
23
|
+
class CloudConnector {
|
|
24
|
+
socket;
|
|
25
|
+
_connected = false;
|
|
26
|
+
logger;
|
|
27
|
+
approvalManager;
|
|
28
|
+
store;
|
|
29
|
+
connectTimeoutMs;
|
|
30
|
+
/** YOLO 模式偵測 getter(可選) */
|
|
31
|
+
getAgentMode;
|
|
32
|
+
/** ENH-YOLO-002:記住 YOLO 進入時間,避免重連時重置 Mobile 計時器 */
|
|
33
|
+
_yoloEnteredAt;
|
|
34
|
+
/** S4-HUB-DONTASK-001:Session 免審記憶 */
|
|
35
|
+
sessionMemory;
|
|
36
|
+
/** Cloud 認證後回傳的 agentId(Cloud DB 中的 UUID) */
|
|
37
|
+
_agentId;
|
|
38
|
+
/** Cloud 認證後回傳的 agentName */
|
|
39
|
+
_agentName;
|
|
40
|
+
constructor(options) {
|
|
41
|
+
this.logger = options.logger;
|
|
42
|
+
this.approvalManager = options.approvalManager;
|
|
43
|
+
this.store = options.store;
|
|
44
|
+
this.connectTimeoutMs = options.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;
|
|
45
|
+
this.getAgentMode = options.getAgentMode;
|
|
46
|
+
this.sessionMemory = options.sessionMemory;
|
|
47
|
+
this.socket = (0, socket_io_client_1.io)(options.cloudUrl, {
|
|
48
|
+
auth: { token: options.agentToken },
|
|
49
|
+
transports: ['websocket', 'polling'],
|
|
50
|
+
autoConnect: false,
|
|
51
|
+
reconnection: true, // S1-HUB-CLOUD-002:啟用自動重連
|
|
52
|
+
reconnectionDelay: 1000, // 1s 起始
|
|
53
|
+
reconnectionDelayMax: 30000, // 最長 30s(指數退避)
|
|
54
|
+
reconnectionAttempts: Infinity, // 永遠嘗試,Hub 本地模式持續運行
|
|
55
|
+
});
|
|
56
|
+
this.bindEventListeners();
|
|
57
|
+
}
|
|
58
|
+
// ─── Lifecycle ──────────────────────────────────────────────────────────────
|
|
59
|
+
/**
|
|
60
|
+
* 連接 Cloud Gateway 並等待認證結果
|
|
61
|
+
*
|
|
62
|
+
* - 成功:_connected = true(由持久 authenticated listener 設定)
|
|
63
|
+
* - 失敗/超時:_connected = false,不 throw(Hub 降級為純本地模式)
|
|
64
|
+
*
|
|
65
|
+
* 注意:自動重連由 socket.io 在背景持續嘗試,connect() 僅處理初始握手超時。
|
|
66
|
+
*/
|
|
67
|
+
async connect() {
|
|
68
|
+
this.logger.info('CloudConnector: 連接 Cloud Gateway...');
|
|
69
|
+
return new Promise((resolve) => {
|
|
70
|
+
const untyped = this.socket;
|
|
71
|
+
// 一次性 authenticated listener(僅用於 resolve 初始 connect() promise)
|
|
72
|
+
// 狀態(_connected, _agentId, _agentName)由 bindEventListeners() 的持久 listener 管理
|
|
73
|
+
const onAuthenticated = () => {
|
|
74
|
+
clearTimeout(timer);
|
|
75
|
+
untyped.off('error', onError);
|
|
76
|
+
resolve();
|
|
77
|
+
};
|
|
78
|
+
// 一次性 error listener(認證失敗 → resolve promise,Hub 降級本地模式)
|
|
79
|
+
const onError = (...args) => {
|
|
80
|
+
clearTimeout(timer);
|
|
81
|
+
untyped.off('authenticated', onAuthenticated);
|
|
82
|
+
this._connected = false;
|
|
83
|
+
const err = args[0];
|
|
84
|
+
const errMsg = err instanceof Error ? err.message : (err?.message ?? String(err));
|
|
85
|
+
this.logger.error('CloudConnector: 認證失敗', { error: errMsg });
|
|
86
|
+
resolve();
|
|
87
|
+
};
|
|
88
|
+
const timer = setTimeout(() => {
|
|
89
|
+
untyped.off('authenticated', onAuthenticated);
|
|
90
|
+
untyped.off('error', onError);
|
|
91
|
+
this._connected = false;
|
|
92
|
+
this.logger.warn('CloudConnector: 初始連線超時,Hub 以本地模式運行(自動重連中)', {
|
|
93
|
+
timeoutMs: this.connectTimeoutMs,
|
|
94
|
+
});
|
|
95
|
+
resolve();
|
|
96
|
+
}, this.connectTimeoutMs);
|
|
97
|
+
// 'authenticated' 和 'error' 是 Gateway handshake 的自定義事件
|
|
98
|
+
untyped.once('authenticated', onAuthenticated);
|
|
99
|
+
untyped.once('error', onError);
|
|
100
|
+
this.socket.connect();
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* 斷開連線並清理資源
|
|
105
|
+
*/
|
|
106
|
+
async disconnect() {
|
|
107
|
+
this.logger.info('CloudConnector: 斷開連線...');
|
|
108
|
+
this._connected = false;
|
|
109
|
+
this.socket.removeAllListeners();
|
|
110
|
+
this.socket.disconnect();
|
|
111
|
+
}
|
|
112
|
+
// ─── State ──────────────────────────────────────────────────────────────────
|
|
113
|
+
get isConnected() {
|
|
114
|
+
return this._connected;
|
|
115
|
+
}
|
|
116
|
+
get cloudAgentId() {
|
|
117
|
+
return this._agentId;
|
|
118
|
+
}
|
|
119
|
+
get cloudAgentName() {
|
|
120
|
+
return this._agentName;
|
|
121
|
+
}
|
|
122
|
+
// ─── Hub → Cloud 事件發送 ───────────────────────────────────────────────────
|
|
123
|
+
sendPermissionPrompt(payload) {
|
|
124
|
+
if (!this._connected) {
|
|
125
|
+
this.logger.warn('CloudConnector: 未連線,無法發送 permission_prompt');
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
this.socket.emit('permission_prompt', payload);
|
|
129
|
+
this.logger.debug('CloudConnector: sent permission_prompt', {
|
|
130
|
+
id: payload.id,
|
|
131
|
+
toolName: payload.toolName,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
sendAgentStatus(payload) {
|
|
135
|
+
if (!this._connected) {
|
|
136
|
+
this.logger.warn('CloudConnector: 未連線,無法發送 agent_status');
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this.socket.emit('agent_status', payload);
|
|
140
|
+
this.logger.debug('CloudConnector: sent agent_status', {
|
|
141
|
+
agentId: payload.agentId,
|
|
142
|
+
status: payload.status,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
sendProgressUpdate(payload) {
|
|
146
|
+
if (!this._connected) {
|
|
147
|
+
this.logger.warn('CloudConnector: 未連線,無法發送 progress_update');
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
this.socket.emit('progress_update', payload);
|
|
151
|
+
this.logger.debug('CloudConnector: sent progress_update', {
|
|
152
|
+
agentId: payload.agentId,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
sendDetailResponse(payload) {
|
|
156
|
+
if (!this._connected) {
|
|
157
|
+
this.logger.warn('CloudConnector: 未連線,無法發送 detail_response');
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
this.socket.emit('detail_response', payload);
|
|
161
|
+
this.logger.debug('CloudConnector: sent detail_response', {
|
|
162
|
+
operationId: payload.operationId,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
sendStatsResponse(payload) {
|
|
166
|
+
if (!this._connected) {
|
|
167
|
+
this.logger.warn('CloudConnector: 未連線,無法發送 stats_response');
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
this.socket.emit('stats_response', payload);
|
|
171
|
+
this.logger.debug('CloudConnector: sent stats_response', {
|
|
172
|
+
agentId: payload.agentId,
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
// ─── Cloud → Hub 事件接收(內部綁定) ───────────────────────────────────────
|
|
176
|
+
bindEventListeners() {
|
|
177
|
+
const untyped = this.socket;
|
|
178
|
+
// ─── 持久 authenticated listener(初始連線 + 每次重連後皆觸發)─────────
|
|
179
|
+
//
|
|
180
|
+
// Gateway 在每次新 socket 建立後都會發送 'authenticated',
|
|
181
|
+
// 因此此 listener 同時處理初始認證與重連後的重新認證。
|
|
182
|
+
// connect() 的 once('authenticated') 僅用於 resolve 初始 promise,
|
|
183
|
+
// 狀態管理集中在此。
|
|
184
|
+
untyped.on('authenticated', (...args) => {
|
|
185
|
+
const payload = (args[0] ?? {});
|
|
186
|
+
const wasConnected = this._connected;
|
|
187
|
+
this._connected = true;
|
|
188
|
+
this._agentId = payload.agentId;
|
|
189
|
+
this._agentName = payload.agentName;
|
|
190
|
+
if (wasConnected) {
|
|
191
|
+
this.logger.info('CloudConnector: 重連並重新認證成功', {
|
|
192
|
+
agentId: payload.agentId ?? 'unknown',
|
|
193
|
+
agentName: payload.agentName ?? 'unknown',
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
this.logger.info('CloudConnector: 已連線並認證', {
|
|
198
|
+
agentId: payload.agentId ?? 'unknown',
|
|
199
|
+
agentName: payload.agentName ?? 'unknown',
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
// REQ-HUB-048: 發送 agent_status 帶 agentMode(所有模式皆發送,便於 Mobile 顯示)
|
|
203
|
+
if (this._agentId && this.getAgentMode) {
|
|
204
|
+
const agentMode = this.getAgentMode();
|
|
205
|
+
const now = new Date().toISOString();
|
|
206
|
+
const statusPayload = {
|
|
207
|
+
agentId: this._agentId,
|
|
208
|
+
status: 'online',
|
|
209
|
+
agentName: this._agentName,
|
|
210
|
+
timestamp: now,
|
|
211
|
+
agentMode,
|
|
212
|
+
};
|
|
213
|
+
if (agentMode === 'yolo') {
|
|
214
|
+
// ENH-YOLO-002: 首次記錄 YOLO 進入時間,重連時沿用(避免 Mobile 計時器重置)
|
|
215
|
+
if (!this._yoloEnteredAt) {
|
|
216
|
+
this._yoloEnteredAt = now;
|
|
217
|
+
}
|
|
218
|
+
statusPayload.agentModeChangedAt = this._yoloEnteredAt;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
this._yoloEnteredAt = undefined;
|
|
222
|
+
}
|
|
223
|
+
this.sendAgentStatus(statusPayload);
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
// ─── Manager 層級重連事件(logging only)────────────────────────────────
|
|
227
|
+
const manager = this.socket.io;
|
|
228
|
+
if (manager) {
|
|
229
|
+
manager.on('reconnect_attempt', (attempt) => {
|
|
230
|
+
this.logger.info('CloudConnector: 重連中...', { attempt });
|
|
231
|
+
});
|
|
232
|
+
manager.on('reconnect', () => {
|
|
233
|
+
this.logger.info('CloudConnector: 重連連線成功,等待認證...');
|
|
234
|
+
});
|
|
235
|
+
manager.on('reconnect_error', (err) => {
|
|
236
|
+
const errMsg = err instanceof Error ? err.message : String(err);
|
|
237
|
+
this.logger.warn('CloudConnector: 重連嘗試失敗', { error: errMsg });
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
// ─── 永久 disconnect listener ─────────────────────────────────────────
|
|
241
|
+
this.socket.on('disconnect', (reason) => {
|
|
242
|
+
const wasConnected = this._connected;
|
|
243
|
+
this._connected = false;
|
|
244
|
+
this.logger.warn('CloudConnector: 連線已斷開', { reason, wasConnected });
|
|
245
|
+
});
|
|
246
|
+
// ─── 永久 connect_error listener ─────────────────────────────────────
|
|
247
|
+
this.socket.on('connect_error', (err) => {
|
|
248
|
+
this._connected = false;
|
|
249
|
+
this.logger.error('CloudConnector: 連線錯誤', {
|
|
250
|
+
error: err.message ?? String(err),
|
|
251
|
+
});
|
|
252
|
+
});
|
|
253
|
+
// permission_response — 審核回應,橋接 ApprovalManager
|
|
254
|
+
this.socket.on('permission_response', (payload) => {
|
|
255
|
+
this.handlePermissionResponse(payload);
|
|
256
|
+
});
|
|
257
|
+
// detail_request — 手機請求操作完整內容
|
|
258
|
+
this.socket.on('detail_request', (payload) => {
|
|
259
|
+
this.handleDetailRequest(payload);
|
|
260
|
+
});
|
|
261
|
+
// stats_request — 手機請求統計數據
|
|
262
|
+
this.socket.on('stats_request', (payload) => {
|
|
263
|
+
this.handleStatsRequest(payload);
|
|
264
|
+
});
|
|
265
|
+
// command — 手機下指令(S2 以後才有完整處理)
|
|
266
|
+
this.socket.on('command', (payload) => {
|
|
267
|
+
this.handleCommand(payload);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
handlePermissionResponse(payload) {
|
|
271
|
+
this.logger.info('CloudConnector: 收到 permission_response', {
|
|
272
|
+
id: payload.id,
|
|
273
|
+
decision: payload.decision,
|
|
274
|
+
});
|
|
275
|
+
const approved = payload.decision === 'approved' || payload.decision === 'conditional';
|
|
276
|
+
const reason = payload.reason ?? `Decision: ${payload.decision}`;
|
|
277
|
+
// 提取 rich response 欄位(Mobile 選擇題/自由填寫回應)
|
|
278
|
+
const richResponse = payload.selectedOption !== undefined ||
|
|
279
|
+
payload.freetext !== undefined ||
|
|
280
|
+
payload.customText !== undefined
|
|
281
|
+
? {
|
|
282
|
+
selectedOption: payload.selectedOption,
|
|
283
|
+
freetext: payload.freetext,
|
|
284
|
+
customText: payload.customText,
|
|
285
|
+
}
|
|
286
|
+
: undefined;
|
|
287
|
+
this.approvalManager.resolveApproval(payload.id, approved, reason, 'mobile', richResponse);
|
|
288
|
+
// 同步更新 SQLite 操作決策
|
|
289
|
+
if (this.store) {
|
|
290
|
+
const decidedAt = payload.timestamp ?? new Date().toISOString();
|
|
291
|
+
this.store.operations.updateDecision(payload.id, payload.decision, decidedAt);
|
|
292
|
+
// 若有 rich response,更新 response_data
|
|
293
|
+
if (richResponse) {
|
|
294
|
+
this.store.operations.updateResponseData(payload.id, JSON.stringify(richResponse));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// S4-HUB-DONTASK-001: 偵測 "don't ask again" 回應,寫入 session memory
|
|
298
|
+
const VALID_RISK_LEVELS = new Set(['low', 'medium', 'high', 'critical']);
|
|
299
|
+
if (approved && payload.reason === 'dont_ask_again' && this.sessionMemory && this.store) {
|
|
300
|
+
const op = this.store.operations.getById(payload.id);
|
|
301
|
+
if (op?.toolName && op.riskLevel && VALID_RISK_LEVELS.has(op.riskLevel)) {
|
|
302
|
+
this.sessionMemory.add(op.toolName, op.riskLevel);
|
|
303
|
+
this.logger.info('CloudConnector: session memory updated', {
|
|
304
|
+
toolName: op.toolName,
|
|
305
|
+
riskLevel: op.riskLevel,
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
sendDetailError(operationId, error) {
|
|
311
|
+
this.sendDetailResponse({
|
|
312
|
+
operationId,
|
|
313
|
+
toolName: '',
|
|
314
|
+
createdAt: new Date().toISOString(),
|
|
315
|
+
error,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
handleDetailRequest(payload) {
|
|
319
|
+
this.logger.info('CloudConnector: 收到 detail_request', {
|
|
320
|
+
operationId: payload.operationId,
|
|
321
|
+
});
|
|
322
|
+
// 輸入驗證:operationId 必須是非空字串
|
|
323
|
+
if (!payload.operationId || typeof payload.operationId !== 'string') {
|
|
324
|
+
this.logger.warn('CloudConnector: detail_request operationId 無效', {
|
|
325
|
+
operationId: payload.operationId,
|
|
326
|
+
});
|
|
327
|
+
this.sendDetailError(payload.operationId ?? '', shared_1.DETAIL_RESPONSE_ERRORS.INVALID_OPERATION_ID);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
if (!this.store) {
|
|
331
|
+
this.logger.warn('CloudConnector: 無 store,無法回應 detail_request');
|
|
332
|
+
this.sendDetailError(payload.operationId, shared_1.DETAIL_RESPONSE_ERRORS.INTERNAL_ERROR);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
const record = this.store.operations.getById(payload.operationId);
|
|
336
|
+
if (!record) {
|
|
337
|
+
this.logger.warn('CloudConnector: 找不到操作記錄', {
|
|
338
|
+
operationId: payload.operationId,
|
|
339
|
+
});
|
|
340
|
+
this.sendDetailError(payload.operationId, shared_1.DETAIL_RESPONSE_ERRORS.NOT_FOUND);
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
// 查詢 metadata(含 userPrompt,透過 transparent relay 送到 Mobile)
|
|
344
|
+
const metadataRecords = this.store.metadata.getByOperationId(payload.operationId);
|
|
345
|
+
const meta = metadataRecords.length > 0 ? metadataRecords[0] : undefined;
|
|
346
|
+
const response = {
|
|
347
|
+
operationId: record.id,
|
|
348
|
+
toolName: record.toolName,
|
|
349
|
+
toolParams: record.toolParams ? (0, json_1.safeJsonParseObject)(record.toolParams) : undefined,
|
|
350
|
+
filePaths: record.filePaths ? (0, json_1.safeJsonParseArray)(record.filePaths) : undefined,
|
|
351
|
+
riskLevel: record.riskLevel ?? undefined,
|
|
352
|
+
decision: record.decision ?? undefined,
|
|
353
|
+
createdAt: record.createdAt,
|
|
354
|
+
decidedAt: record.decidedAt ?? undefined,
|
|
355
|
+
metadata: meta
|
|
356
|
+
? {
|
|
357
|
+
agentType: meta.agentType,
|
|
358
|
+
sessionId: meta.sessionId,
|
|
359
|
+
durationMs: meta.durationMs,
|
|
360
|
+
contextTags: meta.contextTags ? (0, json_1.safeJsonParseObject)(meta.contextTags) : null,
|
|
361
|
+
source: meta.source ?? undefined,
|
|
362
|
+
resultStatus: meta.resultStatus ?? undefined,
|
|
363
|
+
toolResultSummary: meta.toolResultSummary ?? undefined,
|
|
364
|
+
}
|
|
365
|
+
: undefined,
|
|
366
|
+
};
|
|
367
|
+
this.sendDetailResponse(response);
|
|
368
|
+
}
|
|
369
|
+
calculateDateRange(period, timezoneOffset) {
|
|
370
|
+
// timezoneOffset: JS getTimezoneOffset() semantics — UTC+8 = -480, UTC-7 = 420
|
|
371
|
+
// local = UTC - offset → UTC = local + offset
|
|
372
|
+
const offsetMs = timezoneOffset * 60_000;
|
|
373
|
+
const nowMs = Date.now();
|
|
374
|
+
// Express current moment as local wall-clock coordinates via UTC getters
|
|
375
|
+
const localNow = new Date(nowMs - offsetMs);
|
|
376
|
+
const localMidnight = new Date(Date.UTC(localNow.getUTCFullYear(), localNow.getUTCMonth(), localNow.getUTCDate()));
|
|
377
|
+
// Convert local midnight back to its actual UTC moment
|
|
378
|
+
const todayStartUtc = new Date(localMidnight.getTime() + offsetMs);
|
|
379
|
+
const tomorrowStartUtc = new Date(todayStartUtc.getTime() + 24 * 60 * 60_000);
|
|
380
|
+
switch (period) {
|
|
381
|
+
case 'day':
|
|
382
|
+
return { startUtc: todayStartUtc.toISOString(), endUtc: tomorrowStartUtc.toISOString() };
|
|
383
|
+
case 'week': {
|
|
384
|
+
const weekStartUtc = new Date(todayStartUtc.getTime() - 6 * 24 * 60 * 60_000);
|
|
385
|
+
return { startUtc: weekStartUtc.toISOString(), endUtc: tomorrowStartUtc.toISOString() };
|
|
386
|
+
}
|
|
387
|
+
case 'month': {
|
|
388
|
+
const monthStartUtc = new Date(todayStartUtc.getTime() - 29 * 24 * 60 * 60_000);
|
|
389
|
+
return { startUtc: monthStartUtc.toISOString(), endUtc: tomorrowStartUtc.toISOString() };
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
handleStatsRequest(payload) {
|
|
394
|
+
this.logger.info('CloudConnector: 收到 stats_request', {
|
|
395
|
+
agentId: payload.agentId,
|
|
396
|
+
type: payload.type ?? 'stats',
|
|
397
|
+
});
|
|
398
|
+
if (payload.type === 'session_timeline') {
|
|
399
|
+
const limit = Math.min(payload.limit ?? 100, 500);
|
|
400
|
+
const timeline = this.store
|
|
401
|
+
? this.store.metadata.getRecentTimeline(limit).map((entry) => ({
|
|
402
|
+
operationId: entry.operationId,
|
|
403
|
+
toolName: entry.toolName,
|
|
404
|
+
riskLevel: entry.riskLevel,
|
|
405
|
+
decision: entry.decision,
|
|
406
|
+
durationMs: entry.durationMs,
|
|
407
|
+
source: entry.source,
|
|
408
|
+
createdAt: entry.createdAt,
|
|
409
|
+
}))
|
|
410
|
+
: [];
|
|
411
|
+
const response = {
|
|
412
|
+
agentId: payload.agentId,
|
|
413
|
+
period: 'day',
|
|
414
|
+
totalOperations: 0,
|
|
415
|
+
approvedCount: 0,
|
|
416
|
+
deniedCount: 0,
|
|
417
|
+
autoApprovedCount: 0,
|
|
418
|
+
topTools: [],
|
|
419
|
+
timeline,
|
|
420
|
+
};
|
|
421
|
+
this.sendStatsResponse(response);
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
const period = payload.period ?? 'day';
|
|
425
|
+
const rawOffset = payload.timezoneOffset ?? 0;
|
|
426
|
+
const timezoneOffset = Math.max(-720, Math.min(840, Math.round(rawOffset)));
|
|
427
|
+
if (!this.store) {
|
|
428
|
+
const response = {
|
|
429
|
+
agentId: payload.agentId,
|
|
430
|
+
period,
|
|
431
|
+
totalOperations: 0,
|
|
432
|
+
approvedCount: 0,
|
|
433
|
+
deniedCount: 0,
|
|
434
|
+
autoApprovedCount: 0,
|
|
435
|
+
topTools: [],
|
|
436
|
+
};
|
|
437
|
+
this.sendStatsResponse(response);
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
const { startUtc, endUtc } = this.calculateDateRange(period, timezoneOffset);
|
|
441
|
+
const counts = this.store.operations.countByDecisionRange(startUtc, endUtc);
|
|
442
|
+
const topTools = this.store.metadata
|
|
443
|
+
.getToolUsageStatsRange(startUtc, endUtc, 10)
|
|
444
|
+
.map((s) => ({ toolName: s.toolName, count: s.count }));
|
|
445
|
+
const response = {
|
|
446
|
+
agentId: payload.agentId,
|
|
447
|
+
period,
|
|
448
|
+
totalOperations: counts.total,
|
|
449
|
+
approvedCount: counts.approved,
|
|
450
|
+
deniedCount: counts.denied,
|
|
451
|
+
autoApprovedCount: counts.autoApproved,
|
|
452
|
+
topTools,
|
|
453
|
+
};
|
|
454
|
+
this.sendStatsResponse(response);
|
|
455
|
+
}
|
|
456
|
+
handleCommand(payload) {
|
|
457
|
+
this.logger.info('CloudConnector: 收到 command', {
|
|
458
|
+
agentId: payload.agentId,
|
|
459
|
+
command: payload.command,
|
|
460
|
+
});
|
|
461
|
+
const agentId = this._agentId ?? payload.agentId;
|
|
462
|
+
const sessionId = agentId;
|
|
463
|
+
const now = new Date().toISOString();
|
|
464
|
+
const command = payload.command.trim().toLowerCase();
|
|
465
|
+
switch (command) {
|
|
466
|
+
case 'status': {
|
|
467
|
+
const pendingCount = this.approvalManager.pendingCount;
|
|
468
|
+
const todayOps = this.store?.operations.countToday() ?? 0;
|
|
469
|
+
const connectedStr = this._connected ? '已連線' : '離線';
|
|
470
|
+
const message = `Hub 狀態:待審 ${pendingCount} 件、今日 ${todayOps} 次操作、雲端連線:${connectedStr}`;
|
|
471
|
+
this.sendProgressUpdate({
|
|
472
|
+
agentId,
|
|
473
|
+
sessionId,
|
|
474
|
+
message,
|
|
475
|
+
timestamp: now,
|
|
476
|
+
messageType: 'status_report',
|
|
477
|
+
});
|
|
478
|
+
break;
|
|
479
|
+
}
|
|
480
|
+
case 'continue': {
|
|
481
|
+
this.sendProgressUpdate({
|
|
482
|
+
agentId,
|
|
483
|
+
sessionId,
|
|
484
|
+
message: '收到指令:繼續執行',
|
|
485
|
+
timestamp: now,
|
|
486
|
+
messageType: 'command_ack',
|
|
487
|
+
});
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
case 'pause': {
|
|
491
|
+
this.sendProgressUpdate({
|
|
492
|
+
agentId,
|
|
493
|
+
sessionId,
|
|
494
|
+
message: '收到指令:暫停(實際效果由 Agent Skill 決定)',
|
|
495
|
+
timestamp: now,
|
|
496
|
+
messageType: 'command_ack',
|
|
497
|
+
});
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
case 'retry': {
|
|
501
|
+
this.sendProgressUpdate({
|
|
502
|
+
agentId,
|
|
503
|
+
sessionId,
|
|
504
|
+
message: '收到指令:重試',
|
|
505
|
+
timestamp: now,
|
|
506
|
+
messageType: 'command_ack',
|
|
507
|
+
});
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
default: {
|
|
511
|
+
this.sendProgressUpdate({
|
|
512
|
+
agentId,
|
|
513
|
+
sessionId,
|
|
514
|
+
message: `收到指令:${payload.command}`,
|
|
515
|
+
timestamp: now,
|
|
516
|
+
messageType: 'command_ack',
|
|
517
|
+
});
|
|
518
|
+
break;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
exports.CloudConnector = CloudConnector;
|
|
524
|
+
//# sourceMappingURL=connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.js","sourceRoot":"","sources":["../../src/cloud/connector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cloud/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CloudConnector = void 0;
|
|
4
|
+
var connector_1 = require("./connector");
|
|
5
|
+
Object.defineProperty(exports, "CloudConnector", { enumerable: true, get: function () { return connector_1.CloudConnector; } });
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cloud/index.ts"],"names":[],"mappings":";;;AAAA,yCAA6C;AAApC,2GAAA,cAAc,OAAA"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { TimeoutDecision, HubLocalConfig, LocalApprovalConfig, AskConfig } from '@hopping/shared';
|
|
2
|
+
import type { ToolRegistry } from '../policy/tool-mapping';
|
|
3
|
+
export declare const DEFAULT_CONFIG_DIR: string;
|
|
4
|
+
export declare const DEFAULT_CONFIG_FILE: string;
|
|
5
|
+
/** 使用者可設定的超時行為(user-facing)。Hub 在送往 Cloud 前透過 toApprovalDecision() 轉換。 */
|
|
6
|
+
export type TimeoutAction = 'ask_agent' | 'keep_open' | 'auto_approve' | 'auto_deny';
|
|
7
|
+
/** TimeoutAction → TimeoutDecision 轉換(送往 Cloud 前使用) */
|
|
8
|
+
export declare function toApprovalDecision(action: TimeoutAction): TimeoutDecision;
|
|
9
|
+
export interface ApprovalTimeoutConfig {
|
|
10
|
+
timeouts: Record<'low' | 'medium' | 'high' | 'critical', number>;
|
|
11
|
+
onTimeout: Record<'low' | 'medium' | 'high' | 'critical', TimeoutAction>;
|
|
12
|
+
}
|
|
13
|
+
export declare const DEFAULT_APPROVAL_CONFIG: ApprovalTimeoutConfig;
|
|
14
|
+
export declare const DEFAULT_LOCAL_APPROVAL_CONFIG: LocalApprovalConfig;
|
|
15
|
+
export declare const DEFAULT_ASK_CONFIG: AskConfig;
|
|
16
|
+
/**
|
|
17
|
+
* ConfigManager — Hub 本地設定持久化
|
|
18
|
+
*
|
|
19
|
+
* 負責:
|
|
20
|
+
* 1. 讀取 ~/.hopping/config.json(配對後取得的 agentId + token)
|
|
21
|
+
* 2. 配對成功後寫入設定檔(chmod 0o600)
|
|
22
|
+
* 3. 提供 token 讀取(token 優先順序由呼叫者決定:env > getToken() > 無)
|
|
23
|
+
*/
|
|
24
|
+
export declare class ConfigManager {
|
|
25
|
+
private configPath;
|
|
26
|
+
constructor(configPath?: string);
|
|
27
|
+
/**
|
|
28
|
+
* 讀取完整設定
|
|
29
|
+
* - 找不到檔案或解析失敗時回傳 null(不 throw)
|
|
30
|
+
*/
|
|
31
|
+
getConfig(): Promise<HubLocalConfig | null>;
|
|
32
|
+
/**
|
|
33
|
+
* 取得 token
|
|
34
|
+
* - 找不到設定或 token 為空時回傳 null
|
|
35
|
+
*/
|
|
36
|
+
getToken(): Promise<string | null>;
|
|
37
|
+
/**
|
|
38
|
+
* 配對成功後儲存設定
|
|
39
|
+
* - 建立 ~/.hopping/ 目錄(若不存在)
|
|
40
|
+
* - 寫入 config.json,權限設為 0o600
|
|
41
|
+
*/
|
|
42
|
+
saveAfterPairing(agentId: string, token: string, cloudUrl: string): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* 取得 toolMappings 設定(User Config Layer 1)
|
|
45
|
+
*
|
|
46
|
+
* 讀取 ~/.hopping/config.json 的 toolMappings section。
|
|
47
|
+
* 不存在或解析失敗時回傳 null(不 throw)。
|
|
48
|
+
*/
|
|
49
|
+
getToolMappings(): Promise<ToolRegistry | null>;
|
|
50
|
+
/**
|
|
51
|
+
* 取得 localApproval 設定(REQ-HUB-035)
|
|
52
|
+
*
|
|
53
|
+
* 讀取 ~/.hopping/config.json 的 localApproval section,支援 partial override。
|
|
54
|
+
* 找不到設定或解析失敗時回傳預設值(不 throw)。
|
|
55
|
+
*/
|
|
56
|
+
getLocalApprovalConfig(): Promise<LocalApprovalConfig>;
|
|
57
|
+
/**
|
|
58
|
+
* 清除本地設定(用於取消配對)
|
|
59
|
+
* - 找不到檔案時不 throw
|
|
60
|
+
*/
|
|
61
|
+
clear(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* 取得 askConfig 設定(REQ-HUB-042)
|
|
64
|
+
*
|
|
65
|
+
* 讀取 ~/.hopping/config.json 的 askConfig section,支援 partial override。
|
|
66
|
+
* 找不到設定或解析失敗時回傳預設值(timeoutEnabled: true, timeoutMs: 1hr)。
|
|
67
|
+
*/
|
|
68
|
+
getAskConfig(): Promise<AskConfig>;
|
|
69
|
+
/**
|
|
70
|
+
* 取得 Approval timeout 設定
|
|
71
|
+
*
|
|
72
|
+
* 優先序:HOPPING_APPROVAL_TIMEOUT_MS env > config.json approval section > defaults
|
|
73
|
+
*/
|
|
74
|
+
getApprovalConfig(): Promise<ApprovalTimeoutConfig>;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/config/manager.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,SAAS,EACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAM3D,eAAO,MAAM,kBAAkB,QAAsC,CAAC;AACtE,eAAO,MAAM,mBAAmB,QAA+C,CAAC;AAMhF,0EAA0E;AAC1E,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG,WAAW,GAAG,cAAc,GAAG,WAAW,CAAC;AAErF,uDAAuD;AACvD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,CAQzE;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,EAAE,MAAM,CAAC,CAAC;IACjE,SAAS,EAAE,MAAM,CAAC,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,EAAE,aAAa,CAAC,CAAC;CAC1E;AAED,eAAO,MAAM,uBAAuB,EAAE,qBAGrC,CAAC;AASF,eAAO,MAAM,6BAA6B,EAAE,mBAK3C,CAAC;AAMF,eAAO,MAAM,kBAAkB,EAAE,SAGhC,CAAC;AAMF;;;;;;;GAOG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAAS;gBAEf,UAAU,GAAE,MAA4B;IAIpD;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IASjD;;;OAGG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKxC;;;;OAIG;IACG,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBvF;;;;;OAKG;IACG,eAAe,IAAI,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAmBrD;;;;;OAKG;IACG,sBAAsB,IAAI,OAAO,CAAC,mBAAmB,CAAC;IAkC5D;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5B;;;;;OAKG;IACG,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;IA0BxC;;;;OAIG;IACG,iBAAiB,IAAI,OAAO,CAAC,qBAAqB,CAAC;CA6D1D"}
|