@geminilight/mindos 1.0.10 → 1.1.3

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 (209) hide show
  1. package/README_zh.md +3 -3
  2. package/bin/mindos-shim.cjs +318 -7
  3. package/dist/agent/prompts.d.ts +1 -1
  4. package/dist/agent/prompts.d.ts.map +1 -1
  5. package/dist/agent/prompts.js +14 -0
  6. package/dist/agent/prompts.js.map +1 -1
  7. package/dist/agent-runtime/claude-code-cli.d.ts +34 -0
  8. package/dist/agent-runtime/claude-code-cli.d.ts.map +1 -0
  9. package/dist/agent-runtime/claude-code-cli.js +259 -0
  10. package/dist/agent-runtime/claude-code-cli.js.map +1 -0
  11. package/dist/agent-runtime/claude-code-sdk.d.ts +41 -0
  12. package/dist/agent-runtime/claude-code-sdk.d.ts.map +1 -0
  13. package/dist/agent-runtime/claude-code-sdk.js +553 -0
  14. package/dist/agent-runtime/claude-code-sdk.js.map +1 -0
  15. package/dist/agent-runtime/codex-app-server.d.ts +154 -0
  16. package/dist/agent-runtime/codex-app-server.d.ts.map +1 -0
  17. package/dist/agent-runtime/codex-app-server.js +628 -0
  18. package/dist/agent-runtime/codex-app-server.js.map +1 -0
  19. package/dist/agent-runtime/codex-env.d.ts +41 -0
  20. package/dist/agent-runtime/codex-env.d.ts.map +1 -0
  21. package/dist/agent-runtime/codex-env.js +278 -0
  22. package/dist/agent-runtime/codex-env.js.map +1 -0
  23. package/dist/agent-runtime/index.d.ts +7 -0
  24. package/dist/agent-runtime/index.d.ts.map +1 -0
  25. package/dist/agent-runtime/index.js +7 -0
  26. package/dist/agent-runtime/index.js.map +1 -0
  27. package/dist/agent-runtime/run.d.ts +111 -0
  28. package/dist/agent-runtime/run.d.ts.map +1 -0
  29. package/dist/agent-runtime/run.js +681 -0
  30. package/dist/agent-runtime/run.js.map +1 -0
  31. package/dist/agent-runtime/runtime-env.d.ts +28 -0
  32. package/dist/agent-runtime/runtime-env.d.ts.map +1 -0
  33. package/dist/agent-runtime/runtime-env.js +66 -0
  34. package/dist/agent-runtime/runtime-env.js.map +1 -0
  35. package/dist/agent-runtime.d.ts +2 -0
  36. package/dist/agent-runtime.d.ts.map +1 -0
  37. package/dist/agent-runtime.js +2 -0
  38. package/dist/agent-runtime.js.map +1 -0
  39. package/dist/client.d.ts +8 -1
  40. package/dist/client.d.ts.map +1 -1
  41. package/dist/client.js.map +1 -1
  42. package/dist/foundation/config/schema.d.ts +30 -141
  43. package/dist/foundation/config/schema.d.ts.map +1 -1
  44. package/dist/foundation/config/schema.js +18 -4
  45. package/dist/foundation/config/schema.js.map +1 -1
  46. package/dist/index.d.ts +1 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +1 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/knowledge/audit/index.d.ts +4 -0
  51. package/dist/knowledge/audit/index.d.ts.map +1 -1
  52. package/dist/knowledge/audit/index.js +92 -8
  53. package/dist/knowledge/audit/index.js.map +1 -1
  54. package/dist/knowledge/git/index.d.ts.map +1 -1
  55. package/dist/knowledge/git/index.js +43 -2
  56. package/dist/knowledge/git/index.js.map +1 -1
  57. package/dist/protocols/acp/agent-descriptors.d.ts.map +1 -1
  58. package/dist/protocols/acp/agent-descriptors.js +7 -4
  59. package/dist/protocols/acp/agent-descriptors.js.map +1 -1
  60. package/dist/protocols/acp/index.js +39 -28
  61. package/dist/protocols/acp/session.d.ts.map +1 -1
  62. package/dist/protocols/acp/session.js +11 -14
  63. package/dist/protocols/acp/session.js.map +1 -1
  64. package/dist/protocols/acp/subprocess.d.ts +4 -1
  65. package/dist/protocols/acp/subprocess.d.ts.map +1 -1
  66. package/dist/protocols/acp/subprocess.js +37 -10
  67. package/dist/protocols/acp/subprocess.js.map +1 -1
  68. package/dist/protocols/mcp-server/index.cjs +80 -68
  69. package/dist/server/channel-contract.d.ts +13 -0
  70. package/dist/server/channel-contract.d.ts.map +1 -0
  71. package/dist/server/channel-contract.js +115 -0
  72. package/dist/server/channel-contract.js.map +1 -0
  73. package/dist/server/contract.d.ts.map +1 -1
  74. package/dist/server/contract.js +12 -0
  75. package/dist/server/contract.js.map +1 -1
  76. package/dist/server/handlers/a2a.d.ts +7 -0
  77. package/dist/server/handlers/a2a.d.ts.map +1 -1
  78. package/dist/server/handlers/a2a.js +5 -1
  79. package/dist/server/handlers/a2a.js.map +1 -1
  80. package/dist/server/handlers/agent-capabilities.d.ts +60 -0
  81. package/dist/server/handlers/agent-capabilities.d.ts.map +1 -0
  82. package/dist/server/handlers/agent-capabilities.js +178 -0
  83. package/dist/server/handlers/agent-capabilities.js.map +1 -0
  84. package/dist/server/handlers/agent-runtime-codex.d.ts +29 -0
  85. package/dist/server/handlers/agent-runtime-codex.d.ts.map +1 -0
  86. package/dist/server/handlers/agent-runtime-codex.js +198 -0
  87. package/dist/server/handlers/agent-runtime-codex.js.map +1 -0
  88. package/dist/server/handlers/agent-runtimes.d.ts +136 -0
  89. package/dist/server/handlers/agent-runtimes.d.ts.map +1 -0
  90. package/dist/server/handlers/agent-runtimes.js +712 -0
  91. package/dist/server/handlers/agent-runtimes.js.map +1 -0
  92. package/dist/server/handlers/agents.d.ts +6 -0
  93. package/dist/server/handlers/agents.d.ts.map +1 -1
  94. package/dist/server/handlers/agents.js +41 -6
  95. package/dist/server/handlers/agents.js.map +1 -1
  96. package/dist/server/handlers/ask.d.ts +18 -0
  97. package/dist/server/handlers/ask.d.ts.map +1 -1
  98. package/dist/server/handlers/ask.js +70 -0
  99. package/dist/server/handlers/ask.js.map +1 -1
  100. package/dist/server/handlers/channels-verify.d.ts +1 -1
  101. package/dist/server/handlers/channels-verify.d.ts.map +1 -1
  102. package/dist/server/handlers/channels-verify.js +1 -63
  103. package/dist/server/handlers/channels-verify.js.map +1 -1
  104. package/dist/server/handlers/extract-docx.d.ts +42 -0
  105. package/dist/server/handlers/extract-docx.d.ts.map +1 -0
  106. package/dist/server/handlers/extract-docx.js +101 -0
  107. package/dist/server/handlers/extract-docx.js.map +1 -0
  108. package/dist/server/handlers/extract-pdf.d.ts +32 -0
  109. package/dist/server/handlers/extract-pdf.d.ts.map +1 -0
  110. package/dist/server/handlers/extract-pdf.js +116 -0
  111. package/dist/server/handlers/extract-pdf.js.map +1 -0
  112. package/dist/server/handlers/im-activity.d.ts.map +1 -1
  113. package/dist/server/handlers/im-activity.js +26 -1
  114. package/dist/server/handlers/im-activity.js.map +1 -1
  115. package/dist/server/handlers/im-config.d.ts +1 -1
  116. package/dist/server/handlers/im-config.d.ts.map +1 -1
  117. package/dist/server/handlers/im-config.js +69 -59
  118. package/dist/server/handlers/im-config.js.map +1 -1
  119. package/dist/server/handlers/im-feishu-oauth.d.ts +55 -0
  120. package/dist/server/handlers/im-feishu-oauth.d.ts.map +1 -0
  121. package/dist/server/handlers/im-feishu-oauth.js +218 -0
  122. package/dist/server/handlers/im-feishu-oauth.js.map +1 -0
  123. package/dist/server/handlers/im-status.d.ts +15 -0
  124. package/dist/server/handlers/im-status.d.ts.map +1 -1
  125. package/dist/server/handlers/im-status.js +41 -24
  126. package/dist/server/handlers/im-status.js.map +1 -1
  127. package/dist/server/handlers/inbox-source.d.ts +18 -0
  128. package/dist/server/handlers/inbox-source.d.ts.map +1 -0
  129. package/dist/server/handlers/inbox-source.js +108 -0
  130. package/dist/server/handlers/inbox-source.js.map +1 -0
  131. package/dist/server/handlers/inbox.d.ts +2 -0
  132. package/dist/server/handlers/inbox.d.ts.map +1 -1
  133. package/dist/server/handlers/inbox.js +34 -2
  134. package/dist/server/handlers/inbox.js.map +1 -1
  135. package/dist/server/handlers/mcp-agents.d.ts +16 -1
  136. package/dist/server/handlers/mcp-agents.d.ts.map +1 -1
  137. package/dist/server/handlers/mcp-agents.js +174 -44
  138. package/dist/server/handlers/mcp-agents.js.map +1 -1
  139. package/dist/server/handlers/mcp-install.d.ts +5 -0
  140. package/dist/server/handlers/mcp-install.d.ts.map +1 -1
  141. package/dist/server/handlers/mcp-install.js +68 -20
  142. package/dist/server/handlers/mcp-install.js.map +1 -1
  143. package/dist/server/handlers/mcp-restart.js +1 -1
  144. package/dist/server/handlers/mcp-restart.js.map +1 -1
  145. package/dist/server/handlers/mcp-status.d.ts +7 -1
  146. package/dist/server/handlers/mcp-status.d.ts.map +1 -1
  147. package/dist/server/handlers/mcp-status.js +14 -1
  148. package/dist/server/handlers/mcp-status.js.map +1 -1
  149. package/dist/server/handlers/settings-list-models.d.ts +1 -1
  150. package/dist/server/handlers/settings-list-models.d.ts.map +1 -1
  151. package/dist/server/handlers/settings-list-models.js +6 -5
  152. package/dist/server/handlers/settings-list-models.js.map +1 -1
  153. package/dist/server/handlers/settings-test-key.d.ts.map +1 -1
  154. package/dist/server/handlers/settings-test-key.js +17 -7
  155. package/dist/server/handlers/settings-test-key.js.map +1 -1
  156. package/dist/server/handlers/settings.d.ts +5 -1
  157. package/dist/server/handlers/settings.d.ts.map +1 -1
  158. package/dist/server/handlers/settings.js +54 -5
  159. package/dist/server/handlers/settings.js.map +1 -1
  160. package/dist/server/handlers/skills.d.ts +1 -0
  161. package/dist/server/handlers/skills.d.ts.map +1 -1
  162. package/dist/server/handlers/skills.js +7 -5
  163. package/dist/server/handlers/skills.js.map +1 -1
  164. package/dist/server/handlers/sync.d.ts +15 -4
  165. package/dist/server/handlers/sync.d.ts.map +1 -1
  166. package/dist/server/handlers/sync.js +552 -81
  167. package/dist/server/handlers/sync.js.map +1 -1
  168. package/dist/server/handlers/uninstall.js +1 -0
  169. package/dist/server/handlers/uninstall.js.map +1 -1
  170. package/dist/server/handlers/update.js +1 -0
  171. package/dist/server/handlers/update.js.map +1 -1
  172. package/dist/server/http.d.ts +20 -0
  173. package/dist/server/http.d.ts.map +1 -1
  174. package/dist/server/http.js +228 -25
  175. package/dist/server/http.js.map +1 -1
  176. package/dist/server/index.d.ts +14 -5
  177. package/dist/server/index.d.ts.map +1 -1
  178. package/dist/server/index.js +11 -2
  179. package/dist/server/index.js.map +1 -1
  180. package/dist/server/mcp-agent-registry.d.ts +184 -0
  181. package/dist/server/mcp-agent-registry.d.ts.map +1 -1
  182. package/dist/server/mcp-agent-registry.js +100 -9
  183. package/dist/server/mcp-agent-registry.js.map +1 -1
  184. package/dist/server/provider-settings.d.ts +38 -0
  185. package/dist/server/provider-settings.d.ts.map +1 -0
  186. package/dist/server/provider-settings.js +286 -0
  187. package/dist/server/provider-settings.js.map +1 -0
  188. package/dist/server/route-ownership.d.ts.map +1 -1
  189. package/dist/server/route-ownership.js +18 -2
  190. package/dist/server/route-ownership.js.map +1 -1
  191. package/dist/server/runtime.d.ts +1 -0
  192. package/dist/server/runtime.d.ts.map +1 -1
  193. package/dist/server/runtime.js.map +1 -1
  194. package/dist/session/index.d.ts +96 -15
  195. package/dist/session/index.d.ts.map +1 -1
  196. package/dist/session/index.js +162 -30
  197. package/dist/session/index.js.map +1 -1
  198. package/dist/session/pi-coding-agent-runtime.js +3 -3
  199. package/dist/session/pi-coding-agent-runtime.js.map +1 -1
  200. package/dist/session/redaction.d.ts +3 -0
  201. package/dist/session/redaction.d.ts.map +1 -0
  202. package/dist/session/redaction.js +47 -0
  203. package/dist/session/redaction.js.map +1 -0
  204. package/dist/setup/index.d.ts +1 -0
  205. package/dist/setup/index.d.ts.map +1 -1
  206. package/dist/setup/index.js +13 -0
  207. package/dist/setup/index.js.map +1 -1
  208. package/package.json +18 -12
  209. package/src/cli.js +1 -0
