@greatlhd/ailo-desktop 1.0.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.
Files changed (73) hide show
  1. package/copy-static.mjs +11 -0
  2. package/dist/browser_control.js +767 -0
  3. package/dist/browser_snapshot.js +174 -0
  4. package/dist/cli.js +36 -0
  5. package/dist/code_executor.js +95 -0
  6. package/dist/config_server.js +658 -0
  7. package/dist/connection_util.js +14 -0
  8. package/dist/constants.js +2 -0
  9. package/dist/desktop_state_store.js +57 -0
  10. package/dist/desktop_types.js +1 -0
  11. package/dist/desktop_verifier.js +40 -0
  12. package/dist/dingtalk-handler.js +173 -0
  13. package/dist/dingtalk-types.js +1 -0
  14. package/dist/email_handler.js +501 -0
  15. package/dist/exec_tool.js +90 -0
  16. package/dist/feishu-handler.js +620 -0
  17. package/dist/feishu-types.js +8 -0
  18. package/dist/feishu-utils.js +162 -0
  19. package/dist/fs_tools.js +398 -0
  20. package/dist/index.js +433 -0
  21. package/dist/mcp/config-manager.js +64 -0
  22. package/dist/mcp/index.js +3 -0
  23. package/dist/mcp/rpc.js +109 -0
  24. package/dist/mcp/session.js +140 -0
  25. package/dist/mcp_manager.js +253 -0
  26. package/dist/mouse_keyboard.js +516 -0
  27. package/dist/qq-handler.js +153 -0
  28. package/dist/qq-types.js +15 -0
  29. package/dist/qq-ws.js +178 -0
  30. package/dist/screenshot.js +271 -0
  31. package/dist/skills_hub.js +212 -0
  32. package/dist/skills_manager.js +103 -0
  33. package/dist/static/AGENTS.md +25 -0
  34. package/dist/static/app.css +539 -0
  35. package/dist/static/app.html +292 -0
  36. package/dist/static/app.js +380 -0
  37. package/dist/static/chat.html +994 -0
  38. package/dist/time_tool.js +22 -0
  39. package/dist/utils.js +15 -0
  40. package/package.json +38 -0
  41. package/src/browser_control.ts +739 -0
  42. package/src/browser_snapshot.ts +196 -0
  43. package/src/cli.ts +44 -0
  44. package/src/code_executor.ts +101 -0
  45. package/src/config_server.ts +723 -0
  46. package/src/connection_util.ts +23 -0
  47. package/src/constants.ts +2 -0
  48. package/src/desktop_state_store.ts +64 -0
  49. package/src/desktop_types.ts +44 -0
  50. package/src/desktop_verifier.ts +45 -0
  51. package/src/dingtalk-types.ts +26 -0
  52. package/src/exec_tool.ts +93 -0
  53. package/src/feishu-handler.ts +722 -0
  54. package/src/feishu-types.ts +66 -0
  55. package/src/feishu-utils.ts +174 -0
  56. package/src/fs_tools.ts +411 -0
  57. package/src/index.ts +474 -0
  58. package/src/mcp/config-manager.ts +85 -0
  59. package/src/mcp/index.ts +7 -0
  60. package/src/mcp/rpc.ts +131 -0
  61. package/src/mcp/session.ts +182 -0
  62. package/src/mcp_manager.ts +273 -0
  63. package/src/mouse_keyboard.ts +526 -0
  64. package/src/qq-types.ts +49 -0
  65. package/src/qq-ws.ts +223 -0
  66. package/src/screenshot.ts +297 -0
  67. package/src/static/app.css +539 -0
  68. package/src/static/app.html +292 -0
  69. package/src/static/app.js +380 -0
  70. package/src/static/chat.html +994 -0
  71. package/src/time_tool.ts +24 -0
  72. package/src/utils.ts +22 -0
  73. package/tsconfig.json +13 -0
