@leterhong/multichat 1.6.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 (214) hide show
  1. package/.agents/plugins/marketplace.json +32 -0
  2. package/.agents/plugins/plugins/developer-toolkit/.codex-plugin/plugin.json +24 -0
  3. package/.agents/plugins/plugins/developer-toolkit/skills/code-review/SKILL.md +9 -0
  4. package/.agents/plugins/plugins/developer-toolkit/skills/code-review/agents/openai.yaml +3 -0
  5. package/.agents/plugins/plugins/developer-toolkit/skills/release-notes/SKILL.md +9 -0
  6. package/.agents/plugins/plugins/developer-toolkit/skills/release-notes/agents/openai.yaml +3 -0
  7. package/.agents/plugins/plugins/developer-toolkit/skills/security-review/SKILL.md +9 -0
  8. package/.agents/plugins/plugins/developer-toolkit/skills/security-review/agents/openai.yaml +3 -0
  9. package/.agents/plugins/plugins/developer-toolkit/skills/test-plan/SKILL.md +9 -0
  10. package/.agents/plugins/plugins/developer-toolkit/skills/test-plan/agents/openai.yaml +3 -0
  11. package/.agents/plugins/plugins/writing-toolkit/.codex-plugin/plugin.json +24 -0
  12. package/.agents/plugins/plugins/writing-toolkit/skills/meeting-notes/SKILL.md +9 -0
  13. package/.agents/plugins/plugins/writing-toolkit/skills/meeting-notes/agents/openai.yaml +3 -0
  14. package/.agents/plugins/plugins/writing-toolkit/skills/resume-tune/SKILL.md +9 -0
  15. package/.agents/plugins/plugins/writing-toolkit/skills/resume-tune/agents/openai.yaml +3 -0
  16. package/.agents/plugins/plugins/writing-toolkit/skills/weekly-report/SKILL.md +9 -0
  17. package/.agents/plugins/plugins/writing-toolkit/skills/weekly-report/agents/openai.yaml +3 -0
  18. package/.agents/skills/.gitkeep +1 -0
  19. package/.agents/skills/wanghong-handwritten-ppt/SKILL.md +172 -0
  20. package/.agents/skills/wanghong-handwritten-ppt/assets/HTML-PPT-LICENSE +21 -0
  21. package/.agents/skills/wanghong-handwritten-ppt/assets/NEAT-ANNOTATIONS-LICENSE +21 -0
  22. package/.agents/skills/wanghong-handwritten-ppt/assets/animations.css +138 -0
  23. package/.agents/skills/wanghong-handwritten-ppt/assets/base.css +150 -0
  24. package/.agents/skills/wanghong-handwritten-ppt/assets/deepseek-example.css +893 -0
  25. package/.agents/skills/wanghong-handwritten-ppt/assets/neat-annotations.css +152 -0
  26. package/.agents/skills/wanghong-handwritten-ppt/assets/preview-cover.png +0 -0
  27. package/.agents/skills/wanghong-handwritten-ppt/assets/preview-diagram.png +0 -0
  28. package/.agents/skills/wanghong-handwritten-ppt/assets/preview-summary.png +0 -0
  29. package/.agents/skills/wanghong-handwritten-ppt/assets/preview-table.png +0 -0
  30. package/.agents/skills/wanghong-handwritten-ppt/assets/runtime.js +960 -0
  31. package/.agents/skills/wanghong-handwritten-ppt/assets/template.css +198 -0
  32. package/.agents/skills/wanghong-handwritten-ppt/evals/evals.json +20 -0
  33. package/.agents/skills/wanghong-handwritten-ppt/examples/deepseek-v4-flash/index.html +414 -0
  34. package/.agents/skills/wanghong-handwritten-ppt/examples/deepseek-v4-flash/style.css +897 -0
  35. package/.agents/skills/wanghong-handwritten-ppt/references/prompts.md +170 -0
  36. package/.agents/skills/wanghong-handwritten-ppt/references/style-guide.md +133 -0
  37. package/.agents/skills/wanghong-handwritten-ppt/scripts/check_deck.py +41 -0
  38. package/.agents/skills/wanghong-handwritten-ppt/scripts/prepare_render_html.py +137 -0
  39. package/.agents/skills/wanghong-handwritten-ppt/scripts/render.sh +110 -0
  40. package/.agents/skills/wanghong-handwritten-ppt/templates/deck.html +94 -0
  41. package/.agents/skills/wanghong-handwritten-ppt/tests/test_font_contract.py +73 -0
  42. package/LICENSE +21 -0
  43. package/README.md +186 -0
  44. package/backend/adapters/README.md +77 -0
  45. package/backend/adapters/anthropic.ts +115 -0
  46. package/backend/adapters/base.ts +47 -0
  47. package/backend/adapters/index.ts +41 -0
  48. package/backend/adapters/lmstudio.ts +7 -0
  49. package/backend/adapters/moonshot.ts +7 -0
  50. package/backend/adapters/ollama.ts +7 -0
  51. package/backend/adapters/openai-compatible.ts +51 -0
  52. package/backend/adapters/openai.ts +7 -0
  53. package/backend/adapters/qwen.ts +112 -0
  54. package/backend/adapters/wenxin.ts +136 -0
  55. package/backend/adapters/zhipu.ts +93 -0
  56. package/backend/dist/adapters/anthropic.js +130 -0
  57. package/backend/dist/adapters/anthropic.js.map +1 -0
  58. package/backend/dist/adapters/base.js +38 -0
  59. package/backend/dist/adapters/base.js.map +1 -0
  60. package/backend/dist/adapters/index.js +39 -0
  61. package/backend/dist/adapters/index.js.map +1 -0
  62. package/backend/dist/adapters/lmstudio.js +8 -0
  63. package/backend/dist/adapters/lmstudio.js.map +1 -0
  64. package/backend/dist/adapters/moonshot.js +8 -0
  65. package/backend/dist/adapters/moonshot.js.map +1 -0
  66. package/backend/dist/adapters/ollama.js +8 -0
  67. package/backend/dist/adapters/ollama.js.map +1 -0
  68. package/backend/dist/adapters/openai-compatible.js +47 -0
  69. package/backend/dist/adapters/openai-compatible.js.map +1 -0
  70. package/backend/dist/adapters/openai.js +8 -0
  71. package/backend/dist/adapters/openai.js.map +1 -0
  72. package/backend/dist/adapters/qwen.js +103 -0
  73. package/backend/dist/adapters/qwen.js.map +1 -0
  74. package/backend/dist/adapters/wenxin.js +114 -0
  75. package/backend/dist/adapters/wenxin.js.map +1 -0
  76. package/backend/dist/adapters/zhipu.js +86 -0
  77. package/backend/dist/adapters/zhipu.js.map +1 -0
  78. package/backend/dist/extensions/demo-mcp-server.js +75 -0
  79. package/backend/dist/extensions/demo-mcp-server.js.map +1 -0
  80. package/backend/dist/extensions/importer.js +828 -0
  81. package/backend/dist/extensions/importer.js.map +1 -0
  82. package/backend/dist/extensions/manager.js +1154 -0
  83. package/backend/dist/extensions/manager.js.map +1 -0
  84. package/backend/dist/lib/catalog.js +30 -0
  85. package/backend/dist/lib/catalog.js.map +1 -0
  86. package/backend/dist/lib/context.js +59 -0
  87. package/backend/dist/lib/context.js.map +1 -0
  88. package/backend/dist/lib/errors.js +75 -0
  89. package/backend/dist/lib/errors.js.map +1 -0
  90. package/backend/dist/lib/provider-store.js +116 -0
  91. package/backend/dist/lib/provider-store.js.map +1 -0
  92. package/backend/dist/lib/redact.js +11 -0
  93. package/backend/dist/lib/redact.js.map +1 -0
  94. package/backend/dist/lib/runtime-store.js +28 -0
  95. package/backend/dist/lib/runtime-store.js.map +1 -0
  96. package/backend/dist/lib/sqlite-store.js +218 -0
  97. package/backend/dist/lib/sqlite-store.js.map +1 -0
  98. package/backend/dist/lib/sse.js +46 -0
  99. package/backend/dist/lib/sse.js.map +1 -0
  100. package/backend/dist/lib/ssrf.js +131 -0
  101. package/backend/dist/lib/ssrf.js.map +1 -0
  102. package/backend/dist/lib/store.js +84 -0
  103. package/backend/dist/lib/store.js.map +1 -0
  104. package/backend/dist/lib/usage.js +219 -0
  105. package/backend/dist/lib/usage.js.map +1 -0
  106. package/backend/dist/lib/util.js +38 -0
  107. package/backend/dist/lib/util.js.map +1 -0
  108. package/backend/dist/lib/workspace-store.js +152 -0
  109. package/backend/dist/lib/workspace-store.js.map +1 -0
  110. package/backend/dist/mcp.js +429 -0
  111. package/backend/dist/mcp.js.map +1 -0
  112. package/backend/dist/routes/agents.js +51 -0
  113. package/backend/dist/routes/agents.js.map +1 -0
  114. package/backend/dist/routes/assistants.js +32 -0
  115. package/backend/dist/routes/assistants.js.map +1 -0
  116. package/backend/dist/routes/chat.js +697 -0
  117. package/backend/dist/routes/chat.js.map +1 -0
  118. package/backend/dist/routes/control-plane.js +200 -0
  119. package/backend/dist/routes/control-plane.js.map +1 -0
  120. package/backend/dist/routes/conversations.js +66 -0
  121. package/backend/dist/routes/conversations.js.map +1 -0
  122. package/backend/dist/routes/extensions-import.js +22 -0
  123. package/backend/dist/routes/extensions-import.js.map +1 -0
  124. package/backend/dist/routes/import.js +85 -0
  125. package/backend/dist/routes/import.js.map +1 -0
  126. package/backend/dist/routes/mcp-servers.js +56 -0
  127. package/backend/dist/routes/mcp-servers.js.map +1 -0
  128. package/backend/dist/routes/meta.js +37 -0
  129. package/backend/dist/routes/meta.js.map +1 -0
  130. package/backend/dist/routes/mock.js +28 -0
  131. package/backend/dist/routes/mock.js.map +1 -0
  132. package/backend/dist/routes/plugins.js +41 -0
  133. package/backend/dist/routes/plugins.js.map +1 -0
  134. package/backend/dist/routes/providers.js +197 -0
  135. package/backend/dist/routes/providers.js.map +1 -0
  136. package/backend/dist/routes/runs.js +57 -0
  137. package/backend/dist/routes/runs.js.map +1 -0
  138. package/backend/dist/routes/skills.js +73 -0
  139. package/backend/dist/routes/skills.js.map +1 -0
  140. package/backend/dist/routes/tools.js +40 -0
  141. package/backend/dist/routes/tools.js.map +1 -0
  142. package/backend/dist/routes/usage.js +14 -0
  143. package/backend/dist/routes/usage.js.map +1 -0
  144. package/backend/dist/routes/workspaces.js +158 -0
  145. package/backend/dist/routes/workspaces.js.map +1 -0
  146. package/backend/dist/runtime/agent.js +518 -0
  147. package/backend/dist/runtime/agent.js.map +1 -0
  148. package/backend/dist/server.js +103 -0
  149. package/backend/dist/server.js.map +1 -0
  150. package/backend/dist/types.js +3 -0
  151. package/backend/dist/types.js.map +1 -0
  152. package/backend/extensions/demo-mcp-server.js +70 -0
  153. package/backend/extensions/importer.ts +709 -0
  154. package/backend/extensions/manager.ts +1055 -0
  155. package/backend/lib/catalog.ts +28 -0
  156. package/backend/lib/context.ts +61 -0
  157. package/backend/lib/errors.ts +78 -0
  158. package/backend/lib/provider-store.ts +116 -0
  159. package/backend/lib/redact.ts +9 -0
  160. package/backend/lib/runtime-store.ts +38 -0
  161. package/backend/lib/sqlite-store.ts +220 -0
  162. package/backend/lib/sse.ts +42 -0
  163. package/backend/lib/ssrf.ts +120 -0
  164. package/backend/lib/store.ts +79 -0
  165. package/backend/lib/usage.ts +212 -0
  166. package/backend/lib/util.ts +31 -0
  167. package/backend/lib/workspace-store.ts +150 -0
  168. package/backend/mcp.ts +417 -0
  169. package/backend/package.json +34 -0
  170. package/backend/prompts.json +82 -0
  171. package/backend/routes/agents.ts +55 -0
  172. package/backend/routes/assistants.ts +30 -0
  173. package/backend/routes/chat.ts +660 -0
  174. package/backend/routes/control-plane.ts +165 -0
  175. package/backend/routes/conversations.ts +62 -0
  176. package/backend/routes/extensions-import.ts +15 -0
  177. package/backend/routes/import.ts +72 -0
  178. package/backend/routes/mcp-servers.ts +36 -0
  179. package/backend/routes/meta.ts +38 -0
  180. package/backend/routes/mock.ts +25 -0
  181. package/backend/routes/plugins.ts +27 -0
  182. package/backend/routes/providers.ts +166 -0
  183. package/backend/routes/runs.ts +55 -0
  184. package/backend/routes/skills.ts +52 -0
  185. package/backend/routes/tools.ts +40 -0
  186. package/backend/routes/usage.ts +13 -0
  187. package/backend/routes/workspaces.ts +124 -0
  188. package/backend/runtime/agent.ts +474 -0
  189. package/backend/server.ts +106 -0
  190. package/backend/types.ts +126 -0
  191. package/bin/multichat.mjs +535 -0
  192. package/frontend/dist/assets/agentPicker-C39VzmYa.js +13 -0
  193. package/frontend/dist/assets/compare-BpaGD32J.js +1 -0
  194. package/frontend/dist/assets/conversations-COuLmg99.js +7 -0
  195. package/frontend/dist/assets/data-ZH7Dux1K.js +1 -0
  196. package/frontend/dist/assets/extensionImport-CnTWKtWm.js +28 -0
  197. package/frontend/dist/assets/importExport-B3mB-9zs.js +70 -0
  198. package/frontend/dist/assets/index-CASVCOUO.js +34 -0
  199. package/frontend/dist/assets/index-DSvbjNLc.css +1 -0
  200. package/frontend/dist/assets/init-ZPK483vB.js +1 -0
  201. package/frontend/dist/assets/jsx-runtime-ZSsbr0oW.js +9 -0
  202. package/frontend/dist/assets/modal-CgHocv3n.js +2 -0
  203. package/frontend/dist/assets/modelPicker-EUmmVnbj.js +14 -0
  204. package/frontend/dist/assets/pluginsUI-B6jGUQkx.js +16 -0
  205. package/frontend/dist/assets/render-DgAg1K8A.js +1 -0
  206. package/frontend/dist/assets/send-BJhZ_5YA.js +14 -0
  207. package/frontend/dist/assets/settings-DdnYwZl-.js +2 -0
  208. package/frontend/dist/assets/shell-DFV2khQl.js +1 -0
  209. package/frontend/dist/assets/workbench-BY2J4vWC.js +41 -0
  210. package/frontend/dist/icon-maskable.svg +4 -0
  211. package/frontend/dist/icon.svg +4 -0
  212. package/frontend/dist/index.html +21 -0
  213. package/frontend/dist/manifest.webmanifest +26 -0
  214. package/package.json +58 -0
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { DatabaseSync } = require('node:sqlite');
6
+ function createSqliteStore(rootDir) {
7
+ fs.mkdirSync(rootDir, { recursive: true });
8
+ const databaseFile = path.join(rootDir, 'multichat.sqlite3');
9
+ const database = new DatabaseSync(databaseFile);
10
+ const chains = new Map();
11
+ database.exec(`
12
+ PRAGMA journal_mode = WAL;
13
+ PRAGMA synchronous = NORMAL;
14
+ PRAGMA busy_timeout = 5000;
15
+ CREATE TABLE IF NOT EXISTS kv_store (
16
+ name TEXT PRIMARY KEY,
17
+ value TEXT NOT NULL,
18
+ updated_at TEXT NOT NULL
19
+ );
20
+ CREATE TABLE IF NOT EXISTS store_meta (
21
+ key TEXT PRIMARY KEY,
22
+ value TEXT NOT NULL
23
+ );
24
+ `);
25
+ let ftsEnabled = false;
26
+ try {
27
+ database.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS search_fts USING fts5(
28
+ source UNINDEXED,
29
+ entity_id UNINDEXED,
30
+ project_id UNINDEXED,
31
+ title,
32
+ content,
33
+ tokenize='trigram'
34
+ );`);
35
+ ftsEnabled = true;
36
+ }
37
+ catch {
38
+ try {
39
+ database.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS search_fts USING fts5(
40
+ source UNINDEXED,
41
+ entity_id UNINDEXED,
42
+ project_id UNINDEXED,
43
+ title,
44
+ content
45
+ );`);
46
+ ftsEnabled = true;
47
+ }
48
+ catch {
49
+ database.exec(`
50
+ CREATE TABLE IF NOT EXISTS search_documents (
51
+ source TEXT NOT NULL,
52
+ entity_id TEXT NOT NULL,
53
+ project_id TEXT NOT NULL,
54
+ title TEXT NOT NULL,
55
+ content TEXT NOT NULL,
56
+ PRIMARY KEY(source, entity_id)
57
+ );
58
+ CREATE INDEX IF NOT EXISTS search_documents_project ON search_documents(project_id);
59
+ `);
60
+ }
61
+ }
62
+ const selectValue = database.prepare('SELECT value FROM kv_store WHERE name = ?');
63
+ const upsertValue = database.prepare(`
64
+ INSERT INTO kv_store(name, value, updated_at) VALUES (?, ?, ?)
65
+ ON CONFLICT(name) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at
66
+ `);
67
+ const deleteValue = database.prepare('DELETE FROM kv_store WHERE name = ?');
68
+ const migrationValue = database.prepare("SELECT value FROM store_meta WHERE key = 'json_migration_v1'");
69
+ function validName(name) {
70
+ if (typeof name !== 'string' || !name || path.basename(name) !== name)
71
+ throw new Error('invalid data file name');
72
+ return name;
73
+ }
74
+ function resolve(name) {
75
+ return path.join(rootDir, validName(name));
76
+ }
77
+ function importJsonFiles() {
78
+ if (migrationValue.get())
79
+ return;
80
+ database.exec('BEGIN IMMEDIATE');
81
+ try {
82
+ const names = fs.readdirSync(rootDir).filter((name) => name.endsWith('.json') && path.basename(name) === name);
83
+ for (const name of names) {
84
+ if (selectValue.get(name))
85
+ continue;
86
+ try {
87
+ const parsed = JSON.parse(fs.readFileSync(path.join(rootDir, name), 'utf8'));
88
+ upsertValue.run(name, JSON.stringify(parsed), new Date().toISOString());
89
+ }
90
+ catch {
91
+ // Corrupt legacy files remain untouched for manual recovery.
92
+ }
93
+ }
94
+ database.prepare("INSERT OR REPLACE INTO store_meta(key, value) VALUES ('json_migration_v1', ?)").run(new Date().toISOString());
95
+ database.exec('COMMIT');
96
+ }
97
+ catch (error) {
98
+ database.exec('ROLLBACK');
99
+ throw error;
100
+ }
101
+ }
102
+ function read(name, fallback) {
103
+ validName(name);
104
+ const row = selectValue.get(name);
105
+ if (!row?.value)
106
+ return fallback;
107
+ try {
108
+ return JSON.parse(row.value);
109
+ }
110
+ catch {
111
+ return fallback;
112
+ }
113
+ }
114
+ function reindex(source, value) {
115
+ if (!['assets.json', 'memories.json'].includes(source))
116
+ return;
117
+ const rows = Array.isArray(value) ? value : [];
118
+ const table = ftsEnabled ? 'search_fts' : 'search_documents';
119
+ const removeSource = database.prepare(`DELETE FROM ${table} WHERE source = ?`);
120
+ const insert = database.prepare(`INSERT INTO ${table}(source, entity_id, project_id, title, content) VALUES (?, ?, ?, ?, ?)`);
121
+ database.exec('SAVEPOINT reindex_source');
122
+ try {
123
+ removeSource.run(source);
124
+ for (const row of rows) {
125
+ if (!row?.id || !row?.content)
126
+ continue;
127
+ insert.run(source, String(row.id), String(row.projectId || ''), String(row.name || row.title || ''), String(row.content));
128
+ }
129
+ database.exec('RELEASE reindex_source');
130
+ }
131
+ catch (error) {
132
+ database.exec('ROLLBACK TO reindex_source');
133
+ database.exec('RELEASE reindex_source');
134
+ throw error;
135
+ }
136
+ }
137
+ function write(name, value) {
138
+ validName(name);
139
+ database.exec('BEGIN IMMEDIATE');
140
+ try {
141
+ upsertValue.run(name, JSON.stringify(value), new Date().toISOString());
142
+ reindex(name, value);
143
+ database.exec('COMMIT');
144
+ }
145
+ catch (error) {
146
+ database.exec('ROLLBACK');
147
+ throw error;
148
+ }
149
+ }
150
+ function remove(name) {
151
+ validName(name);
152
+ database.exec('BEGIN IMMEDIATE');
153
+ try {
154
+ deleteValue.run(name);
155
+ database.prepare(`DELETE FROM ${ftsEnabled ? 'search_fts' : 'search_documents'} WHERE source = ?`).run(name);
156
+ database.exec('COMMIT');
157
+ }
158
+ catch (error) {
159
+ database.exec('ROLLBACK');
160
+ throw error;
161
+ }
162
+ }
163
+ function mutate(name, update, fallback) {
164
+ const previous = chains.get(name) || Promise.resolve();
165
+ const run = previous
166
+ .then(() => update(read(name, fallback)))
167
+ .then((result) => {
168
+ if (result !== undefined)
169
+ write(name, result);
170
+ return result;
171
+ });
172
+ chains.set(name, run.then(() => { }, () => { }));
173
+ return run;
174
+ }
175
+ function searchDocuments(query, options = {}) {
176
+ const text = String(query || '').trim();
177
+ if (!text)
178
+ return [];
179
+ const projectId = String(options.projectId || '');
180
+ const limit = Math.max(1, Math.min(100, Number(options.limit) || 12));
181
+ const commonSelect = `SELECT source, entity_id AS entityId, project_id AS projectId, title,
182
+ snippet(search_fts, 4, '', '', ' … ', 56) AS snippet,
183
+ bm25(search_fts) AS rank FROM search_fts`;
184
+ try {
185
+ if (!ftsEnabled)
186
+ throw new Error('fts5 unavailable');
187
+ if ([...text].length >= 3) {
188
+ const phrase = `"${text.replace(/"/g, '""')}"`;
189
+ return database.prepare(`${commonSelect}
190
+ WHERE search_fts MATCH ? AND (? = '' OR project_id = ?)
191
+ ORDER BY rank LIMIT ?`).all(phrase, projectId, projectId, limit);
192
+ }
193
+ }
194
+ catch {
195
+ // Invalid FTS syntax and short queries use the bounded LIKE fallback.
196
+ }
197
+ const like = `%${text.replace(/[\\%_]/g, '\\$&')}%`;
198
+ return database.prepare(`SELECT source, entity_id AS entityId, project_id AS projectId, title,
199
+ substr(content, 1, 2400) AS snippet, 0 AS rank FROM ${ftsEnabled ? 'search_fts' : 'search_documents'}
200
+ WHERE (title LIKE ? ESCAPE '\\' OR content LIKE ? ESCAPE '\\') AND (? = '' OR project_id = ?)
201
+ LIMIT ?`).all(like, like, projectId, projectId, limit);
202
+ }
203
+ importJsonFiles();
204
+ reindex('assets.json', read('assets.json', []));
205
+ reindex('memories.json', read('memories.json', []));
206
+ return {
207
+ kind: 'sqlite',
208
+ read,
209
+ write,
210
+ remove,
211
+ resolve,
212
+ mutate,
213
+ searchDocuments,
214
+ close: () => database.close(),
215
+ };
216
+ }
217
+ module.exports = { createSqliteStore };
218
+ //# sourceMappingURL=sqlite-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-store.js","sourceRoot":"","sources":["../../lib/sqlite-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /** Incremental WHATWG-style SSE decoder for arbitrarily split byte chunks. */
4
+ class SSEDecoder {
5
+ buffer = '';
6
+ push(chunk) {
7
+ this.buffer += String(chunk || '').replace(/\r\n/g, '\n').replace(/\r/g, '\n');
8
+ const events = [];
9
+ let boundary = this.buffer.indexOf('\n\n');
10
+ while (boundary >= 0) {
11
+ const block = this.buffer.slice(0, boundary);
12
+ this.buffer = this.buffer.slice(boundary + 2);
13
+ const data = this.dataFrom(block);
14
+ if (data !== null)
15
+ events.push(`data: ${data}`);
16
+ boundary = this.buffer.indexOf('\n\n');
17
+ }
18
+ return events;
19
+ }
20
+ flush() {
21
+ const block = this.buffer;
22
+ this.buffer = '';
23
+ const data = this.dataFrom(block);
24
+ return data === null ? [] : [`data: ${data}`];
25
+ }
26
+ dataFrom(block) {
27
+ if (!block.trim())
28
+ return null;
29
+ const values = [];
30
+ for (const line of block.split('\n')) {
31
+ if (!line || line.startsWith(':'))
32
+ continue;
33
+ const separator = line.indexOf(':');
34
+ const field = separator < 0 ? line : line.slice(0, separator);
35
+ if (field !== 'data')
36
+ continue;
37
+ let value = separator < 0 ? '' : line.slice(separator + 1);
38
+ if (value.startsWith(' '))
39
+ value = value.slice(1);
40
+ values.push(value);
41
+ }
42
+ return values.length ? values.join('\n') : null;
43
+ }
44
+ }
45
+ module.exports = { SSEDecoder };
46
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../lib/sse.ts"],"names":[],"mappings":";;AAAA,8EAA8E;AAC9E,MAAM,UAAU;IACN,MAAM,GAAG,EAAE,CAAC;IAEpB,IAAI,CAAC,KAAa;QAChB,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAC/E,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC3C,OAAO,QAAQ,IAAI,CAAC,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;YAC7C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;YAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAClC,IAAI,IAAI,KAAK,IAAI;gBAAE,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;YAChD,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAClC,OAAO,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;IAEO,QAAQ,CAAC,KAAa;QAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QAC/B,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACpC,MAAM,KAAK,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;YAC9D,IAAI,KAAK,KAAK,MAAM;gBAAE,SAAS;YAC/B,IAAI,KAAK,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;YAC3D,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAClD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,CAAC;CACF;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // SSRF 防护:拦截指向私有/内网地址的导入与远程资产请求。
4
+ // 注意:本地模型发现(/api/fetch-local-models)故意不在此拦截,因为它本就需要访问用户自己的 localhost 服务。
5
+ const { promises: dns } = require('dns');
6
+ const net = require('net');
7
+ function ipv4ToInt(ip) {
8
+ const parts = ip.split('.').map(Number);
9
+ return (((parts[0] << 24) >>> 0) + (parts[1] << 16) + (parts[2] << 8) + parts[3]) >>> 0;
10
+ }
11
+ function inCidr(ipInt, base, bits) {
12
+ if (bits === 0)
13
+ return ipInt === (base >>> 0);
14
+ const mask = (0xffffffff << (32 - bits)) >>> 0;
15
+ return (ipInt & mask) === (base & mask);
16
+ }
17
+ const PRIVATE_V4 = [
18
+ [0, 8], // 0.0.0.0/8
19
+ [ipv4ToInt('10.0.0.0'), 8],
20
+ [ipv4ToInt('100.64.0.0'), 10], // CGNAT
21
+ [ipv4ToInt('127.0.0.0'), 8], // loopback
22
+ [ipv4ToInt('169.254.0.0'), 16], // link-local
23
+ [ipv4ToInt('172.16.0.0'), 12],
24
+ [ipv4ToInt('192.0.0.0'), 24],
25
+ [ipv4ToInt('192.168.0.0'), 16],
26
+ [ipv4ToInt('198.18.0.0'), 15],
27
+ ];
28
+ function isPrivateV4(ip) {
29
+ const n = ipv4ToInt(ip);
30
+ if (n === 0)
31
+ return true;
32
+ return PRIVATE_V4.some(([base, bits]) => inCidr(n, base, bits));
33
+ }
34
+ function isPrivateV6(ip) {
35
+ const a = ip.toLowerCase();
36
+ if (a === '::1' || a === '::')
37
+ return true;
38
+ if (a.startsWith('fe80:'))
39
+ return true; // link-local
40
+ if (a.startsWith('fc') || a.startsWith('fd'))
41
+ return true; // unique local fc00::/7
42
+ const mapped = mappedV4(a);
43
+ if (mapped)
44
+ return isPrivateV4(mapped);
45
+ return false;
46
+ }
47
+ function mappedV4(ip) {
48
+ const dotted = ip.match(/^::ffff:(\d+\.\d+\.\d+\.\d+)$/i);
49
+ if (dotted)
50
+ return dotted[1];
51
+ const hex = ip.match(/^::ffff:([0-9a-f]{1,4}):([0-9a-f]{1,4})$/i);
52
+ if (!hex)
53
+ return null;
54
+ const high = Number.parseInt(hex[1], 16), low = Number.parseInt(hex[2], 16);
55
+ return `${high >> 8}.${high & 255}.${low >> 8}.${low & 255}`;
56
+ }
57
+ function isMetadataAddress(ip) {
58
+ const value = ip.toLowerCase();
59
+ const mapped = mappedV4(value);
60
+ const v4 = mapped || (net.isIP(value) === 4 ? value : null);
61
+ return Boolean(v4 && (v4.startsWith('0.') || v4.startsWith('169.254.') || v4 === '100.100.100.200')) || value === '::' || value === 'fd00:ec2::254' || value.startsWith('fe80:');
62
+ }
63
+ async function assertSafeUrl(input, { allowPrivate = false } = {}) {
64
+ let url;
65
+ try {
66
+ url = new URL(input);
67
+ }
68
+ catch {
69
+ throw new Error('非法 URL');
70
+ }
71
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
72
+ throw new Error('仅支持 http/https 链接');
73
+ }
74
+ // Node keeps square brackets around IPv6 URL hostnames; net.isIP expects the
75
+ // bare address. Normalize before applying private/metadata checks.
76
+ const host = url.hostname.replace(/^\[|\]$/g, '');
77
+ if (net.isIP(host) === 4) {
78
+ if (isMetadataAddress(host))
79
+ throw new Error('SSRF: 目标为保留、元数据或链路本地地址 ' + host);
80
+ if (!allowPrivate && isPrivateV4(host))
81
+ throw new Error('SSRF: 目标为内网地址 ' + host);
82
+ }
83
+ else if (net.isIP(host) === 6) {
84
+ if (isMetadataAddress(host))
85
+ throw new Error('SSRF: 目标为保留、元数据或链路本地地址 ' + host);
86
+ if (!allowPrivate && isPrivateV6(host))
87
+ throw new Error('SSRF: 目标为内网地址 ' + host);
88
+ }
89
+ else {
90
+ const addrs = await dns.lookup(host, { all: true });
91
+ for (const { address } of addrs) {
92
+ const v = net.isIP(address);
93
+ if (isMetadataAddress(address))
94
+ throw new Error('SSRF: 解析到保留、元数据或链路本地地址 ' + address);
95
+ if (v === 4 && !allowPrivate && isPrivateV4(address))
96
+ throw new Error('SSRF: 解析到内网地址 ' + address);
97
+ if (v === 6 && !allowPrivate && isPrivateV6(address))
98
+ throw new Error('SSRF: 解析到内网地址 ' + address);
99
+ }
100
+ }
101
+ return url;
102
+ }
103
+ // 带 SSRF 校验的 fetch:手动处理重定向,每次跳转都重新校验目标地址。
104
+ async function safeFetch(input, options = {}, allowPrivate = false, depth = 0) {
105
+ const url = await assertSafeUrl(input, { allowPrivate });
106
+ const resp = await fetch(url, { ...options, redirect: 'manual' });
107
+ if ([301, 302, 307, 308].includes(resp.status) && depth < 3) {
108
+ const loc = resp.headers.get('location');
109
+ if (!loc)
110
+ throw new Error('重定向缺少 Location');
111
+ const nextUrl = new URL(loc, url);
112
+ let nextOptions = options;
113
+ if (nextUrl.origin !== url.origin && options.headers) {
114
+ // Never forward credentials, cookies, MCP sessions or arbitrary custom
115
+ // headers to another origin. Only protocol/content negotiation headers
116
+ // are safe to retain across the redirect boundary.
117
+ const current = new Headers(options.headers);
118
+ const forwarded = new Headers();
119
+ for (const name of ['accept', 'accept-language', 'content-type', 'mcp-protocol-version']) {
120
+ const value = current.get(name);
121
+ if (value !== null)
122
+ forwarded.set(name, value);
123
+ }
124
+ nextOptions = { ...options, headers: forwarded };
125
+ }
126
+ return safeFetch(nextUrl.toString(), nextOptions, allowPrivate, depth + 1);
127
+ }
128
+ return resp;
129
+ }
130
+ module.exports = { isPrivateV4, isPrivateV6, assertSafeUrl, safeFetch };
131
+ //# sourceMappingURL=ssrf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssrf.js","sourceRoot":"","sources":["../../lib/ssrf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ function createJsonStore(rootDir) {
6
+ // per-file 串行化队列:防止多个并发请求对同一 JSON 做 read-modify-write 时互相覆盖
7
+ const chains = new Map();
8
+ function resolve(name) {
9
+ if (typeof name !== 'string' || !name || path.basename(name) !== name) {
10
+ throw new Error('invalid data file name');
11
+ }
12
+ return path.join(rootDir, name);
13
+ }
14
+ function read(name, fallback) {
15
+ const file = resolve(name);
16
+ if (!fs.existsSync(file))
17
+ return fallback;
18
+ try {
19
+ return JSON.parse(fs.readFileSync(file, 'utf8'));
20
+ }
21
+ catch {
22
+ // A partially written/corrupted JSON file should not silently erase the
23
+ // user's view of their data. Every successful write keeps one local
24
+ // recovery copy, so prefer that before falling back to an empty value.
25
+ const backup = `${file}.bak`;
26
+ try {
27
+ if (fs.existsSync(backup))
28
+ return JSON.parse(fs.readFileSync(backup, 'utf8'));
29
+ }
30
+ catch { }
31
+ return fallback;
32
+ }
33
+ }
34
+ function write(name, value) {
35
+ const file = resolve(name);
36
+ fs.mkdirSync(rootDir, { recursive: true });
37
+ const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
38
+ fs.writeFileSync(temp, JSON.stringify(value, null, 2), 'utf8');
39
+ // Keep one known-good recovery point. On Windows rename-over-existing can
40
+ // fail with EPERM, so use a guarded replacement fallback while retaining
41
+ // the backup. The temporary file is always cleaned up.
42
+ try {
43
+ if (fs.existsSync(file))
44
+ fs.copyFileSync(file, `${file}.bak`);
45
+ try {
46
+ fs.renameSync(temp, file);
47
+ }
48
+ catch (error) {
49
+ if (!['EEXIST', 'EPERM'].includes(error?.code))
50
+ throw error;
51
+ fs.rmSync(file, { force: true });
52
+ fs.renameSync(temp, file);
53
+ }
54
+ }
55
+ finally {
56
+ if (fs.existsSync(temp))
57
+ fs.rmSync(temp, { force: true });
58
+ }
59
+ }
60
+ function remove(name) {
61
+ const file = resolve(name);
62
+ if (fs.existsSync(file))
63
+ fs.unlinkSync(file);
64
+ }
65
+ // 串行化 read-modify-write:fn(currentValue) => newValue(或 undefined 表示不写回)。
66
+ // 同一 name 的多次 mutate 会严格按调用顺序排队执行,杜绝并发覆盖。
67
+ function mutate(name, fn, fallback) {
68
+ const prev = chains.get(name) || Promise.resolve();
69
+ const run = prev
70
+ .then(() => fn(read(name, fallback)))
71
+ .then((result) => {
72
+ if (result === undefined)
73
+ return result;
74
+ write(name, result);
75
+ return result;
76
+ });
77
+ // 存入"已处理 rejection"的链,避免后续排队因前序失败而中断,也避免 unhandled rejection
78
+ chains.set(name, run.then(() => { }, () => { }));
79
+ return run;
80
+ }
81
+ return { kind: 'json', read, write, remove, resolve, mutate };
82
+ }
83
+ module.exports = { createJsonStore };
84
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../lib/store.ts"],"names":[],"mappings":"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"}