package/README_zh.md CHANGED
@@ -102,7 +102,7 @@ MindOS 是你思考的地方,也是 AI Agent 行动的起点——一个你和
102
102
  | 2026-04 | **产品主包落地** — MindOS 采用 OpenCode 式核心包:`packages/mindos`(`@geminilight/mindos`)承载产品 runtime facade 与 CLI kernel 边界;Web/CLI 围绕它做适配。 |
103
103
  | 2026-04 | **OpenCode 式 workspace 扁平化** — 所有源码 workspace 已统一到 `packages/`:`packages/web`、`packages/desktop`、`packages/mobile`、`packages/mindos`,以及可选 `packages/retrieval/*` adapters。npm tarball / CLI / MCP / Web standalone / Desktop / Mobile 均已验证。 |
104
104
  | 2026-04 | **发布包清理** — 旧顶层 `app/`、`mcp/`、`desktop/`、`mobile/` 源码根已移除,发布清单精确排除测试、缓存与 nested `node_modules`。 |
105
- | 2026-04 | **网页剪藏插件** — 浏览器扩展,一键剪藏任意网页到 MindOS 暂存台。[安装 →](packages/browser-extension/) |
105
+ | 2026-04 | **网页剪藏插件** — 浏览器扩展,一键剪藏任意网页到 MindOS 收集箱。[安装 →](packages/browser-extension/) |
106
106
  | 2026-04 | **PDF & 图片导入** — 拖拽 PDF 和图片到 MindOS,自动转换为可搜索的 Markdown。 |