@@ -0,0 +1,292 @@
1
+ <!DOCTYPE html>
2
+ <html lang="zh">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Ailo Desktop</title>
7
+ <link rel="stylesheet" href="/app.css">
8
+ </head>
9
+ <body>
10
+
11
+ <!-- ─── Sidebar ─────────────────────────────────────────────── -->
12
+ <aside class="sidebar">
13
+ <div class="sidebar-brand">
14
+ <div class="brand-icon">
15
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
16
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
17
+ </svg>
18
+ </div>
19
+ <div class="brand-info">
20
+ <div class="brand-name">Ailo Desktop</div>
21
+ <div class="brand-status">
22
+ <span class="status-dot off" id="globalDot"></span>
23
+ <span id="globalStatus">未连接</span>
24
+ </div>
25
+ </div>
26
+ </div>
27
+
28
+ <nav class="sidebar-nav">
29
+ <div class="nav-section-label">主界面</div>
30
+ <div class="nav-item active" data-panel="chat" onclick="nav('chat')">
31
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
32
+ <span>网页聊天</span>
33
+ </div>
34
+ <div class="nav-item" data-panel="status" onclick="nav('status')">
35
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/></svg>
36
+ <span>状态</span>
37
+ </div>
38
+
39
+ <div class="nav-section-label">能力</div>
40
+ <div class="nav-item" data-panel="tools" onclick="nav('tools')">
41
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
42
+ <span>工具</span>
43
+ </div>
44
+ <div class="nav-item" data-panel="mcp" onclick="nav('mcp')">
45
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83"/></svg>
46
+ <span>MCP</span>
47
+ </div>
48
+
49
+ <div class="nav-section-label">通道配置</div>
50
+ <div class="nav-item" data-panel="feishu" onclick="nav('feishu')">
51
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
52
+ <span>飞书</span>
53
+ <span class="nav-badge off" id="feishuNavBadge" style="display:none"></span>
54
+ </div>
55
+
56
+ <div class="nav-section-label">系统</div>
57
+ <div class="nav-item" data-panel="env" onclick="nav('env')">
58
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
59
+ <span>运行环境</span>
60
+ </div>
61
+ </nav>
62
+ </aside>
63
+
64
+ <!-- ─── Main ─────────────────────────────────────────────────── -->
65
+ <div class="main">
66
+ <div class="main-content">
67
+
68
+ <!-- 网页聊天 -->
69
+ <div class="panel active" id="panel-chat" style="height:100vh;overflow:hidden;margin:-20px -32px -32px">
70
+ <iframe src="/chat" title="网页聊天" class="chat-embed"></iframe>
71
+ </div>
72
+
73
+ <!-- 状态 -->
74
+ <div class="panel" id="panel-status">
75
+ <div class="card" id="statusCard">
76
+ <div class="connection-hero">
77
+ <div class="connection-icon" id="connectionIcon">
78
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
79
+ <path d="M5 12.55a11 11 0 0 1 14.08 0"/><path d="M1.42 9a16 16 0 0 1 21.16 0"/>
80
+ <path d="M8.53 16.11a6 6 0 0 1 6.95 0"/><line x1="12" y1="20" x2="12.01" y2="20"/>
81
+ </svg>
82
+ </div>
83
+ <div>
84
+ <div class="connection-label" id="connectionLabel">未连接</div>
85
+ <div class="connection-sublabel" id="connectionSublabel">尚未连接至 Ailo 服务</div>
86
+ </div>
87
+ <div style="margin-left:auto" id="connectionBadgeWrap"></div>
88
+ </div>
89
+ <div class="info-grid" id="statusInfoGrid" style="display:none">
90
+ <div class="info-item">
91
+ <div class="info-item-label">端点 ID</div>
92
+ <div class="info-item-value" id="statusEndpointId">-</div>
93
+ </div>
94
+ <div class="info-item">
95
+ <div class="info-item-label">连接状态</div>
96
+ <div class="info-item-value" id="statusConnected">-</div>
97
+ </div>
98
+ </div>
99
+ </div>
100
+
101
+ <!-- 连接配置(仅 showConnectionForm=true 时显示) -->
102
+ <div class="card" id="connectionFormCard" style="display:none">
103
+ <div class="card-header">
104
+ <div>
105
+ <div class="card-title">
106
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83"/></svg>
107
+ Ailo 连接配置
108
+ </div>
109
+ <div class="card-desc">保存后将使用新配置自动重连,无需重启进程</div>
110
+ </div>
111
+ </div>
112
+ <div class="form-group"><label>AILO_WS_URL</label><input id="connWsUrl" placeholder="ws://127.0.0.1:19800/ws"></div>
113
+ <div class="form-group"><label>AILO_API_KEY</label><input id="connApiKey" type="text" placeholder="ailo_ep_xxx" autocomplete="off"></div>
114
+ <div class="form-group"><label>AILO_ENDPOINT_ID</label><input id="connEndpointId" placeholder="desktop-01"></div>
115
+ <div class="btn-group">
116
+ <button class="btn btn-primary" id="saveConnBtn" onclick="saveConnection()">
117
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
118
+ 保存配置
119
+ </button>
120
+ </div>
121
+ </div>
122
+ </div>
123
+
124
+ <!-- 工具 -->
125
+ <div class="panel" id="panel-tools">
126
+ <div class="sub-tabs">
127
+ <button class="sub-tab active" data-sub="reported" onclick="toolsSub('reported')">已上报工具</button>
128
+ <button class="sub-tab" data-sub="blueprints" onclick="toolsSub('blueprints')">蓝图</button>
129
+ </div>
130
+ <div class="sub-panel active" id="sub-reported">
131
+ <div class="card">
132
+ <div class="card-header">
133
+ <div class="card-title">
134
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
135
+ 已上报工具
136
+ </div>
137
+ <button class="btn btn-secondary btn-sm" onclick="loadReportedTools()">
138
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 .49-3.51"/></svg>
139
+ 刷新
140
+ </button>
141
+ </div>
142
+ <div class="card-desc" style="margin-bottom:12px">桌面端向 Ailo 注册的能力(蓝图 + MCP),可直接在对话中调用</div>
143
+ <div id="reportedToolsList"><div class="loading-text">加载中...</div></div>
144
+ </div>
145
+ </div>
146
+ <div class="sub-panel" id="sub-blueprints">
147
+ <div class="card">
148
+ <div class="card-header">
149
+ <div class="card-title">
150
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>
151
+ 蓝图
152
+ </div>
153
+ <button class="btn btn-secondary btn-sm" onclick="loadAllBlueprints()">
154
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 .49-3.51"/></svg>
155
+ 刷新
156
+ </button>
157
+ </div>
158
+ <div class="card-desc" style="margin-bottom:14px">当前激活蓝图列表(仅已配置的通道才会出现)</div>
159
+ <div class="sub-tabs blueprint-tabs" id="blueprintTabRow"></div>
160
+ <div id="blueprintPanels"><div class="loading-text">加载中...</div></div>
161
+ </div>
162
+ </div>
163
+ </div>
164
+
165
+ <!-- MCP -->
166
+ <div class="panel" id="panel-mcp">
167
+ <div class="card">
168
+ <div class="card-header">
169
+ <div class="card-title">
170
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"/><path d="M12 1v4M12 19v4M4.22 4.22l2.83 2.83M16.95 16.95l2.83 2.83M1 12h4M19 12h4M4.22 19.78l2.83-2.83M16.95 7.05l2.83-2.83"/></svg>
171
+ MCP 服务
172
+ </div>
173
+ <div class="btn-group" style="margin:0">
174
+ <button class="btn btn-primary btn-sm" onclick="showMCPCreateModal()">
175
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
176
+ 新增
177
+ </button>
178
+ <button class="btn btn-secondary btn-sm" onclick="loadMCP()">
179
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 .49-3.51"/></svg>
180
+ 刷新
181
+ </button>
182
+ </div>
183
+ </div>
184
+ <div class="card-desc" style="margin-bottom:12px">配置保存在 <code>~/.agents/mcp_config.json</code>,新增后需点击「启动」才会上报工具</div>
185
+ <div id="mcpList"><div class="loading-text">加载中...</div></div>
186
+ </div>
187
+ </div>
188
+
189
+ <!-- 飞书 -->
190
+ <div class="panel" id="panel-feishu">
191
+ <div class="card">
192
+ <div class="channel-header">
193
+ <div class="channel-icon" style="background:rgba(6,182,212,.15)">🐦</div>
194
+ <div>
195
+ <div class="channel-title">飞书通道</div>
196
+ <div class="channel-subtitle">通过飞书 WebSocket 接收消息并代为回复</div>
197
+ </div>
198
+ <div style="margin-left:auto" id="feishuStatusBadge"></div>
199
+ </div>
200
+ <div class="form-group"><label>App ID</label><input id="feishuAppId" placeholder="cli_xxx"></div>
201
+ <div class="form-group"><label>App Secret</label><input id="feishuAppSecret" type="text" autocomplete="off" placeholder="应用密钥"></div>
202
+ <div class="btn-group">
203
+ <button class="btn btn-primary" id="saveFeishuBtn" onclick="saveFeishuConfig()">
204
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>
205
+ 保存
206
+ </button>
207
+ </div>
208
+ </div>
209
+ </div>
210
+
211
+ <!-- 运行环境 -->
212
+ <div class="panel" id="panel-env">
213
+ <div class="card">
214
+ <div class="card-header">
215
+ <div class="card-title">
216
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>
217
+ 运行环境检测
218
+ </div>
219
+ <button class="btn btn-secondary btn-sm" onclick="loadEnvCheck()">
220
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="1 4 1 10 7 10"/><path d="M3.51 15a9 9 0 1 0 .49-3.51"/></svg>
221
+ 刷新
222
+ </button>
223
+ </div>
224
+ <div class="card-desc" style="margin-bottom:16px">以下为桌面端与 Skills 所需的运行环境。未安装时请按提示操作;仅「Playwright Chromium」支持一键安装。</div>
225
+ <div id="envCheckList"><div class="loading-text">加载中...</div></div>
226
+ <div id="envInstallRow" style="margin-top:14px;display:none">
227
+ <button class="btn btn-primary btn-sm" id="envInstallBtn" onclick="doEnvInstall()">
228
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></svg>
229
+ 安装缺失依赖
230
+ </button>
231
+ </div>
232
+ </div>
233
+ </div>
234
+
235
+ </div><!-- .main-content -->
236
+ </div><!-- .main -->
237
+
238
+ <!-- ─── Toast container ──────────────────────────────────────── -->
239
+ <div id="toast-container"></div>
240
+
241
+ <!-- ─── Modals ───────────────────────────────────────────────── -->
242
+
243
+ <!-- Add MCP Modal -->
244
+ <div class="modal-overlay" id="mcpCreateModal">
245
+ <div class="modal modal-lg">
246
+ <div class="modal-title">新增 MCP 服务</div>
247
+ <div class="modal-sub">选择传输类型:stdio(本地命令)或 SSE(远程服务器 URL)</div>
248
+ <div class="form-group"><label>名称</label><input id="mcpName" placeholder="filesystem"></div>
249
+ <div class="form-group">
250
+ <label>传输类型</label>
251
+ <select id="mcpTransport" onchange="onMCPTransportChange()">
252
+ <option value="stdio">stdio(本地命令)</option>
253
+ <option value="sse">SSE(远程服务器)</option>
254
+ </select>
255
+ </div>
256
+ <div id="mcpStdioFields">
257
+ <div class="form-group">
258
+ <label>命令与参数(数组,每行一项)</label>
259
+ <div id="mcpCommandArgsList" style="display:flex;flex-direction:column;gap:6px;margin-bottom:8px"></div>
260
+ <button type="button" class="btn btn-secondary btn-sm" onclick="addMCPArgvRow()">+ 添加一项</button>
261
+ </div>
262
+ </div>
263
+ <div id="mcpSSEFields" style="display:none">
264
+ <div class="form-group"><label>服务器 URL</label><input id="mcpSSEUrl" placeholder="http://localhost:3001"></div>
265
+ </div>
266
+ <div class="form-group">
267
+ <label>环境变量</label>
268
+ <div id="mcpEnvList" style="display:flex;flex-direction:column;gap:6px;margin-bottom:8px"></div>
269
+ <button type="button" class="btn btn-secondary btn-sm" onclick="addMCPEnvRow()">+ 添加环境变量</button>
270
+ </div>
271
+ <div class="modal-footer">
272
+ <button class="btn btn-secondary btn-sm" onclick="hideModal('mcpCreateModal')">取消</button>
273
+ <button class="btn btn-primary btn-sm" onclick="doCreateMCP()">添加</button>
274
+ </div>
275
+ </div>
276
+ </div>
277
+
278
+ <!-- Env Hint Modal -->
279
+ <div class="modal-overlay" id="envHintModal">
280
+ <div class="modal">
281
+ <div class="modal-title" id="envHintModalTitle">安装说明</div>
282
+ <div id="envHintModalContent" style="font-size:14px;color:var(--text-secondary);line-height:1.65;white-space:pre-line;max-height:55vh;overflow:auto"></div>
283
+ <div class="modal-footer">
284
+ <button class="btn btn-secondary btn-sm" onclick="hideModal('envHintModal')">关闭</button>
285
+ </div>
286
+ </div>
287
+ </div>
288
+
289
+ <script>window.SHOW_CONNECTION_FORM = __SHOW_CONNECTION_FORM__;</script>
290
+ <script src="/app.js"></script>
291
+ </body>
292
+ </html>