@lylyuanliang/agent-feedback-sentinel 0.0.0-stage → 1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 lylyuanliang
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/bin/cli.js ADDED
@@ -0,0 +1,177 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * @agent-feedback/sentinel CLI
5
+ * Silent Watcher, Pluggable Adapters, and CLI Status Feedback Utility
6
+ */
7
+
8
+ import {
9
+ startSentinel,
10
+ startMcpServer,
11
+ updateFeedbackStatus,
12
+ insertNotice
13
+ } from '../dist/index.js';
14
+
15
+ const rawArgs = process.argv.slice(2);
16
+
17
+ function printHelp() {
18
+ console.log(`
19
+ @lylyuanliang/agent-feedback-sentinel CLI - In-App Agent Feedback Bridge
20
+
21
+ 用法:
22
+ agent-feedback <command> [options]
23
+
24
+ 命令:
25
+ watch 启动静默哨兵监听队列 (默认)
26
+ mcp 启动标准 Stdio MCP 服务器 (Cursor / Antigravity / Claude)
27
+ update-status <id> <status> [reply] 更新指定反馈项的状态与回复
28
+ notice <content> 向当天分片插入一条系统通知工单
29
+
30
+ 选项:
31
+ --dir <path> 反馈数据持久化目录 (默认: .agent/feedback)
32
+ --adapter <type> 唤醒适配器: antigravity | mcp | webhook (默认: antigravity)
33
+ --debounce <seconds> 防抖聚合窗口时长秒数 (默认: 10)
34
+ --poll <ms> 轮询检测间隔毫秒数 (默认: 2000)
35
+ --webhook-cmd <command> Webhook 适配器触发的外部 Shell 命令
36
+ --webhook-url <url> Webhook 适配器触发的 HTTP POST 端点
37
+ --once 处理完第一批反馈即退出 (默认开启)
38
+ --no-once, --daemon 持续守护监听模式 (处理完一批后不退出,继续等待下一批)
39
+ -h, --help 显示帮助文档
40
+ -v, --version 显示版本号
41
+
42
+ 示例:
43
+ agent-feedback watch --debounce 10 --adapter antigravity
44
+ agent-feedback update-status 1001 completed "已完成修复并在当前分支验证通过"
45
+ agent-feedback mcp --dir .agent/feedback
46
+ `);
47
+ }
48
+
49
+ function parseCliArgs(args) {
50
+ const options = {
51
+ dir: '.agent/feedback',
52
+ adapter: 'antigravity',
53
+ debounce: 10,
54
+ poll: 2000,
55
+ webhookCmd: undefined,
56
+ webhookUrl: undefined,
57
+ once: undefined,
58
+ help: false,
59
+ version: false
60
+ };
61
+ const positional = [];
62
+
63
+ for (let i = 0; i < args.length; i++) {
64
+ const arg = args[i];
65
+ if (arg === '--help' || arg === '-h') {
66
+ options.help = true;
67
+ } else if (arg === '--version' || arg === '-v') {
68
+ options.version = true;
69
+ } else if (arg === '--no-once' || arg === '--daemon' || arg === '-d') {
70
+ options.once = false;
71
+ } else if (arg === '--once') {
72
+ options.once = true;
73
+ } else if (arg === '--dir' && i + 1 < args.length) {
74
+ options.dir = args[++i];
75
+ } else if (arg === '--adapter' && i + 1 < args.length) {
76
+ options.adapter = args[++i];
77
+ } else if (arg === '--debounce' && i + 1 < args.length) {
78
+ options.debounce = parseFloat(args[++i]) || 10;
79
+ } else if (arg === '--poll' && i + 1 < args.length) {
80
+ options.poll = parseInt(args[++i], 10) || 2000;
81
+ } else if (arg === '--webhook-cmd' && i + 1 < args.length) {
82
+ options.webhookCmd = args[++i];
83
+ } else if (arg === '--webhook-url' && i + 1 < args.length) {
84
+ options.webhookUrl = args[++i];
85
+ } else if (!arg.startsWith('-')) {
86
+ positional.push(arg);
87
+ }
88
+ }
89
+
90
+ return { options, positional };
91
+ }
92
+
93
+ async function main() {
94
+ const { options, positional } = parseCliArgs(rawArgs);
95
+
96
+ if (rawArgs.length === 0 || options.help) {
97
+ printHelp();
98
+ process.exit(0);
99
+ }
100
+
101
+ if (options.version) {
102
+ console.log('@lylyuanliang/agent-feedback-sentinel v1.0.0');
103
+ process.exit(0);
104
+ }
105
+
106
+ const command = positional[0] || 'watch';
107
+
108
+ // 1. MCP 服务器模式
109
+ if (command === 'mcp') {
110
+ await startMcpServer({ storageDir: options.dir });
111
+ return;
112
+ }
113
+
114
+ // 2. 状态写回命令: update-status <id> <status> [reply]
115
+ if (command === 'update-status') {
116
+ const id = parseInt(positional[1], 10);
117
+ const status = positional[2];
118
+ const reply = positional.slice(3).join(' ') || undefined;
119
+
120
+ if (isNaN(id) || !status) {
121
+ console.error('[!] 错误: update-status 需要指定有效的 <id> 和 <status>');
122
+ console.error(' 示例: agent-feedback update-status 1001 completed "已修复"');
123
+ process.exit(1);
124
+ }
125
+
126
+ const updated = updateFeedbackStatus(options.dir, id, status, reply);
127
+ if (!updated) {
128
+ console.error(`[!] 错误: 未在 [${options.dir}] 中找到 ID 为 ${id} 的反馈条目`);
129
+ process.exit(1);
130
+ }
131
+
132
+ console.log(`[*] ✅ 成功更新反馈 [ID: ${id}] 状态为 '${status}'`);
133
+ if (reply) {
134
+ console.log(` 回复内容: ${reply}`);
135
+ }
136
+ console.log(JSON.stringify(updated, null, 2));
137
+ process.exit(0);
138
+ }
139
+
140
+ // 3. 系统通知写入命令: notice <content>
141
+ if (command === 'notice') {
142
+ const content = positional.slice(1).join(' ');
143
+ if (!content || !content.trim()) {
144
+ console.error('[!] 错误: notice 命令需要指定通知内容');
145
+ console.error(' 示例: agent-feedback notice "AI Agent 修复通知:已重构高山拓扑视图"');
146
+ process.exit(1);
147
+ }
148
+
149
+ const item = insertNotice(options.dir, content.trim());
150
+ console.log(`[*] ✅ 成功插入系统通知工单 [ID: ${item.id}, 日期: ${item.date}]`);
151
+ console.log(JSON.stringify(item, null, 2));
152
+ process.exit(0);
153
+ }
154
+
155
+ // 4. 哨兵监听模式: watch (或直接作为缺省命令)
156
+ if (command === 'watch') {
157
+ await startSentinel({
158
+ adapter: options.adapter,
159
+ debounceSeconds: options.debounce,
160
+ pollIntervalMs: options.poll,
161
+ storageDir: options.dir,
162
+ webhookCommand: options.webhookCmd,
163
+ webhookUrl: options.webhookUrl,
164
+ once: options.once
165
+ });
166
+ return;
167
+ }
168
+
169
+ console.error(`[!] 未知命令: ${command}`);
170
+ printHelp();
171
+ process.exit(1);
172
+ }
173
+
174
+ main().catch(err => {
175
+ console.error('[!] Sentinel 发生未捕获异常:', err);
176
+ process.exit(1);
177
+ });
@@ -0,0 +1,161 @@
1
+ /**
2
+ * @agent-feedback/sentinel
3
+ * In-App Agent Feedback Bridge - Silent Sentinel & Wakeup CLI
4
+ */
5
+ import type { InAppFeedback, FeedbackStatus, SecurityTriageResult } from '@lylyuanliang/agent-feedback-core';
6
+ export type { InAppFeedback, FeedbackStatus, SecurityTriageResult };
7
+ export type WatcherAdapter = 'antigravity' | 'mcp' | 'webhook';
8
+ export interface WatcherOptions {
9
+ /** 本地反馈存储目录 (默认: .agent/feedback) */
10
+ storageDir?: string;
11
+ /** 队列文件绝对或相对路径 (可选,覆盖 storageDir/feedback_queue.json) */
12
+ queueFile?: string;
13
+ /** 上次处理时间戳/ID文件路径 (可选,覆盖 storageDir/last_processed_id.txt) */
14
+ lastProcessedFile?: string;
15
+ /** 防抖收集窗口时长 (秒,默认: 10) */
16
+ debounceSeconds?: number;
17
+ /** 防抖收集窗口时长 (毫秒,用于测试快速运行,优先级高于 debounceSeconds) */
18
+ debounceMs?: number;
19
+ /** 静默轮询间隔 (毫秒,默认: 2000) */
20
+ pollIntervalMs?: number;
21
+ /** 唤醒适配器类型 (默认: antigravity) */
22
+ adapter?: WatcherAdapter;
23
+ /** Webhook 适配器触发的外部 Shell 脚本/命令 */
24
+ webhookCommand?: string;
25
+ /** Webhook 适配器触发的 HTTP POST 端点 */
26
+ webhookUrl?: string;
27
+ /** 唤醒回调钩子 (常用于测试拦截或自定义事件通知) */
28
+ onWakeup?: (batch: InAppFeedback[], adapter: string) => void | Promise<void>;
29
+ /** 防抖收集期间捕获到新反馈时的进度回调 */
30
+ onDebounceProgress?: (count: number) => void;
31
+ /** 唤醒后是否调用 process.exit(0) (默认 true;当提供 onWakeup 时默认 false) */
32
+ exitOnWakeup?: boolean;
33
+ /** 是否仅捕获处理单次批次即退出 (当 adapter 为 antigravity 时默认 true;当 adapter 为 webhook 或 mcp 时默认 false 持续常驻守护) */
34
+ once?: boolean;
35
+ /** 外部中止信号 (用于优雅终止轮询) */
36
+ signal?: AbortSignal;
37
+ /** Antigravity 目标会话 ID (用于通过 agentapi send-message 主动唤醒) */
38
+ conversationId?: string;
39
+ /** 是否静默控制台输出 (测试时开启可保持输出整洁) */
40
+ silent?: boolean;
41
+ }
42
+ /**
43
+ * 获取本地 YYYY-MM-DD 日期字符串
44
+ */
45
+ export declare function getLocalDateString(d?: Date | number | string): string;
46
+ /**
47
+ * 读取上次已处理的最大反馈 ID
48
+ */
49
+ export declare function getLastProcessedId(lastProcessedFile: string): number;
50
+ /**
51
+ * 记录本次已处理的最大反馈 ID
52
+ */
53
+ export declare function setLastProcessedId(lastProcessedFile: string, id: number): void;
54
+ /**
55
+ * 原子化写入 JSON 数据到文件,防并发读脏
56
+ */
57
+ export declare function atomicWriteJson(filePath: string, data: any): void;
58
+ /**
59
+ * 插入系统通知工单到当天分片
60
+ */
61
+ export declare function insertNotice(storageDirOrFile: string, content: string, extra?: Partial<InAppFeedback>): InAppFeedback;
62
+ /**
63
+ * 从存储目录或队列文件中聚合获取新待处理反馈
64
+ */
65
+ export declare function collectPendingItemsFromStorage(storageDir: string, queueFile: string, lastProcessedId: number): InAppFeedback[];
66
+ /**
67
+ * 批量处理并分诊端侧反馈
68
+ */
69
+ export declare function processQueueBatch(queueFileOrDir: string, items: InAppFeedback[], options?: WatcherOptions): InAppFeedback[];
70
+ /**
71
+ * 手动更新单个反馈状态 (支持跨分片检索、CLI 和 MCP 回写)
72
+ */
73
+ export declare function updateFeedbackStatus(queueFileOrDir: string, id: number, status: FeedbackStatus, reply?: string): InAppFeedback | null;
74
+ /**
75
+ * 获取待处理反馈列表
76
+ */
77
+ export declare function getPendingFeedback(queueFileOrDir: string, statusFilter?: FeedbackStatus | 'all'): InAppFeedback[];
78
+ /**
79
+ * MCP 协议工具定义规范
80
+ */
81
+ export declare const mcpTools: ({
82
+ name: string;
83
+ description: string;
84
+ inputSchema: {
85
+ type: string;
86
+ properties: {
87
+ status: {
88
+ type: string;
89
+ description: string;
90
+ enum: string[];
91
+ };
92
+ storageDir: {
93
+ type: string;
94
+ description: string;
95
+ };
96
+ id?: undefined;
97
+ reply?: undefined;
98
+ };
99
+ required?: undefined;
100
+ };
101
+ } | {
102
+ name: string;
103
+ description: string;
104
+ inputSchema: {
105
+ type: string;
106
+ properties: {
107
+ id: {
108
+ type: string;
109
+ description: string;
110
+ };
111
+ status: {
112
+ type: string;
113
+ description: string;
114
+ enum: string[];
115
+ };
116
+ reply: {
117
+ type: string;
118
+ description: string;
119
+ };
120
+ storageDir: {
121
+ type: string;
122
+ description: string;
123
+ };
124
+ };
125
+ required: string[];
126
+ };
127
+ })[];
128
+ /**
129
+ * 执行 MCP 工具调用
130
+ */
131
+ export declare function executeMcpTool(name: string, args?: Record<string, any>, defaultStorageDir?: string): Promise<{
132
+ content: Array<{
133
+ type: string;
134
+ text: string;
135
+ }>;
136
+ isError?: boolean;
137
+ }>;
138
+ /**
139
+ * 启动标准 Stdio MCP Server 循环
140
+ */
141
+ export declare function startMcpServer(options?: WatcherOptions): Promise<void>;
142
+ /**
143
+ * 解析本机可用的 agentapi 可执行程序路径
144
+ */
145
+ export declare function getAgentApiExecutable(): string;
146
+ /**
147
+ * 自动检测并推断当前项目工作区对应的活跃 Antigravity 会话 ID
148
+ * 1. 优先读取系统环境变量 ANTIGRAVITY_CONVERSATION_ID (智能体内部子进程环境)
149
+ * 2. 外部终端自适应:读取 ~/.gemini/antigravity/conversation_summaries.db (通过 Node 原生 node:sqlite 零依赖检索)
150
+ */
151
+ export declare function detectAntigravityConversation(cwd?: string): string | null;
152
+ /**
153
+ * 静默哨兵核心监听器
154
+ * 1. 适配按天分片存储目录及队列文件的静默轮询
155
+ * 2. 捕获第 1 条新 pending 反馈后,自动开启防抖聚合窗口 (默认 10s,支持毫秒配置)
156
+ * 3. 聚合完成后执行启发式安全分诊
157
+ * 4. 触发对应适配器唤醒 (antigravity 正常 exit(0),mcp / webhook 触发钩子)
158
+ */
159
+ export declare function startSentinel(options?: WatcherOptions): Promise<void>;
160
+ export default startSentinel;
161
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,782 @@
1
+ /**
2
+ * @agent-feedback/sentinel
3
+ * In-App Agent Feedback Bridge - Silent Sentinel & Wakeup CLI
4
+ */
5
+ import fs from 'node:fs';
6
+ import os from 'node:os';
7
+ import path from 'node:path';
8
+ import { exec } from 'node:child_process';
9
+ import { promisify } from 'node:util';
10
+ import { sanitizeFeedbackContent } from '@lylyuanliang/agent-feedback-core';
11
+ const execAsync = promisify(exec);
12
+ /**
13
+ * 获取本地 YYYY-MM-DD 日期字符串
14
+ */
15
+ export function getLocalDateString(d = new Date()) {
16
+ const dateObj = typeof d === 'object' && d instanceof Date ? d : new Date(d);
17
+ if (isNaN(dateObj.getTime())) {
18
+ const fallback = new Date();
19
+ return `${fallback.getFullYear()}-${String(fallback.getMonth() + 1).padStart(2, '0')}-${String(fallback.getDate()).padStart(2, '0')}`;
20
+ }
21
+ const year = dateObj.getFullYear();
22
+ const month = String(dateObj.getMonth() + 1).padStart(2, '0');
23
+ const day = String(dateObj.getDate()).padStart(2, '0');
24
+ return `${year}-${month}-${day}`;
25
+ }
26
+ /**
27
+ * 读取上次已处理的最大反馈 ID
28
+ */
29
+ export function getLastProcessedId(lastProcessedFile) {
30
+ if (!fs.existsSync(lastProcessedFile))
31
+ return 0;
32
+ try {
33
+ const content = fs.readFileSync(lastProcessedFile, 'utf-8').trim();
34
+ const id = parseInt(content, 10);
35
+ return isNaN(id) ? 0 : id;
36
+ }
37
+ catch {
38
+ return 0;
39
+ }
40
+ }
41
+ /**
42
+ * 记录本次已处理的最大反馈 ID
43
+ */
44
+ export function setLastProcessedId(lastProcessedFile, id) {
45
+ const dir = path.dirname(lastProcessedFile);
46
+ if (!fs.existsSync(dir)) {
47
+ fs.mkdirSync(dir, { recursive: true });
48
+ }
49
+ fs.writeFileSync(lastProcessedFile, String(id), 'utf-8');
50
+ }
51
+ /**
52
+ * 原子化写入 JSON 数据到文件,防并发读脏
53
+ */
54
+ export function atomicWriteJson(filePath, data) {
55
+ const dir = path.dirname(filePath);
56
+ if (!fs.existsSync(dir)) {
57
+ fs.mkdirSync(dir, { recursive: true });
58
+ }
59
+ const content = JSON.stringify(data, null, 2);
60
+ const tmpFile = `${filePath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2, 8)}`;
61
+ try {
62
+ fs.writeFileSync(tmpFile, content, 'utf-8');
63
+ fs.renameSync(tmpFile, filePath);
64
+ }
65
+ catch {
66
+ // Windows 平台文件锁或跨卷降级直接覆写
67
+ fs.writeFileSync(filePath, content, 'utf-8');
68
+ try {
69
+ if (fs.existsSync(tmpFile))
70
+ fs.unlinkSync(tmpFile);
71
+ }
72
+ catch { }
73
+ }
74
+ }
75
+ /**
76
+ * 插入系统通知工单到当天分片
77
+ */
78
+ export function insertNotice(storageDirOrFile, content, extra = {}) {
79
+ const isFile = fs.existsSync(storageDirOrFile) && fs.statSync(storageDirOrFile).isFile();
80
+ const storageDir = isFile ? path.dirname(storageDirOrFile) : storageDirOrFile;
81
+ const queueFile = isFile ? storageDirOrFile : path.resolve(storageDir, 'feedback_queue.json');
82
+ if (!fs.existsSync(storageDir)) {
83
+ fs.mkdirSync(storageDir, { recursive: true });
84
+ }
85
+ const now = Date.now();
86
+ const date = getLocalDateString(extra.timestamp || now);
87
+ const noticeItem = {
88
+ id: extra.id || now,
89
+ type: 'agent_notice',
90
+ status: extra.status || 'completed',
91
+ content,
92
+ receivedAt: extra.receivedAt || new Date(now).toISOString(),
93
+ timestamp: extra.timestamp || now,
94
+ date,
95
+ reply: extra.reply || '系统主动推送的 Agent 通知',
96
+ telemetry: extra.telemetry || {
97
+ route: 'cli',
98
+ viewport: { width: 0, height: 0, dpr: 1 },
99
+ userAgent: '@lylyuanliang/agent-feedback-sentinel-cli',
100
+ platform: 'desktop'
101
+ }
102
+ };
103
+ // 1. 写入当天分片
104
+ const shardFile = path.resolve(storageDir, `feedback_${date}.json`);
105
+ let shardItems = [];
106
+ if (fs.existsSync(shardFile)) {
107
+ try {
108
+ const parsed = JSON.parse(fs.readFileSync(shardFile, 'utf-8'));
109
+ if (Array.isArray(parsed))
110
+ shardItems = parsed;
111
+ }
112
+ catch { }
113
+ }
114
+ shardItems.unshift(noticeItem);
115
+ atomicWriteJson(shardFile, shardItems);
116
+ // 2. 更新索引
117
+ const indexFile = path.resolve(storageDir, 'feedback_index.json');
118
+ let dates = [date];
119
+ let totalCount = shardItems.length;
120
+ if (fs.existsSync(indexFile)) {
121
+ try {
122
+ const idxData = JSON.parse(fs.readFileSync(indexFile, 'utf-8'));
123
+ if (Array.isArray(idxData.dates)) {
124
+ dates = Array.from(new Set([date, ...idxData.dates]));
125
+ dates.sort((a, b) => b.localeCompare(a));
126
+ totalCount = (idxData.totalCount || 0) + 1;
127
+ }
128
+ }
129
+ catch { }
130
+ }
131
+ atomicWriteJson(indexFile, {
132
+ dates,
133
+ totalCount,
134
+ updatedAt: new Date().toISOString()
135
+ });
136
+ // 3. 同步写回 feedback_queue.json
137
+ let queueItems = [];
138
+ if (fs.existsSync(queueFile)) {
139
+ try {
140
+ const parsed = JSON.parse(fs.readFileSync(queueFile, 'utf-8'));
141
+ if (Array.isArray(parsed))
142
+ queueItems = parsed;
143
+ }
144
+ catch { }
145
+ }
146
+ queueItems.unshift(noticeItem);
147
+ atomicWriteJson(queueFile, queueItems);
148
+ return noticeItem;
149
+ }
150
+ /**
151
+ * 从存储目录或队列文件中聚合获取新待处理反馈
152
+ */
153
+ export function collectPendingItemsFromStorage(storageDir, queueFile, lastProcessedId) {
154
+ const map = new Map();
155
+ // 1. 优先扫描当天及最近的分片文件
156
+ const today = getLocalDateString();
157
+ const todayShard = path.resolve(storageDir, `feedback_${today}.json`);
158
+ if (fs.existsSync(todayShard)) {
159
+ try {
160
+ const items = JSON.parse(fs.readFileSync(todayShard, 'utf-8'));
161
+ if (Array.isArray(items)) {
162
+ for (const item of items) {
163
+ if (item.id > lastProcessedId && item.status === 'pending') {
164
+ map.set(item.id, item);
165
+ }
166
+ }
167
+ }
168
+ }
169
+ catch { }
170
+ }
171
+ // 扫描 index 中的近期分片
172
+ const indexFile = path.resolve(storageDir, 'feedback_index.json');
173
+ if (fs.existsSync(indexFile)) {
174
+ try {
175
+ const index = JSON.parse(fs.readFileSync(indexFile, 'utf-8'));
176
+ if (Array.isArray(index?.dates)) {
177
+ for (const date of index.dates.slice(0, 3)) {
178
+ const shardPath = path.resolve(storageDir, `feedback_${date}.json`);
179
+ if (fs.existsSync(shardPath) && shardPath !== todayShard) {
180
+ const items = JSON.parse(fs.readFileSync(shardPath, 'utf-8'));
181
+ if (Array.isArray(items)) {
182
+ for (const item of items) {
183
+ if (item.id > lastProcessedId && item.status === 'pending') {
184
+ map.set(item.id, item);
185
+ }
186
+ }
187
+ }
188
+ }
189
+ }
190
+ }
191
+ }
192
+ catch { }
193
+ }
194
+ // 2. 检查 feedback_queue.json
195
+ if (fs.existsSync(queueFile)) {
196
+ try {
197
+ const raw = fs.readFileSync(queueFile, 'utf-8');
198
+ const queue = JSON.parse(raw);
199
+ if (Array.isArray(queue)) {
200
+ for (const item of queue) {
201
+ if (item.id > lastProcessedId && item.status === 'pending') {
202
+ map.set(item.id, item);
203
+ }
204
+ }
205
+ }
206
+ }
207
+ catch { }
208
+ }
209
+ return Array.from(map.values()).sort((a, b) => a.id - b.id);
210
+ }
211
+ /**
212
+ * 批量处理并分诊端侧反馈
213
+ */
214
+ export function processQueueBatch(queueFileOrDir, items, options = {}) {
215
+ const isFile = fs.existsSync(queueFileOrDir) && fs.statSync(queueFileOrDir).isFile();
216
+ const storageDir = isFile ? path.dirname(queueFileOrDir) : queueFileOrDir;
217
+ const queueFile = isFile ? queueFileOrDir : path.resolve(storageDir, 'feedback_queue.json');
218
+ const lastProcessedFile = options.lastProcessedFile ||
219
+ path.resolve(storageDir, 'last_processed_id.txt');
220
+ let curQueue = [];
221
+ if (fs.existsSync(queueFile)) {
222
+ try {
223
+ const raw = fs.readFileSync(queueFile, 'utf-8');
224
+ const parsed = JSON.parse(raw);
225
+ if (Array.isArray(parsed)) {
226
+ curQueue = parsed;
227
+ }
228
+ }
229
+ catch {
230
+ curQueue = [];
231
+ }
232
+ }
233
+ let maxId = getLastProcessedId(lastProcessedFile);
234
+ const nowIso = new Date().toISOString();
235
+ const processedItems = [];
236
+ for (const item of items) {
237
+ maxId = Math.max(maxId, item.id);
238
+ const triage = sanitizeFeedbackContent(item.content);
239
+ if (!triage.isSafe) {
240
+ item.status = 'rejected';
241
+ item.reply = `系统安全防线已拦截:${triage.reason}`;
242
+ }
243
+ else {
244
+ item.status = 'processing';
245
+ item.reply = `AI 智能体已被自动唤醒,已聚合批次 (共 ${items.length} 条),正在分析排查...`;
246
+ }
247
+ item.updatedAt = nowIso;
248
+ processedItems.push(item);
249
+ // 同步写入对应日期的分片
250
+ const itemDate = item.date || getLocalDateString(item.receivedAt || item.timestamp);
251
+ item.date = itemDate;
252
+ const shardFile = path.resolve(storageDir, `feedback_${itemDate}.json`);
253
+ if (fs.existsSync(shardFile)) {
254
+ try {
255
+ const shardItems = JSON.parse(fs.readFileSync(shardFile, 'utf-8'));
256
+ const idx = shardItems.findIndex(i => i.id === item.id);
257
+ if (idx >= 0) {
258
+ shardItems[idx] = { ...shardItems[idx], ...item };
259
+ }
260
+ else {
261
+ shardItems.unshift(item);
262
+ }
263
+ atomicWriteJson(shardFile, shardItems);
264
+ }
265
+ catch { }
266
+ }
267
+ // 同步更新至全局队列中的对应条目
268
+ const existingIndex = curQueue.findIndex(q => q.id === item.id);
269
+ if (existingIndex >= 0) {
270
+ curQueue[existingIndex] = { ...curQueue[existingIndex], ...item };
271
+ }
272
+ else {
273
+ curQueue.unshift(item);
274
+ }
275
+ }
276
+ // 原子化写回队列
277
+ if (curQueue.length > 0 || fs.existsSync(queueFile)) {
278
+ atomicWriteJson(queueFile, curQueue);
279
+ }
280
+ // 更新已处理最大 ID 游标
281
+ setLastProcessedId(lastProcessedFile, maxId);
282
+ return processedItems;
283
+ }
284
+ /**
285
+ * 手动更新单个反馈状态 (支持跨分片检索、CLI 和 MCP 回写)
286
+ */
287
+ export function updateFeedbackStatus(queueFileOrDir, id, status, reply) {
288
+ const isFile = fs.existsSync(queueFileOrDir) && fs.statSync(queueFileOrDir).isFile();
289
+ const storageDir = isFile ? path.dirname(queueFileOrDir) : queueFileOrDir;
290
+ const queueFile = isFile ? queueFileOrDir : path.resolve(storageDir, 'feedback_queue.json');
291
+ const numId = Number(id);
292
+ let updatedItem = null;
293
+ // 1. 跨分片检索并更新
294
+ if (fs.existsSync(storageDir)) {
295
+ try {
296
+ const files = fs.readdirSync(storageDir);
297
+ const shardFiles = files.filter(f => f.startsWith('feedback_') && f.endsWith('.json') && f !== 'feedback_index.json' && f !== 'feedback_queue.json');
298
+ for (const sf of shardFiles) {
299
+ const shardPath = path.resolve(storageDir, sf);
300
+ try {
301
+ const raw = fs.readFileSync(shardPath, 'utf-8');
302
+ const shardList = JSON.parse(raw);
303
+ const item = shardList.find(i => i.id === numId);
304
+ if (item) {
305
+ item.status = status;
306
+ if (reply !== undefined)
307
+ item.reply = reply;
308
+ item.updatedAt = new Date().toISOString();
309
+ atomicWriteJson(shardPath, shardList);
310
+ updatedItem = item;
311
+ break;
312
+ }
313
+ }
314
+ catch { }
315
+ }
316
+ }
317
+ catch { }
318
+ }
319
+ // 2. 同步更新 feedback_queue.json
320
+ if (fs.existsSync(queueFile)) {
321
+ try {
322
+ const raw = fs.readFileSync(queueFile, 'utf-8');
323
+ const queue = JSON.parse(raw);
324
+ const item = queue.find(i => i.id === numId);
325
+ if (item) {
326
+ item.status = status;
327
+ if (reply !== undefined)
328
+ item.reply = reply;
329
+ item.updatedAt = new Date().toISOString();
330
+ atomicWriteJson(queueFile, queue);
331
+ if (!updatedItem)
332
+ updatedItem = item;
333
+ }
334
+ }
335
+ catch { }
336
+ }
337
+ return updatedItem;
338
+ }
339
+ /**
340
+ * 获取待处理反馈列表
341
+ */
342
+ export function getPendingFeedback(queueFileOrDir, statusFilter) {
343
+ const isFile = fs.existsSync(queueFileOrDir) && fs.statSync(queueFileOrDir).isFile();
344
+ const storageDir = isFile ? path.dirname(queueFileOrDir) : queueFileOrDir;
345
+ const queueFile = isFile ? queueFileOrDir : path.resolve(storageDir, 'feedback_queue.json');
346
+ const map = new Map();
347
+ // 优先从分片读取
348
+ if (fs.existsSync(storageDir)) {
349
+ try {
350
+ const files = fs.readdirSync(storageDir);
351
+ const shardFiles = files.filter(f => f.startsWith('feedback_') && f.endsWith('.json') && f !== 'feedback_index.json' && f !== 'feedback_queue.json');
352
+ for (const sf of shardFiles) {
353
+ try {
354
+ const list = JSON.parse(fs.readFileSync(path.resolve(storageDir, sf), 'utf-8'));
355
+ if (Array.isArray(list)) {
356
+ for (const item of list) {
357
+ map.set(item.id, item);
358
+ }
359
+ }
360
+ }
361
+ catch { }
362
+ }
363
+ }
364
+ catch { }
365
+ }
366
+ // 合并 feedback_queue.json
367
+ if (fs.existsSync(queueFile)) {
368
+ try {
369
+ const raw = fs.readFileSync(queueFile, 'utf-8');
370
+ const queue = JSON.parse(raw);
371
+ if (Array.isArray(queue)) {
372
+ for (const item of queue) {
373
+ if (!map.has(item.id)) {
374
+ map.set(item.id, item);
375
+ }
376
+ }
377
+ }
378
+ }
379
+ catch { }
380
+ }
381
+ const allItems = Array.from(map.values()).sort((a, b) => b.id - a.id);
382
+ if (!statusFilter || statusFilter === 'pending') {
383
+ return allItems.filter(i => i.status === 'pending');
384
+ }
385
+ if (statusFilter === 'all') {
386
+ return allItems;
387
+ }
388
+ return allItems.filter(i => i.status === statusFilter);
389
+ }
390
+ /**
391
+ * MCP 协议工具定义规范
392
+ */
393
+ export const mcpTools = [
394
+ {
395
+ name: 'get_pending_feedback',
396
+ description: 'Retrieve pending or processing in-app feedback submitted from mobile or web devices',
397
+ inputSchema: {
398
+ type: 'object',
399
+ properties: {
400
+ status: {
401
+ type: 'string',
402
+ description: 'Filter status (default: pending). Allowed values: pending, processing, all, completed, rejected',
403
+ enum: ['pending', 'processing', 'all', 'completed', 'rejected']
404
+ },
405
+ storageDir: {
406
+ type: 'string',
407
+ description: 'Optional storage directory (default: .agent/feedback)'
408
+ }
409
+ }
410
+ }
411
+ },
412
+ {
413
+ name: 'update_feedback_status',
414
+ description: 'Update the processing status and reply message for a feedback item after diagnosis or fix',
415
+ inputSchema: {
416
+ type: 'object',
417
+ properties: {
418
+ id: {
419
+ type: 'number',
420
+ description: 'Unique ID of the feedback item to update'
421
+ },
422
+ status: {
423
+ type: 'string',
424
+ description: 'Target status for the feedback',
425
+ enum: ['processing', 'completed', 'rejected', 'ignored']
426
+ },
427
+ reply: {
428
+ type: 'string',
429
+ description: 'Detailed explanation or fix message presented to the mobile user in In-App history'
430
+ },
431
+ storageDir: {
432
+ type: 'string',
433
+ description: 'Optional storage directory (default: .agent/feedback)'
434
+ }
435
+ },
436
+ required: ['id', 'status']
437
+ }
438
+ }
439
+ ];
440
+ /**
441
+ * 执行 MCP 工具调用
442
+ */
443
+ export async function executeMcpTool(name, args = {}, defaultStorageDir = '.agent/feedback') {
444
+ const dir = args.storageDir || defaultStorageDir;
445
+ if (name === 'get_pending_feedback') {
446
+ const items = getPendingFeedback(dir, args.status || 'pending');
447
+ return {
448
+ content: [
449
+ {
450
+ type: 'text',
451
+ text: JSON.stringify({ count: items.length, items }, null, 2)
452
+ }
453
+ ]
454
+ };
455
+ }
456
+ if (name === 'update_feedback_status') {
457
+ const updated = updateFeedbackStatus(dir, args.id, args.status, args.reply);
458
+ if (!updated) {
459
+ return {
460
+ isError: true,
461
+ content: [
462
+ {
463
+ type: 'text',
464
+ text: JSON.stringify({ error: `Feedback item with id ${args.id} not found.` })
465
+ }
466
+ ]
467
+ };
468
+ }
469
+ return {
470
+ content: [
471
+ {
472
+ type: 'text',
473
+ text: JSON.stringify({ success: true, item: updated }, null, 2)
474
+ }
475
+ ]
476
+ };
477
+ }
478
+ return {
479
+ isError: true,
480
+ content: [
481
+ {
482
+ type: 'text',
483
+ text: JSON.stringify({ error: `Unknown tool: ${name}` })
484
+ }
485
+ ]
486
+ };
487
+ }
488
+ /**
489
+ * 启动标准 Stdio MCP Server 循环
490
+ */
491
+ export async function startMcpServer(options = {}) {
492
+ const storageDir = path.resolve(process.cwd(), options.storageDir || '.agent/feedback');
493
+ const readline = await import('node:readline');
494
+ const rl = readline.createInterface({
495
+ input: process.stdin,
496
+ output: process.stdout,
497
+ terminal: false
498
+ });
499
+ const sendResponse = (id, result, error) => {
500
+ const res = { jsonrpc: '2.0', id };
501
+ if (error) {
502
+ res.error = error;
503
+ }
504
+ else {
505
+ res.result = result;
506
+ }
507
+ process.stdout.write(JSON.stringify(res) + '\n');
508
+ };
509
+ rl.on('line', async (line) => {
510
+ const trimmed = line.trim();
511
+ if (!trimmed)
512
+ return;
513
+ try {
514
+ const msg = JSON.parse(trimmed);
515
+ const { id, method, params } = msg;
516
+ if (method === 'initialize') {
517
+ sendResponse(id, {
518
+ protocolVersion: '2024-11-05',
519
+ capabilities: { tools: {} },
520
+ serverInfo: {
521
+ name: '@lylyuanliang/agent-feedback-sentinel',
522
+ version: '1.0.0'
523
+ }
524
+ });
525
+ return;
526
+ }
527
+ if (method === 'notifications/initialized') {
528
+ return;
529
+ }
530
+ if (method === 'ping') {
531
+ sendResponse(id, {});
532
+ return;
533
+ }
534
+ if (method === 'tools/list') {
535
+ sendResponse(id, { tools: mcpTools });
536
+ return;
537
+ }
538
+ if (method === 'tools/call') {
539
+ const toolName = params?.name;
540
+ const toolArgs = params?.arguments || {};
541
+ const outcome = await executeMcpTool(toolName, toolArgs, storageDir);
542
+ sendResponse(id, outcome);
543
+ return;
544
+ }
545
+ // 未知方法响应方法未找到错误
546
+ sendResponse(id, undefined, { code: -32601, message: `Method not found: ${method}` });
547
+ }
548
+ catch (err) {
549
+ sendResponse(null, undefined, { code: -32700, message: err?.message || 'Parse error' });
550
+ }
551
+ });
552
+ }
553
+ /**
554
+ * 解析本机可用的 agentapi 可执行程序路径
555
+ */
556
+ export function getAgentApiExecutable() {
557
+ const home = os.homedir();
558
+ const winBat = path.join(home, '.gemini/antigravity/bin/agentapi.bat');
559
+ if (process.platform === 'win32' && fs.existsSync(winBat)) {
560
+ return `"${winBat}"`;
561
+ }
562
+ const nixBin = path.join(home, '.gemini/antigravity/bin/agentapi');
563
+ if (fs.existsSync(nixBin)) {
564
+ return `"${nixBin}"`;
565
+ }
566
+ return 'agentapi';
567
+ }
568
+ /**
569
+ * 自动检测并推断当前项目工作区对应的活跃 Antigravity 会话 ID
570
+ * 1. 优先读取系统环境变量 ANTIGRAVITY_CONVERSATION_ID (智能体内部子进程环境)
571
+ * 2. 外部终端自适应:读取 ~/.gemini/antigravity/conversation_summaries.db (通过 Node 原生 node:sqlite 零依赖检索)
572
+ */
573
+ export function detectAntigravityConversation(cwd = process.cwd()) {
574
+ if (process.env.ANTIGRAVITY_CONVERSATION_ID) {
575
+ return process.env.ANTIGRAVITY_CONVERSATION_ID;
576
+ }
577
+ try {
578
+ const home = os.homedir();
579
+ const dbPath = path.join(home, '.gemini/antigravity/conversation_summaries.db');
580
+ if (!fs.existsSync(dbPath))
581
+ return null;
582
+ // 动态探测原生 node:sqlite (Node 22.5+ 原生支持)
583
+ // @ts-ignore
584
+ const { DatabaseSync } = require('node:sqlite');
585
+ if (!DatabaseSync)
586
+ return null;
587
+ const db = new DatabaseSync(dbPath, { readOnly: true });
588
+ const normCwd = path.resolve(cwd).replace(/\\/g, '/').toLowerCase();
589
+ const stmt = db.prepare(`
590
+ SELECT conversation_id, workspace_uris, last_modified_time
591
+ FROM conversation_summaries
592
+ WHERE killed = 0
593
+ ORDER BY last_modified_time DESC
594
+ LIMIT 20
595
+ `);
596
+ const rows = stmt.all();
597
+ db.close();
598
+ for (const row of rows) {
599
+ if (row.workspace_uris) {
600
+ const decodedUris = decodeURIComponent(row.workspace_uris).replace(/\\/g, '/').toLowerCase();
601
+ if (decodedUris.includes(normCwd)) {
602
+ return row.conversation_id;
603
+ }
604
+ }
605
+ }
606
+ }
607
+ catch {
608
+ // 降级容错
609
+ }
610
+ return null;
611
+ }
612
+ /**
613
+ * 静默哨兵核心监听器
614
+ * 1. 适配按天分片存储目录及队列文件的静默轮询
615
+ * 2. 捕获第 1 条新 pending 反馈后,自动开启防抖聚合窗口 (默认 10s,支持毫秒配置)
616
+ * 3. 聚合完成后执行启发式安全分诊
617
+ * 4. 触发对应适配器唤醒 (antigravity 正常 exit(0),mcp / webhook 触发钩子)
618
+ */
619
+ export async function startSentinel(options = {}) {
620
+ const debounceMs = options.debounceMs ?? ((options.debounceSeconds ?? 10) * 1000);
621
+ const pollIntervalMs = options.pollIntervalMs ?? 2000;
622
+ const storageDir = path.resolve(process.cwd(), options.storageDir || '.agent/feedback');
623
+ const queueFile = options.queueFile || path.resolve(storageDir, 'feedback_queue.json');
624
+ const lastProcessedFile = options.lastProcessedFile || path.resolve(storageDir, 'last_processed_id.txt');
625
+ const detectedConvId = options.conversationId || detectAntigravityConversation(storageDir || process.cwd());
626
+ const adapter = options.adapter || (detectedConvId ? 'antigravity' : 'webhook');
627
+ const convId = detectedConvId;
628
+ const isOnce = options.once !== false;
629
+ const log = options.silent
630
+ ? () => { }
631
+ : (...args) => console.log(...args);
632
+ const warn = options.silent
633
+ ? () => { }
634
+ : (...args) => console.warn(...args);
635
+ // 确保存储目录就绪
636
+ if (!fs.existsSync(storageDir)) {
637
+ fs.mkdirSync(storageDir, { recursive: true });
638
+ }
639
+ let lastProcessedId = getLastProcessedId(lastProcessedFile);
640
+ const convInfo = adapter === 'antigravity' && convId ? ` (会话: ${convId.slice(0, 8)}...)` : '';
641
+ log(`[*] Agent Feedback 哨兵已启动 (适配器: ${adapter}${convInfo})...`);
642
+ log(`[*] 静默守候中 (0% CPU, 0 Token,捕获反馈后将启动 ${debounceMs / 1000}s 防抖聚合)...`);
643
+ const stepInterval = Math.min(1500, Math.max(10, Math.floor(debounceMs / 5)));
644
+ return new Promise((resolve, reject) => {
645
+ let isRunning = true;
646
+ let timer = null;
647
+ const cleanup = () => {
648
+ isRunning = false;
649
+ if (timer) {
650
+ clearTimeout(timer);
651
+ timer = null;
652
+ }
653
+ };
654
+ if (options.signal) {
655
+ options.signal.addEventListener('abort', () => {
656
+ cleanup();
657
+ resolve();
658
+ });
659
+ }
660
+ const checkLoop = async () => {
661
+ if (!isRunning || options.signal?.aborted) {
662
+ resolve();
663
+ return;
664
+ }
665
+ try {
666
+ const newItems = collectPendingItemsFromStorage(storageDir, queueFile, lastProcessedId);
667
+ if (newItems.length > 0) {
668
+ log(`\n[*] 📥 捕获到新反馈 (初始 ${newItems.length} 条),启动 ${debounceMs / 1000} 秒防抖收集窗口...`);
669
+ const startTime = Date.now();
670
+ let aggregatedItems = [...newItems];
671
+ while (Date.now() - startTime < debounceMs) {
672
+ if (!isRunning || options.signal?.aborted)
673
+ break;
674
+ await new Promise(r => setTimeout(r, stepInterval));
675
+ try {
676
+ const curNew = collectPendingItemsFromStorage(storageDir, queueFile, lastProcessedId);
677
+ if (curNew.length > aggregatedItems.length) {
678
+ log(`[*] ➕ 窗口内捕获追加提交,当前聚合批次数量: ${curNew.length} 条...`);
679
+ aggregatedItems = curNew;
680
+ options.onDebounceProgress?.(curNew.length);
681
+ }
682
+ }
683
+ catch {
684
+ // 忽略窗口内的读锁瞬态
685
+ }
686
+ }
687
+ log(`[*] ✅ 防抖收集完毕,共聚合 ${aggregatedItems.length} 条端侧反馈!`);
688
+ // 执行安全分诊与状态持久化
689
+ const target = fs.existsSync(queueFile) ? queueFile : storageDir;
690
+ const processedBatch = processQueueBatch(target, aggregatedItems, options);
691
+ lastProcessedId = getLastProcessedId(lastProcessedFile);
692
+ // 适配器调度分发
693
+ if (adapter === 'webhook') {
694
+ let webhookHandled = false;
695
+ if (options.webhookCommand) {
696
+ webhookHandled = true;
697
+ try {
698
+ await execAsync(options.webhookCommand, {
699
+ env: {
700
+ ...process.env,
701
+ FEEDBACK_COUNT: String(processedBatch.length),
702
+ FEEDBACK_IDS: processedBatch.map(i => i.id).join(',')
703
+ }
704
+ });
705
+ }
706
+ catch (cmdErr) {
707
+ warn(`[!] Webhook 命令执行异常: ${cmdErr?.message}`);
708
+ }
709
+ }
710
+ if (options.webhookUrl) {
711
+ webhookHandled = true;
712
+ try {
713
+ await fetch(options.webhookUrl, {
714
+ method: 'POST',
715
+ headers: { 'Content-Type': 'application/json' },
716
+ body: JSON.stringify({ batch: processedBatch })
717
+ });
718
+ }
719
+ catch (netErr) {
720
+ warn(`[!] Webhook 请求发送异常: ${netErr?.message}`);
721
+ }
722
+ }
723
+ if (!webhookHandled && !options.onWakeup) {
724
+ log('[*] 💡 [Webhook 适配器提示] 批次已安全分诊并持久化。因未配置 webhookCommand 或 webhookUrl,未触发外部通知。');
725
+ }
726
+ }
727
+ if (typeof options.onWakeup === 'function') {
728
+ await options.onWakeup(processedBatch, adapter);
729
+ }
730
+ if (adapter === 'antigravity') {
731
+ log('[*] 🔔 触发 Antigravity 响应式唤醒机制...');
732
+ const activeConvId = convId || options.conversationId || process.env.ANTIGRAVITY_CONVERSATION_ID || detectAntigravityConversation(storageDir || process.cwd());
733
+ if (activeConvId) {
734
+ const summaryLines = processedBatch
735
+ .slice(0, 3)
736
+ .map(i => `[#${i.id}] ${i.content}`)
737
+ .join('; ');
738
+ const moreText = processedBatch.length > 3 ? ` 等共 ${processedBatch.length} 条` : '';
739
+ const wakeMsg = `📥 [Agent Feedback 自动唤醒] 捕获到端侧真实新反馈 (共 ${processedBatch.length} 条):${summaryLines}${moreText}。请立即进入排查与自愈修复流程。`;
740
+ try {
741
+ const safeMsg = wakeMsg.replace(/"/g, '\\"').replace(/[\r\n]+/g, ' ');
742
+ const agentApiBin = getAgentApiExecutable();
743
+ await execAsync(`${agentApiBin} send-message ${activeConvId} "${safeMsg}"`);
744
+ log(`[*] 🚀 已通过 agentapi 向 Antigravity 会话 [${activeConvId}] 发送主动唤醒消息!`);
745
+ }
746
+ catch (apiErr) {
747
+ warn(`[!] agentapi 唤醒调用异常: ${apiErr?.message}`);
748
+ }
749
+ }
750
+ else {
751
+ warn('[!] 未能识别到活跃的 Antigravity 会话 ID,跳过 agentapi 发送。');
752
+ }
753
+ const shouldExit = options.exitOnWakeup !== undefined
754
+ ? options.exitOnWakeup
755
+ : !options.onWakeup;
756
+ if (shouldExit) {
757
+ cleanup();
758
+ process.exit(0);
759
+ }
760
+ }
761
+ if (isOnce) {
762
+ cleanup();
763
+ resolve();
764
+ return;
765
+ }
766
+ }
767
+ }
768
+ catch (err) {
769
+ warn(`[!] 哨兵检测异常: ${err?.message}`);
770
+ }
771
+ if (isRunning && !options.signal?.aborted) {
772
+ timer = setTimeout(checkLoop, pollIntervalMs);
773
+ }
774
+ else {
775
+ resolve();
776
+ }
777
+ };
778
+ timer = setTimeout(checkLoop, 10);
779
+ });
780
+ }
781
+ export default startSentinel;
782
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAc5E,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAuClC;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAA4B,IAAI,IAAI,EAAE;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7E,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC;QAC5B,OAAO,GAAG,QAAQ,CAAC,WAAW,EAAE,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IACxI,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACvD,OAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;AACnC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,iBAAyB;IAC1D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC;QAAE,OAAO,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACnE,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACjC,OAAO,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,iBAAyB,EAAE,EAAU;IACtE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB,EAAE,IAAS;IACzD,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,GAAG,QAAQ,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC1F,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,yBAAyB;QACzB,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC7C,IAAI,CAAC;YACH,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,gBAAwB,EACxB,OAAe,EACf,QAAgC,EAAE;IAElC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,MAAM,EAAE,CAAC;IACzF,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;IAC9E,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;IAE9F,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,SAAS,IAAI,GAAG,CAAC,CAAC;IACxD,MAAM,UAAU,GAAkB;QAChC,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,GAAG;QACnB,IAAI,EAAE,cAAc;QACpB,MAAM,EAAE,KAAK,CAAC,MAAM,IAAI,WAAW;QACnC,OAAO;QACP,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;QAC3D,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,GAAG;QACjC,IAAI;QACJ,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,kBAAkB;QACxC,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI;YAC5B,KAAK,EAAE,KAAK;YACZ,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;YACzC,SAAS,EAAE,2CAA2C;YACtD,QAAQ,EAAE,SAAS;SACpB;KACF,CAAC;IAEF,YAAY;IACZ,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,YAAY,IAAI,OAAO,CAAC,CAAC;IACpE,IAAI,UAAU,GAAoB,EAAE,CAAC;IACrC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;YAC/D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,UAAU,GAAG,MAAM,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IACD,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,eAAe,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAEvC,UAAU;IACV,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;IAClE,IAAI,KAAK,GAAa,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,UAAU,GAAG,UAAU,CAAC,MAAM,CAAC;IACnC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,OAAO,GAAsB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;YACnF,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;gBACzC,UAAU,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IACD,eAAe,CAAC,SAAS,EAAE;QACzB,KAAK;QACL,UAAU;QACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC;IAEH,8BAA8B;IAC9B,IAAI,UAAU,GAAoB,EAAE,CAAC;IACrC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;YAC/D,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;gBAAE,UAAU,GAAG,MAAM,CAAC;QACjD,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IACD,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC/B,eAAe,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAEvC,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,8BAA8B,CAC5C,UAAkB,EAClB,SAAiB,EACjB,eAAuB;IAEvB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE7C,oBAAoB;IACpB,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,YAAY,KAAK,OAAO,CAAC,CAAC;IACtE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;YAC/D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,IAAI,CAAC,EAAE,GAAG,eAAe,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;wBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,kBAAkB;IAClB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;IAClE,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;YAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;gBAChC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;oBAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,YAAY,IAAI,OAAO,CAAC,CAAC;oBACpE,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,SAAS,KAAK,UAAU,EAAE,CAAC;wBACzD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;wBAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;4BACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gCACzB,IAAI,IAAI,CAAC,EAAE,GAAG,eAAe,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oCAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;gCACzB,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,4BAA4B;IAC5B,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAChD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,IAAI,CAAC,EAAE,GAAG,eAAe,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;wBAC3D,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,cAAsB,EACtB,KAAsB,EACtB,UAA0B,EAAE;IAE5B,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,CAAC;IACrF,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;IAC1E,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;IAC5F,MAAM,iBAAiB,GACrB,OAAO,CAAC,iBAAiB;QACzB,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;IAEpD,IAAI,QAAQ,GAAoB,EAAE,CAAC;IACnC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC1B,QAAQ,GAAG,MAAM,CAAC;YACpB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,GAAG,EAAE,CAAC;QAChB,CAAC;IACH,CAAC;IAED,IAAI,KAAK,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxC,MAAM,cAAc,GAAoB,EAAE,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACjC,MAAM,MAAM,GAAyB,uBAAuB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAE3E,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC;YACzB,IAAI,CAAC,KAAK,GAAG,aAAa,MAAM,CAAC,MAAM,EAAE,CAAC;QAC5C,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC;YAC3B,IAAI,CAAC,KAAK,GAAG,yBAAyB,KAAK,CAAC,MAAM,eAAe,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC;QACxB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE1B,cAAc;QACd,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,IAAI,kBAAkB,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QACpF,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;QACrB,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,YAAY,QAAQ,OAAO,CAAC,CAAC;QACxE,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,UAAU,GAAoB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;gBACpF,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;gBACxD,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;oBACb,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;gBACpD,CAAC;qBAAM,CAAC;oBACN,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBAC3B,CAAC;gBACD,eAAe,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YACzC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;QAED,kBAAkB;QAClB,MAAM,aAAa,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC;QAChE,IAAI,aAAa,IAAI,CAAC,EAAE,CAAC;YACvB,QAAQ,CAAC,aAAa,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IAED,UAAU;IACV,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACpD,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED,gBAAgB;IAChB,kBAAkB,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;IAE7C,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,cAAsB,EACtB,EAAU,EACV,MAAsB,EACtB,KAAc;IAEd,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,CAAC;IACrF,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;IAC1E,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;IAC5F,MAAM,KAAK,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;IAEzB,IAAI,WAAW,GAAyB,IAAI,CAAC;IAE7C,cAAc;IACd,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YACzC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,qBAAqB,IAAI,CAAC,KAAK,qBAAqB,CAAC,CAAC;YACrJ,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;gBAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;gBAC/C,IAAI,CAAC;oBACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;oBAChD,MAAM,SAAS,GAAoB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACnD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;oBACjD,IAAI,IAAI,EAAE,CAAC;wBACT,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;wBACrB,IAAI,KAAK,KAAK,SAAS;4BAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;wBAC5C,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;wBAC1C,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;wBACtC,WAAW,GAAG,IAAI,CAAC;wBACnB,MAAM;oBACR,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,8BAA8B;IAC9B,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAChD,MAAM,KAAK,GAAoB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;YAC7C,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;gBACrB,IAAI,KAAK,KAAK,SAAS;oBAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;gBAC5C,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBAC1C,eAAe,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;gBAClC,IAAI,CAAC,WAAW;oBAAE,WAAW,GAAG,IAAI,CAAC;YACvC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,cAAsB,EACtB,YAAqC;IAErC,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,CAAC;IACrF,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;IAC1E,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;IAE5F,MAAM,GAAG,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE7C,UAAU;IACV,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YACzC,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,qBAAqB,IAAI,CAAC,KAAK,qBAAqB,CAAC,CAAC;YACrJ,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;gBAC5B,IAAI,CAAC;oBACH,MAAM,IAAI,GAAoB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;oBACjG,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;wBACxB,KAAK,MAAM,IAAI,IAAI,IAAI,EAAE,CAAC;4BACxB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;wBACzB,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAA,CAAC;YACZ,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,yBAAyB;IACzB,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAChD,MAAM,KAAK,GAAoB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;wBACtB,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;IAEtE,IAAI,CAAC,YAAY,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAChD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,YAAY,KAAK,KAAK,EAAE,CAAC;QAC3B,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC;AACzD,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB;QACE,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,qFAAqF;QAClG,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,iGAAiG;oBAC9G,IAAI,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,CAAC;iBAChE;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,uDAAuD;iBACrE;aACF;SACF;KACF;IACD;QACE,IAAI,EAAE,wBAAwB;QAC9B,WAAW,EAAE,2FAA2F;QACxG,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,EAAE,EAAE;oBACF,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,0CAA0C;iBACxD;gBACD,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,gCAAgC;oBAC7C,IAAI,EAAE,CAAC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,CAAC;iBACzD;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,oFAAoF;iBAClG;gBACD,UAAU,EAAE;oBACV,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,uDAAuD;iBACrE;aACF;YACD,QAAQ,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC;SAC3B;KACF;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,IAAY,EACZ,OAA4B,EAAE,EAC9B,oBAA4B,iBAAiB;IAE7C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,IAAI,iBAAiB,CAAC;IAEjD,IAAI,IAAI,KAAK,sBAAsB,EAAE,CAAC;QACpC,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;QAChE,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;iBAC9D;aACF;SACF,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,KAAK,wBAAwB,EAAE,CAAC;QACtC,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5E,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,yBAAyB,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC;qBAC/E;iBACF;aACF,CAAC;QACJ,CAAC;QACD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;iBAChE;aACF;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC;aACzD;SACF;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,UAA0B,EAAE;IAC/D,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC,CAAC;IAExF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,CAAC;IAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,QAAQ,EAAE,KAAK;KAChB,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,CAAC,EAAO,EAAE,MAAY,EAAE,KAAW,EAAE,EAAE;QAC1D,MAAM,GAAG,GAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QACxC,IAAI,KAAK,EAAE,CAAC;YACV,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;QACtB,CAAC;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC;IAEF,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,OAAO;QACrB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAChC,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;YAEnC,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;gBAC5B,YAAY,CAAC,EAAE,EAAE;oBACf,eAAe,EAAE,YAAY;oBAC7B,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;oBAC3B,UAAU,EAAE;wBACV,IAAI,EAAE,uCAAuC;wBAC7C,OAAO,EAAE,OAAO;qBACjB;iBACF,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,MAAM,KAAK,2BAA2B,EAAE,CAAC;gBAC3C,OAAO;YACT,CAAC;YAED,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBACtB,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBACrB,OAAO;YACT,CAAC;YAED,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;gBAC5B,YAAY,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;gBACtC,OAAO;YACT,CAAC;YAED,IAAI,MAAM,KAAK,YAAY,EAAE,CAAC;gBAC5B,MAAM,QAAQ,GAAG,MAAM,EAAE,IAAI,CAAC;gBAC9B,MAAM,QAAQ,GAAG,MAAM,EAAE,SAAS,IAAI,EAAE,CAAC;gBACzC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;gBACrE,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC1B,OAAO;YACT,CAAC;YAED,gBAAgB;YAChB,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,qBAAqB,MAAM,EAAE,EAAE,CAAC,CAAC;QACxF,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,aAAa,EAAE,CAAC,CAAC;QAC1F,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAC;IACvE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1D,OAAO,IAAI,MAAM,GAAG,CAAC;IACvB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,kCAAkC,CAAC,CAAC;IACnE,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,MAAM,GAAG,CAAC;IACvB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,6BAA6B,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACvE,IAAI,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,CAAC;QAC5C,OAAO,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC;IACjD,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,+CAA+C,CAAC,CAAC;QAChF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAExC,uCAAuC;QACvC,aAAa;QACb,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAC;QAE/B,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QACpE,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC;;;;;;KAMvB,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAgE,CAAC;QACtF,EAAE,CAAC,KAAK,EAAE,CAAC;QAEX,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,GAAG,CAAC,cAAc,EAAE,CAAC;gBACvB,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC7F,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBAClC,OAAO,GAAG,CAAC,eAAe,CAAC;gBAC7B,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAA0B,EAAE;IAC9D,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IAClF,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC;IACtD,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC,CAAC;IACxF,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,qBAAqB,CAAC,CAAC;IACvF,MAAM,iBAAiB,GACrB,OAAO,CAAC,iBAAiB,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,uBAAuB,CAAC,CAAC;IAEjF,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,6BAA6B,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC5G,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAChF,MAAM,MAAM,GAAG,cAAc,CAAC;IAE9B,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,KAAK,KAAK,CAAC;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM;QACxB,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC;QACV,CAAC,CAAC,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM;QACzB,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC;QACV,CAAC,CAAC,CAAC,GAAG,IAAW,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAE9C,WAAW;IACX,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,eAAe,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,OAAO,KAAK,aAAa,IAAI,MAAM,CAAC,CAAC,CAAC,SAAS,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,GAAG,CAAC,kCAAkC,OAAO,GAAG,QAAQ,MAAM,CAAC,CAAC;IAChE,GAAG,CAAC,uCAAuC,UAAU,GAAG,IAAI,YAAY,CAAC,CAAC;IAE1E,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9E,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC3C,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,IAAI,KAAK,GAA0B,IAAI,CAAC;QAExC,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,SAAS,GAAG,KAAK,CAAC;YAClB,IAAI,KAAK,EAAE,CAAC;gBACV,YAAY,CAAC,KAAK,CAAC,CAAC;gBACpB,KAAK,GAAG,IAAI,CAAC;YACf,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;gBAC5C,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,IAAI,EAAE;YAC3B,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;gBAC1C,OAAO,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,8BAA8B,CAAC,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;gBAExF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACxB,GAAG,CAAC,uBAAuB,QAAQ,CAAC,MAAM,UAAU,UAAU,GAAG,IAAI,aAAa,CAAC,CAAC;oBAEpF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBAC7B,IAAI,eAAe,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC;oBAEpC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,UAAU,EAAE,CAAC;wBAC3C,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO;4BAAE,MAAM;wBAEjD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;wBAEpD,IAAI,CAAC;4BACH,MAAM,MAAM,GAAG,8BAA8B,CAAC,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;4BACtF,IAAI,MAAM,CAAC,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC;gCAC3C,GAAG,CAAC,6BAA6B,MAAM,CAAC,MAAM,OAAO,CAAC,CAAC;gCACvD,eAAe,GAAG,MAAM,CAAC;gCACzB,OAAO,CAAC,kBAAkB,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;4BAC9C,CAAC;wBACH,CAAC;wBAAC,MAAM,CAAC;4BACP,aAAa;wBACf,CAAC;oBACH,CAAC;oBAED,GAAG,CAAC,oBAAoB,eAAe,CAAC,MAAM,SAAS,CAAC,CAAC;oBAEzD,eAAe;oBACf,MAAM,MAAM,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;oBACjE,MAAM,cAAc,GAAG,iBAAiB,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,CAAC,CAAC;oBAC3E,eAAe,GAAG,kBAAkB,CAAC,iBAAiB,CAAC,CAAC;oBAExD,UAAU;oBACV,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;wBAC1B,IAAI,cAAc,GAAG,KAAK,CAAC;wBAC3B,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;4BAC3B,cAAc,GAAG,IAAI,CAAC;4BACtB,IAAI,CAAC;gCACH,MAAM,SAAS,CAAC,OAAO,CAAC,cAAc,EAAE;oCACtC,GAAG,EAAE;wCACH,GAAG,OAAO,CAAC,GAAG;wCACd,cAAc,EAAE,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC;wCAC7C,YAAY,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;qCACtD;iCACF,CAAC,CAAC;4BACL,CAAC;4BAAC,OAAO,MAAW,EAAE,CAAC;gCACrB,IAAI,CAAC,uBAAuB,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;4BACjD,CAAC;wBACH,CAAC;wBACD,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;4BACvB,cAAc,GAAG,IAAI,CAAC;4BACtB,IAAI,CAAC;gCACH,MAAM,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE;oCAC9B,MAAM,EAAE,MAAM;oCACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;oCAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;iCAChD,CAAC,CAAC;4BACL,CAAC;4BAAC,OAAO,MAAW,EAAE,CAAC;gCACrB,IAAI,CAAC,uBAAuB,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;4BACjD,CAAC;wBACH,CAAC;wBACD,IAAI,CAAC,cAAc,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;4BACzC,GAAG,CAAC,8EAA8E,CAAC,CAAC;wBACtF,CAAC;oBACH,CAAC;oBAED,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;wBAC3C,MAAM,OAAO,CAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;oBAClD,CAAC;oBAED,IAAI,OAAO,KAAK,aAAa,EAAE,CAAC;wBAC9B,GAAG,CAAC,kCAAkC,CAAC,CAAC;wBACxC,MAAM,YAAY,GAAG,MAAM,IAAI,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,6BAA6B,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;wBAC/J,IAAI,YAAY,EAAE,CAAC;4BACjB,MAAM,YAAY,GAAG,cAAc;iCAChC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;iCACX,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;iCACnC,IAAI,CAAC,IAAI,CAAC,CAAC;4BACd,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,cAAc,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;4BACnF,MAAM,OAAO,GAAG,0CAA0C,cAAc,CAAC,MAAM,OAAO,YAAY,GAAG,QAAQ,kBAAkB,CAAC;4BAChI,IAAI,CAAC;gCACH,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;gCACtE,MAAM,WAAW,GAAG,qBAAqB,EAAE,CAAC;gCAC5C,MAAM,SAAS,CAAC,GAAG,WAAW,iBAAiB,YAAY,KAAK,OAAO,GAAG,CAAC,CAAC;gCAC5E,GAAG,CAAC,yCAAyC,YAAY,aAAa,CAAC,CAAC;4BAC1E,CAAC;4BAAC,OAAO,MAAW,EAAE,CAAC;gCACrB,IAAI,CAAC,wBAAwB,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;4BAClD,CAAC;wBACH,CAAC;6BAAM,CAAC;4BACN,IAAI,CAAC,gDAAgD,CAAC,CAAC;wBACzD,CAAC;wBAED,MAAM,UAAU,GACd,OAAO,CAAC,YAAY,KAAK,SAAS;4BAChC,CAAC,CAAC,OAAO,CAAC,YAAY;4BACtB,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;wBACxB,IAAI,UAAU,EAAE,CAAC;4BACf,OAAO,EAAE,CAAC;4BACV,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;wBAClB,CAAC;oBACH,CAAC;oBAED,IAAI,MAAM,EAAE,CAAC;wBACX,OAAO,EAAE,CAAC;wBACV,OAAO,EAAE,CAAC;wBACV,OAAO;oBACT,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,IAAI,CAAC,eAAe,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;YACtC,CAAC;YAED,IAAI,SAAS,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;gBAC1C,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC,CAAC;QAEF,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,eAAe,aAAa,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,45 @@
1
1
  {
2
2
  "name": "@lylyuanliang/agent-feedback-sentinel",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "1.1.0",
4
+ "description": "Silent watcher CLI & pluggable AI Coding Agent wakeup adapters",
5
+ "type": "module",
6
+ "bin": {
7
+ "agent-feedback": "./bin/cli.js"
8
+ },
9
+ "main": "dist/index.js",
10
+ "module": "dist/index.js",
11
+ "types": "dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js",
16
+ "default": "./dist/index.js"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "bin",
22
+ "README.md",
23
+ "LICENSE"
24
+ ],
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "dependencies": {
29
+ "@lylyuanliang/agent-feedback-core": "1.1.0"
30
+ },
31
+ "keywords": [
32
+ "agent-feedback",
33
+ "sentinel",
34
+ "watcher",
35
+ "cli",
36
+ "mcp",
37
+ "antigravity",
38
+ "coding-agent"
39
+ ],
40
+ "license": "MIT",
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "test": "node --experimental-strip-types --test tests/sentinel.test.ts"
44
+ }
6
45
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.