107
107
 
108
108
  ## 🧠 人机共享心智
@@ -205,7 +205,7 @@ npx skills add https://github.com/GeminiLight/MindOS --skill mindos-zh -g -y #
205
205
  MindOS 的知识不必从零开始——把你已有的信息导入进来:
206
206
 
207
207
  - **拖拽导入**:将文件(PDF、图片、Markdown、CSV)直接拖入 MindOS GUI,AI 自动分析并归档到对应文件夹。
208
- - **网页剪藏**:安装[浏览器插件](packages/browser-extension/),一键保存任意网页到暂存台。快捷键 Ctrl+Shift+M 或右键菜单 →「Save to MindOS」。
208
+ - **网页剪藏**:安装[浏览器插件](packages/browser-extension/),一键保存任意网页到收集箱。快捷键 Ctrl+Shift+M 或右键菜单 →「Save to MindOS」。
209
209
  - **Agent 导入**:让任意已连接的 Agent 阅读文档并同步到你的知识库。
210
210
 
211
211
  ## ✨ 功能特性
@@ -217,7 +217,7 @@ MindOS 的知识不必从零开始——把你已有的信息导入进来:
217
217
  - **一键导入**:拖拽文件即可导入,Inline AI Organize 自动分析、分类、写入知识库,支持进度追踪和撤销。
218
218
  - **新手引导**:首次使用的分步引导体验,帮助新用户快速搭建知识库并连接第一个 Agent。
219
219
  - **插件扩展**:多种内置渲染器插件——TODO Board、CSV Views、Wiki Graph、Timeline、Workflow Editor、Agent Inspector 等。
220
- - **网页剪藏**:浏览器扩展,一键将任意网页保存为干净的 Markdown——存入暂存台,稍后 AI 自动整理归档。[安装 →](packages/browser-extension/)
220
+ - **网页剪藏**:浏览器扩展,一键将任意网页保存为干净的 Markdown——存入收集箱,稍后 AI 自动整理归档。[安装 →](packages/browser-extension/)
221
221
 
222
222
  **Agent 侧**
223
223
 
@@ -1,13 +1,18 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const childProcess = require('node:child_process');
4
+ const crypto = require('node:crypto');
4
5
  const fs = require('node:fs');
5
6
  const os = require('node:os');
6
7
  const path = require('node:path');
8
+ const zlib = require('node:zlib');
7
9
  const { createRequire } = require('node:module');
8
10
 
9
11
  const PACKAGE_PREFIX = '@geminilight/mindos-';
10
12
  const LINUX_MUSL_EXAMPLE = 'linux-x64-musl';
13
+ const DEFAULT_RUNTIME_MANIFEST_URL = 'https://github.com/GeminiLight/MindOS/releases/download/runtime-latest/latest.json';
14
+ const MAX_MANIFEST_BYTES = 256 * 1024;
15
+ const MAX_RUNTIME_BYTES = 512 * 1024 * 1024;
11
16
  const scriptPath = fs.realpathSync(__filename);
12
17
  const scriptDir = path.dirname(scriptPath);
13
18
  const packageRoot = path.resolve(scriptDir, '..');
@@ -131,14 +136,16 @@ function runEntrypoint(entrypoint) {
131
136
  }
132
137
 
133
138
  function findRuntimeEntrypoint() {
134
- for (const packageName of platformPackageCandidates()) {
135
- const packageDir = findRuntimePackageByRequire(packageName)
136
- || findRuntimePackageByWalking(packageName)
137
- || findRuntimePackageInSourceTree(packageName);
138
- if (!packageDir) continue;
139
+ if (process.env.MINDOS_DISABLE_PLATFORM_PACKAGE_LOOKUP !== '1') {
140
+ for (const packageName of platformPackageCandidates()) {
141
+ const packageDir = findRuntimePackageByRequire(packageName)
142
+ || findRuntimePackageByWalking(packageName)
143
+ || findRuntimePackageInSourceTree(packageName);
144
+ if (!packageDir) continue;
139
145
 
140
- const entrypoint = runtimeEntrypoint(packageDir);
141
- if (entrypoint) return entrypoint;
146
+ const entrypoint = runtimeEntrypoint(packageDir);
147
+ if (entrypoint) return entrypoint;
148
+ }
142
149
  }
143
150
 
144
151
  const legacyCli = path.join(packageRoot, 'bin', 'cli.js');
@@ -147,6 +154,9 @@ function findRuntimeEntrypoint() {
147
154
  return { type: 'node', path: legacyCli };
148
155
  }
149
156
 
157
+ const downloaded = resolveDownloadedRuntimeEntrypoint();
158
+ if (downloaded) return downloaded;
159
+
150
160
  return null;
151
161
  }
152
162
 
@@ -162,3 +172,304 @@ if (!entrypoint) {
162
172
  }
163
173
 
164
174
  runEntrypoint(entrypoint);
175
+
176
+ function resolveDownloadedRuntimeEntrypoint() {
177
+ if (process.env.MINDOS_DISABLE_RUNTIME_DOWNLOAD === '1') return null;
178
+
179
+ const cachedEntrypoint = findCachedRuntimeEntrypoint(productVersion());
180
+ if (cachedEntrypoint) return cachedEntrypoint;
181
+
182
+ let manifest;
183
+ try {
184
+ manifest = readRuntimeManifest();
185
+ } catch (err) {
186
+ const offlineCachedEntrypoint = findCachedRuntimeEntrypoint();
187
+ if (offlineCachedEntrypoint) return offlineCachedEntrypoint;
188
+ if (process.env.MINDOS_RUNTIME_MANIFEST_URL) {
189
+ console.error(`Failed to read MindOS runtime manifest: ${errorMessage(err)}`);
190
+ }
191
+ return null;
192
+ }
193
+
194
+ const version = safeRuntimeVersion(manifest.version);
195
+ const cacheRoot = runtimeCacheRoot();
196
+ const runtimeRoot = path.join(cacheRoot, version);
197
+ const cached = runtimeEntrypoint(runtimeRoot);
198
+ if (cached) return cached;
199
+
200
+ try {
201
+ fs.mkdirSync(cacheRoot, { recursive: true });
202
+ const tempRoot = path.join(cacheRoot, `.download-${version}-${process.pid}-${Date.now()}`);
203
+ fs.rmSync(tempRoot, { recursive: true, force: true });
204
+ fs.mkdirSync(tempRoot, { recursive: true });
205
+
206
+ const archive = downloadRuntimeArchive(manifest);
207
+ extractRuntimeArchive(archive, tempRoot);
208
+ const entrypoint = runtimeEntrypoint(tempRoot);
209
+ if (!entrypoint) {
210
+ throw new Error('downloaded runtime archive does not contain bin/cli.js or bin/mindos');
211
+ }
212
+
213
+ fs.rmSync(runtimeRoot, { recursive: true, force: true });
214
+ fs.renameSync(tempRoot, runtimeRoot);
215
+ return runtimeEntrypoint(runtimeRoot);
216
+ } catch (err) {
217
+ console.error(`Failed to install MindOS runtime fallback: ${errorMessage(err)}`);
218
+ return null;
219
+ }
220
+ }
221
+
222
+ function runtimeCacheRoot() {
223
+ return path.resolve(process.env.MINDOS_RUNTIME_CACHE_DIR || path.join(os.homedir(), '.mindos', 'runtime-cache'));
224
+ }
225
+
226
+ function productVersion() {
227
+ try {
228
+ const pkg = JSON.parse(fs.readFileSync(path.join(packageRoot, 'package.json'), 'utf-8'));
229
+ return typeof pkg.version === 'string' ? pkg.version : null;
230
+ } catch {
231
+ return null;
232
+ }
233
+ }
234
+
235
+ function findCachedRuntimeEntrypoint(version) {
236
+ const cacheRoot = runtimeCacheRoot();
237
+ let entries;
238
+ try {
239
+ entries = fs.readdirSync(cacheRoot, { withFileTypes: true });
240
+ } catch {
241
+ return null;
242
+ }
243
+
244
+ return entries
245
+ .filter((entry) => entry.isDirectory() && !entry.name.startsWith('.download-'))
246
+ .filter((entry) => !version || entry.name === version)
247
+ .map((entry) => {
248
+ const root = path.join(cacheRoot, entry.name);
249
+ const entrypoint = runtimeEntrypoint(root);
250
+ if (!entrypoint) return null;
251
+ let mtimeMs = 0;
252
+ try { mtimeMs = fs.statSync(root).mtimeMs; } catch {}
253
+ return { entrypoint, mtimeMs };
254
+ })
255
+ .filter(Boolean)
256
+ .sort((a, b) => b.mtimeMs - a.mtimeMs)[0]?.entrypoint || null;
257
+ }
258
+
259
+ function readRuntimeManifest() {
260
+ const manifestUrl = process.env.MINDOS_RUNTIME_MANIFEST_URL || DEFAULT_RUNTIME_MANIFEST_URL;
261
+ const body = requestBuffer(manifestUrl, { maxBytes: MAX_MANIFEST_BYTES, timeoutMs: 30_000 });
262
+ const manifest = JSON.parse(body.toString('utf-8'));
263
+ if (!manifest || typeof manifest !== 'object') throw new Error('manifest is not an object');
264
+ if (typeof manifest.version !== 'string') throw new Error('manifest.version must be a string');
265
+ if (!Array.isArray(manifest.urls) || manifest.urls.some((url) => typeof url !== 'string')) {
266
+ throw new Error('manifest.urls must be a string array');
267
+ }
268
+ return manifest;
269
+ }
270
+
271
+ function safeRuntimeVersion(value) {
272
+ if (!/^[0-9A-Za-z._-]+$/.test(value)) {
273
+ throw new Error(`unsafe runtime version in manifest: ${value}`);
274
+ }
275
+ return value;
276
+ }
277
+
278
+ function downloadRuntimeArchive(manifest) {
279
+ let lastError;
280
+ for (const url of manifest.urls) {
281
+ try {
282
+ const archive = requestBuffer(url, { maxBytes: MAX_RUNTIME_BYTES, timeoutMs: 120_000 });
283
+ if (typeof manifest.size === 'number' && manifest.size > 0 && archive.length !== manifest.size) {
284
+ throw new Error(`runtime archive size mismatch: got ${archive.length}, expected ${manifest.size}`);
285
+ }
286
+ if (typeof manifest.sha256 === 'string' && manifest.sha256) {
287
+ const actual = crypto.createHash('sha256').update(archive).digest('hex');
288
+ if (actual !== manifest.sha256) {
289
+ throw new Error(`runtime archive sha256 mismatch: got ${actual}, expected ${manifest.sha256}`);
290
+ }
291
+ }
292
+ return archive;
293
+ } catch (err) {
294
+ lastError = err;
295
+ }
296
+ }
297
+ throw lastError || new Error('manifest did not include a runtime archive URL');
298
+ }
299
+
300
+ function requestBuffer(urlString, options, redirectCount = 0) {
301
+ if (redirectCount > 5) throw new Error(`too many redirects while fetching ${urlString}`);
302
+ const url = new URL(urlString);
303
+ if (url.protocol === 'file:') {
304
+ const file = fs.readFileSync(url);
305
+ if (file.length > options.maxBytes) {
306
+ throw new Error(`file response exceeded byte limit: ${urlString}`);
307
+ }
308
+ return file;
309
+ }
310
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
311
+ throw new Error(`unsupported URL protocol: ${url.protocol}`);
312
+ }
313
+
314
+ const result = childProcess.spawnSync(process.execPath, [
315
+ '-e',
316
+ `
317
+ const http = require('node:http');
318
+ const https = require('node:https');
319
+ const url = new URL(process.argv[1]);
320
+ const maxBytes = Number(process.argv[2]);
321
+ const timeoutMs = Number(process.argv[3]);
322
+ const client = url.protocol === 'http:' ? http : https;
323
+ const req = client.get(url, { timeout: timeoutMs }, (res) => {
324
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
325
+ process.stdout.write(JSON.stringify({ redirect: new URL(res.headers.location, url).toString() }));
326
+ res.resume();
327
+ return;
328
+ }
329
+ if (res.statusCode !== 200) {
330
+ console.error('HTTP ' + res.statusCode + ' while fetching ' + url);
331
+ res.resume();
332
+ process.exitCode = 2;
333
+ return;
334
+ }
335
+ const chunks = [];
336
+ let size = 0;
337
+ res.on('data', (chunk) => {
338
+ size += chunk.length;
339
+ if (size > maxBytes) {
340
+ console.error('response exceeded byte limit');
341
+ req.destroy();
342
+ process.exitCode = 3;
343
+ return;
344
+ }
345
+ chunks.push(chunk);
346
+ });
347
+ res.on('end', () => process.stdout.write(Buffer.concat(chunks)));
348
+ });
349
+ req.on('timeout', () => req.destroy(new Error('request timed out')));
350
+ req.on('error', (err) => {
351
+ console.error(err.message);
352
+ process.exitCode = process.exitCode || 1;
353
+ });
354
+ `,
355
+ url.toString(),
356
+ String(options.maxBytes),
357
+ String(options.timeoutMs),
358
+ ], {
359
+ encoding: 'buffer',
360
+ maxBuffer: options.maxBytes + 1024,
361
+ });
362
+
363
+ if (result.error) throw result.error;
364
+ if (result.status !== 0) {
365
+ throw new Error(result.stderr.toString('utf-8').trim() || `request failed for ${urlString}`);
366
+ }
367
+
368
+ try {
369
+ const redirect = JSON.parse(result.stdout.toString('utf-8'));
370
+ if (redirect && typeof redirect.redirect === 'string') {
371
+ return requestBuffer(redirect.redirect, options, redirectCount + 1);
372
+ }
373
+ } catch {
374
+ // Binary responses and normal JSON manifests are returned as-is.
375
+ }
376
+
377
+ return result.stdout;
378
+ }
379
+
380
+ function extractRuntimeArchive(archive, targetRoot) {
381
+ const tar = zlib.gunzipSync(archive);
382
+ let offset = 0;
383
+ let nextPax = {};
384
+
385
+ while (offset + 512 <= tar.length) {
386
+ const header = tar.subarray(offset, offset + 512);
387
+ offset += 512;
388
+ if (isZeroBlock(header)) break;
389
+
390
+ const typeflag = String.fromCharCode(header[156] || 0);
391
+ const size = parseOctal(header, 124, 12);
392
+ const rawName = nextPax.path || tarName(header);
393
+ nextPax = {};
394
+ const data = tar.subarray(offset, offset + size);
395
+ offset += Math.ceil(size / 512) * 512;
396
+
397
+ if (typeflag === 'x' || typeflag === 'g') {
398
+ nextPax = parsePax(data);
399
+ continue;
400
+ }
401
+
402
+ if (!rawName || rawName === '.' || rawName === './') continue;
403
+ const dest = safeArchivePath(targetRoot, rawName);
404
+
405
+ if (typeflag === '5') {
406
+ fs.mkdirSync(dest, { recursive: true });
407
+ continue;
408
+ }
409
+
410
+ if (typeflag === '0' || typeflag === '\0') {
411
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
412
+ fs.writeFileSync(dest, data);
413
+ const mode = parseOctal(header, 100, 8);
414
+ if ((mode & 0o111) !== 0) fs.chmodSync(dest, mode & 0o777);
415
+ }
416
+ }
417
+ }
418
+
419
+ function safeArchivePath(targetRoot, archiveName) {
420
+ const normalized = path.normalize(archiveName.replace(/^\.\/+/, ''));
421
+ if (!normalized || normalized === '.' || path.isAbsolute(normalized) || normalized.startsWith('..' + path.sep) || normalized === '..') {
422
+ throw new Error(`unsafe runtime archive path: ${archiveName}`);
423
+ }
424
+ const dest = path.resolve(targetRoot, normalized);
425
+ const rootWithSep = path.resolve(targetRoot) + path.sep;
426
+ if (dest !== path.resolve(targetRoot) && !dest.startsWith(rootWithSep)) {
427
+ throw new Error(`runtime archive path escapes target root: ${archiveName}`);
428
+ }
429
+ return dest;
430
+ }
431
+
432
+ function tarName(header) {
433
+ const name = readNullTerminated(header, 0, 100);
434
+ const prefix = readNullTerminated(header, 345, 155);
435
+ return prefix ? `${prefix}/${name}` : name;
436
+ }
437
+
438
+ function readNullTerminated(buffer, start, length) {
439
+ const slice = buffer.subarray(start, start + length);
440
+ const end = slice.indexOf(0);
441
+ return slice.subarray(0, end === -1 ? slice.length : end).toString('utf-8');
442
+ }
443
+
444
+ function parseOctal(buffer, start, length) {
445
+ const raw = readNullTerminated(buffer, start, length).trim();
446
+ return raw ? Number.parseInt(raw, 8) : 0;
447
+ }
448
+
449
+ function parsePax(buffer) {
450
+ const text = buffer.toString('utf-8');
451
+ const out = {};
452
+ let index = 0;
453
+ while (index < text.length) {
454
+ const space = text.indexOf(' ', index);
455
+ if (space === -1) break;
456
+ const length = Number.parseInt(text.slice(index, space), 10);
457
+ if (!Number.isFinite(length) || length <= 0) break;
458
+ const record = text.slice(space + 1, index + length - 1);
459
+ const eq = record.indexOf('=');
460
+ if (eq > 0) out[record.slice(0, eq)] = record.slice(eq + 1);
461
+ index += length;
462
+ }
463
+ return out;
464
+ }
465
+
466
+ function isZeroBlock(buffer) {
467
+ for (const byte of buffer) {
468
+ if (byte !== 0) return false;
469
+ }
470
+ return true;
471
+ }
472
+
473
+ function errorMessage(err) {
474
+ return err && typeof err.message === 'string' ? err.message : String(err);
475
+ }
@@ -4,7 +4,7 @@
4
4
  * Product runtime owns these prompts. Web, headless mode, and future Product
5
5
  * Server ask runtime should import them from @geminilight/mindos/agent.
6
6
  */
7
- export declare const AGENT_SYSTEM_PROMPT = "You are MindOS \u2014 the user's local knowledge assistant.\n\nPersona: Warm yet precise, reliable, execution-oriented. Like a trusted notebook that understands you \u2014 quiet confidence, zero fluff. Be professional but never cold; be helpful but never verbose.\n\n## Self-Introduction\n\nWhen the user sends a pure greeting (\"\u4F60\u597D\", \"hi\", etc.) or asks who you are / what you can do, introduce yourself briefly:\n\n- Who: MindOS, their local knowledge assistant.\n- What: You can read files, search notes, organize material, capture decisions and preferences, and turn scattered context into reusable knowledge.\n- Tone: Natural, warm, concise. One short paragraph, then invite them to try something practical \u2014 e.g., \"\u4F60\u53EF\u4EE5\u76F4\u63A5\u8BA9\u6211\u8BFB\u6587\u4EF6\u3001\u627E\u7B14\u8BB0\u3001\u8BB0\u5F55\u51B3\u5B9A\uFF0C\u6216\u8005\u6574\u7406\u521A\u4E0A\u4F20\u7684\u6750\u6599\u3002\"\n- Do NOT use slogan-like phrasing such as \"operator of your second brain\" or repetitive identity statements.\n- If the user's message already contains a concrete task \u2014 even if it starts with a greeting \u2014 skip the self-introduction and do the task directly.\n\n## Core Directives\n\n1. **Anti-Hallucination**: Strictly separate your training data from the user's local knowledge. If asked about the user's notes/life/projects, rely EXCLUSIVELY on tool outputs. If a search yields nothing, state \"Not found in knowledge base.\" NEVER fabricate or infer missing data.\n2. **Think Before Acting**: For any non-trivial task, use a brief `<thinking>` block to outline your plan or analyze an error BEFORE calling tools.\n3. **Read Before Write**: You MUST read a file before modifying it. Prefer precise section/line edits over full overwrites. Verify edits by reading again.\n4. **Cite Sources**: Always include the exact file path when answering from local knowledge so the user can verify.\n5. **Smart Recovery**: If a tool fails (e.g. File Not Found), do NOT retry identical arguments. Use `search` or `list_files` to find the correct path first.\n6. **Token Efficiency**: Batch parallel independent tool calls in a single turn. Do not waste rounds.\n7. **Language Alignment**: Match the language of the file when writing, and match the user's language when replying.\n\n## Context Mechanics\n\n- **Auto-loaded**: Configs, instructions, and SKILL.md are already in your context. Do not search for them unless explicitly asked.\n- **Uploaded Files**: Local files attached by the user appear in the \"\u26A0\uFE0F USER-UPLOADED FILES\" section below. Use this content directly. Do NOT use tools to read/search them.\n- **Web Search**: When the user asks to search, look up, or find information online, ALWAYS use `web_search` first to discover relevant URLs. Do NOT guess URLs or use `fetch_content` directly \u2014 search first, then fetch specific results.\n- **Skills**: Available skills are listed at the end of this prompt. Use the load_skill tool to load a skill's full content when a task matches its description.\n- **MCP**: Use the mcp tool to search, describe, and call MCP tools from external servers configured in ~/.mindos/mcp.json.\n\n## Output\n\n- Reply in the user's language.\n- Use clean Markdown (tables, lists, bold).\n- End with concrete next actions if the task is incomplete.";
7
+ export declare const AGENT_SYSTEM_PROMPT = "You are MindOS \u2014 the user's local knowledge assistant.\n\nPersona: Warm yet precise, reliable, execution-oriented. Like a trusted notebook that understands you \u2014 quiet confidence, zero fluff. Be professional but never cold; be helpful but never verbose.\n\n## Self-Introduction\n\nWhen the user sends a pure greeting (\"\u4F60\u597D\", \"hi\", etc.) or asks who you are / what you can do, introduce yourself briefly:\n\n- Who: MindOS, their local knowledge assistant.\n- What: You can read files, search notes, organize material, capture decisions and preferences, and turn scattered context into reusable knowledge.\n- Tone: Natural, warm, concise. One short paragraph, then invite them to try something practical \u2014 e.g., \"\u4F60\u53EF\u4EE5\u76F4\u63A5\u8BA9\u6211\u8BFB\u6587\u4EF6\u3001\u627E\u7B14\u8BB0\u3001\u8BB0\u5F55\u51B3\u5B9A\uFF0C\u6216\u8005\u6574\u7406\u521A\u4E0A\u4F20\u7684\u6750\u6599\u3002\"\n- Do NOT use slogan-like phrasing such as \"operator of your second brain\" or repetitive identity statements.\n- If the user's message already contains a concrete task \u2014 even if it starts with a greeting \u2014 skip the self-introduction and do the task directly.\n\n## Core Directives\n\n1. **Anti-Hallucination**: Strictly separate your training data from the user's local knowledge. If asked about the user's notes/life/projects, rely EXCLUSIVELY on tool outputs. If a search yields nothing, state \"Not found in knowledge base.\" NEVER fabricate or infer missing data.\n2. **Think Before Acting**: For any non-trivial task, use a brief `<thinking>` block to outline your plan or analyze an error BEFORE calling tools.\n3. **Read Before Write**: You MUST read a file before modifying it. Prefer precise section/line edits over full overwrites. Verify edits by reading again.\n4. **Cite Sources**: Always include the exact file path when answering from local knowledge so the user can verify.\n5. **Smart Recovery**: If a tool fails (e.g. File Not Found), do NOT retry identical arguments. Use `search` or `list_files` to find the correct path first.\n6. **Token Efficiency**: Batch parallel independent tool calls in a single turn. Do not waste rounds.\n7. **Language Alignment**: Match the language of the file when writing, and match the user's language when replying.\n\n## Delegation / Subagents\n\n- The `subagent` tool is MindOS Agent's internal delegation tool. It is separate from ACP runtimes, A2A agents, and the user's selected Codex / Claude Code chat runtime.\n- Use `subagent` when the work is complex and separable: independent code review, research, verification, multi-file audit, or comparing options. Keep trivial or tightly coupled work in the main thread.\n- If you are not sure which subagents exist, call `subagent` with `action: \"list\"` first. Use `action: \"status\"` / `action: \"resume\"` only for existing subagent runs.\n- For each delegated task, provide a bounded task, clear acceptance criteria, relevant cwd/files, and the evidence you need back. Run tasks in parallel only when they are independent.\n- Do not use subagents to bypass mode, permission, or confirmation boundaries. Chat/read-only expectations, protected files, destructive operations, and user-confirmation requirements still apply.\n\n## Structured Clarification\n\n- Use `ask_user_question` when the user's request is underspecified and the answer changes what you should do. Prefer one structured question card over a vague free-form clarification.\n- Group related questions into one `ask_user_question` call. Do not stack multiple clarification calls back-to-back.\n- Do not ask about trivial choices you can safely infer. Ask before writing files, choosing among meaningfully different implementation directions, or taking a high-risk action when user intent is unclear.\n\n## Context Mechanics\n\n- **Auto-loaded**: Configs, instructions, and SKILL.md are already in your context. Do not search for them unless explicitly asked.\n- **Uploaded Files**: Local files attached by the user appear in the \"\u26A0\uFE0F USER-UPLOADED FILES\" section below. Use this content directly. Do NOT use tools to read/search them.\n- **Web Search**: When the user asks to search, look up, or find information online, ALWAYS use `web_search` first to discover relevant URLs. Do NOT guess URLs or use `fetch_content` directly \u2014 search first, then fetch specific results.\n- **Skills**: Available skills are listed at the end of this prompt. Use the load_skill tool to load a skill's full content when a task matches its description.\n- **MCP**: Use the mcp tool to search, describe, and call MCP tools from external servers configured in ~/.mindos/mcp.json.\n\n## Output\n\n- Reply in the user's language.\n- Use clean Markdown (tables, lists, bold).\n- End with concrete next actions if the task is incomplete.";
8
8
  /**
9
9
  * Chat mode system prompt — read-only tools, no write operations.
10
10
  */
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/agent/prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,gxGAoC4B,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,kBAAkB,m2CAoB6B,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,sBAAsB,g8BAWoC,CAAC"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/agent/prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,mvJAkD4B,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,kBAAkB,m2CAoB6B,CAAC;AAE7D;;GAEG;AACH,eAAO,MAAM,sBAAsB,g8BAWoC,CAAC"}
@@ -28,6 +28,20 @@ When the user sends a pure greeting ("你好", "hi", etc.) or asks who you are /
28
28
  6. **Token Efficiency**: Batch parallel independent tool calls in a single turn. Do not waste rounds.
29
29
  7. **Language Alignment**: Match the language of the file when writing, and match the user's language when replying.
30
30
 
31
+ ## Delegation / Subagents
32
+
33
+ - The \`subagent\` tool is MindOS Agent's internal delegation tool. It is separate from ACP runtimes, A2A agents, and the user's selected Codex / Claude Code chat runtime.
34
+ - Use \`subagent\` when the work is complex and separable: independent code review, research, verification, multi-file audit, or comparing options. Keep trivial or tightly coupled work in the main thread.
35
+ - If you are not sure which subagents exist, call \`subagent\` with \`action: "list"\` first. Use \`action: "status"\` / \`action: "resume"\` only for existing subagent runs.
36
+ - For each delegated task, provide a bounded task, clear acceptance criteria, relevant cwd/files, and the evidence you need back. Run tasks in parallel only when they are independent.
37
+ - Do not use subagents to bypass mode, permission, or confirmation boundaries. Chat/read-only expectations, protected files, destructive operations, and user-confirmation requirements still apply.
38
+
39
+ ## Structured Clarification
40
+
41
+ - Use \`ask_user_question\` when the user's request is underspecified and the answer changes what you should do. Prefer one structured question card over a vague free-form clarification.
42
+ - Group related questions into one \`ask_user_question\` call. Do not stack multiple clarification calls back-to-back.
43
+ - Do not ask about trivial choices you can safely infer. Ask before writing files, choosing among meaningfully different implementation directions, or taking a high-risk action when user intent is unclear.
44
+
31
45
  ## Context Mechanics
32
46
 
33
47
  - **Auto-loaded**: Configs, instructions, and SKILL.md are already in your context. Do not search for them unless explicitly asked.
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/agent/prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DAoCyB,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;4DAoB0B,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;uEAWiC,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/agent/prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4DAkDyB,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;;;;;4DAoB0B,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;uEAWiC,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { type MindOSSSEvent } from '../session/index.js';
2
+ export type ClaudeCodeCliTransport = {
3
+ run(args: string[], options: {
4
+ cwd: string;
5
+ signal?: AbortSignal;
6
+ }): AsyncIterable<string>;
7
+ close?(): void | Promise<void>;
8
+ };
9
+ export type ClaudeCodeCliPermissionPrompt = {
10
+ toolName: string;
11
+ mcpConfig: string | Record<string, unknown>;
12
+ };
13
+ export type ClaudeCodeCliPermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan' | 'dontAsk' | 'auto';
14
+ export type ClaudeCodeCliClient = {
15
+ startTurn(input: {
16
+ prompt: string;
17
+ cwd: string;
18
+ sessionId?: string;
19
+ permissionMode?: ClaudeCodeCliPermissionMode;
20
+ permissionPrompt?: ClaudeCodeCliPermissionPrompt;
21
+ signal?: AbortSignal;
22
+ }): AsyncIterable<ClaudeCodeCliEvent>;
23
+ close?(): void | Promise<void>;
24
+ };
25
+ export type ClaudeCodeCliEvent = {
26
+ type: 'session_id';
27
+ sessionId: string;
28
+ } | MindOSSSEvent;
29
+ export declare function createClaudeCodeCliClient(transport: ClaudeCodeCliTransport): ClaudeCodeCliClient;
30
+ export declare function createClaudeCodeCliStdioTransport(options?: {
31
+ command?: string;
32
+ env?: NodeJS.ProcessEnv;
33
+ }): ClaudeCodeCliTransport;
34
+ //# sourceMappingURL=claude-code-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code-cli.d.ts","sourceRoot":"","sources":["../../src/agent-runtime/claude-code-cli.ts"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,MAAM,sBAAsB,GAAG;IACnC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3F,KAAK,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG,SAAS,GAAG,aAAa,GAAG,mBAAmB,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC;AAExH,MAAM,MAAM,mBAAmB,GAAG;IAChC,SAAS,CAAC,KAAK,EAAE;QACf,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;QACZ,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,cAAc,CAAC,EAAE,2BAA2B,CAAC;QAC7C,gBAAgB,CAAC,EAAE,6BAA6B,CAAC;QACjD,MAAM,CAAC,EAAE,WAAW,CAAC;KACtB,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAAC;IACtC,KAAK,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzC,aAAa,CAAC;AAOlB,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,sBAAsB,GAAG,mBAAmB,CA6BhG;AAED,wBAAgB,iCAAiC,CAAC,OAAO,GAAE;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACpB,GAAG,sBAAsB,CAqD9B"}