openfox 2.0.110 → 2.0.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +1 -0
- package/dist/CHANGELOG.md +19 -0
- package/dist/{ask-CJMU6EW7.js → ask-ZYPCJKZD.js} +3 -2
- package/dist/{chat-handler-UZ7WTT6D.js → chat-handler-BYXZIIV3.js} +23 -22
- package/dist/{chunk-VJWWJEBX.js → chunk-3UILDGOO.js} +9 -9
- package/dist/{chunk-QRASX3HC.js → chunk-4DTV5JVI.js} +7 -7
- package/dist/{chunk-ZJW3KOII.js → chunk-A32COLEZ.js} +293 -98
- package/dist/{chunk-GNFDD6LN.js → chunk-BOSKQI62.js} +3 -3
- package/dist/{chunk-D6ODGTSZ.js → chunk-C372UH7N.js} +2 -1
- package/dist/{chunk-4ZXRERIW.js → chunk-C5NQF2K4.js} +46 -4
- package/dist/{chunk-3HS72YIE.js → chunk-ERYUSG5C.js} +2 -2
- package/dist/{chunk-PU3IPUSW.js → chunk-FFPCVN5M.js} +45 -8
- package/dist/{chunk-KDQJOI2I.js → chunk-FSYRANYR.js} +2 -2
- package/dist/chunk-GZOK3FAA.js +7 -0
- package/dist/chunk-IJ53Y77N.js +142 -0
- package/dist/{chunk-WCQOHRUX.js → chunk-JDT63SSP.js} +2 -2
- package/dist/{chunk-VT2X3DMC.js → chunk-JNHKKUGJ.js} +2 -2
- package/dist/{chunk-JAX5OEMM.js → chunk-JURM3RPZ.js} +21 -4
- package/dist/chunk-LCLH6ZUL.js +43 -0
- package/dist/{chunk-6EV7X5MP.js → chunk-N4RTAGFY.js} +2 -2
- package/dist/{chunk-LXYNP7LL.js → chunk-NB2D6I64.js} +221 -5
- package/dist/{chunk-VKWVPQJ5.js → chunk-OAN4BXEW.js} +3 -1
- package/dist/{chunk-4R7G5JB6.js → chunk-P45RJGOT.js} +1 -1
- package/dist/{chunk-E5HZKNTY.js → chunk-PCC4DBPF.js} +2 -2
- package/dist/{chunk-ACJNRPTO.js → chunk-QGXLZZBS.js} +29 -21
- package/dist/{chunk-UCYPPLVR.js → chunk-RAKPI4OE.js} +81 -70
- package/dist/{chunk-MM46DJJL.js → chunk-RISQXU32.js} +2 -2
- package/dist/{chunk-CQKRZ4WV.js → chunk-RKMP74BB.js} +4 -4
- package/dist/chunk-RSB4AR2A.js +108 -0
- package/dist/{chunk-VXKPZUCT.js → chunk-RT2A2RRL.js} +4 -2
- package/dist/{chunk-HK75Q3EA.js → chunk-SDGNV45R.js} +10 -10
- package/dist/{chunk-C5JJM72V.js → chunk-SVJFMZ2Q.js} +49 -5
- package/dist/{chunk-B5MH4HQ6.js → chunk-SYJMUIRC.js} +7 -3
- package/dist/{chunk-4HIFB7F5.js → chunk-XCK5IBO4.js} +37 -26
- package/dist/{chunk-5HMKLHTT.js → chunk-XWNCKIPO.js} +2 -2
- package/dist/{chunk-NORNB6IJ.js → chunk-Z56SEG4Z.js} +6 -6
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{client-LPNFUOPV.js → client-QNQTX5EA.js} +4 -4
- package/dist/{compactor-OSDLCGRC.js → compactor-X2KZ3XFU.js} +10 -9
- package/dist/{config-HX7FDKGJ.js → config-TW5FHQEM.js} +2 -2
- package/dist/{dynamic-context-WVA7HTEP.js → dynamic-context-ZRQO2FJN.js} +7 -7
- package/dist/{events-26J7BUSY.js → events-Y6XXQYFG.js} +7 -6
- package/dist/{folding-ZD4AMFNR.js → folding-Z4GNWRC3.js} +9 -6
- package/dist/{http-client-MQARNFY3.js → http-client-2GDKHZIG.js} +3 -3
- package/dist/{manager-RJH7EYIG.js → manager-HCMDFEQH.js} +4 -4
- package/dist/{model-overrides-BXMFIT47.js → model-overrides-O3ZYKFP7.js} +3 -3
- package/dist/oauth-provider-52YILVUJ.js +15 -0
- package/dist/oauth-store-XCFXV2VM.js +32 -0
- package/dist/{orchestrator-BW27C4K4.js → orchestrator-P5EUMC7E.js} +22 -21
- package/dist/package.json +11 -9
- package/dist/{path-security-AAZMH33K.js → path-security-525YLND3.js} +11 -9
- package/dist/{platform-EZJABX5J.js → platform-MEQUWG6U.js} +3 -3
- package/dist/{processor-FTCPHWBM.js → processor-UN4H4V7F.js} +22 -21
- package/dist/{protocol-_Gphic7p.d.ts → protocol-D6MISQyz.d.ts} +8 -3
- package/dist/{protocol-SPIJPOEN.js → protocol-FTHAR2YL.js} +4 -3
- package/dist/{provider-JS5P3HQ2.js → provider-3R4X62LW.js} +7 -7
- package/dist/{provider-manager-MWAIOX2A.js → provider-manager-W5N4XRE5.js} +5 -5
- package/dist/{registry-JJB5GXOM.js → registry-74KPZ5NV.js} +3 -3
- package/dist/{serve-XDZB4EJN.js → serve-V7WQKJ52.js} +32 -29
- package/dist/server/index.d.ts +15 -1
- package/dist/server/index.js +31 -28
- package/dist/server-7MOOJR2N.js +48 -0
- package/dist/{session-overrides-T47KXDDS.js → session-overrides-XH6I3COP.js} +5 -5
- package/dist/{sessions-YTWCOHI3.js → sessions-D772YTWL.js} +8 -4
- package/dist/{settings-2RZBMX5Y.js → settings-KO6DSJLD.js} +2 -2
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/{tools-KPIYFL5A.js → tools-HTUTYMKI.js} +20 -19
- package/dist/{update-75QZJYKD.js → update-MWPQNSEZ.js} +2 -2
- package/dist/{update-server-4I6LXE5K.js → update-server-LOOXIXDW.js} +2 -2
- package/dist/web/assets/{index-BmjVoqQT.js → index-Dukvfqm-.js} +83 -83
- package/dist/web/assets/{index-CyWbbpRP.css → index-nS1p0g8O.css} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/package.json +11 -9
- package/dist/chunk-64374FPB.js +0 -7
- package/dist/server-R6DDJNF3.js +0 -47
|
@@ -5,13 +5,13 @@ import {
|
|
|
5
5
|
deleteItemFromDir,
|
|
6
6
|
loadItemsFromDir,
|
|
7
7
|
pathExists
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-JNHKKUGJ.js";
|
|
9
9
|
import {
|
|
10
10
|
SETTINGS_KEYS,
|
|
11
11
|
deleteSetting,
|
|
12
12
|
getSetting,
|
|
13
13
|
setSetting
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-RT2A2RRL.js";
|
|
15
15
|
|
|
16
16
|
// src/server/context/instructions.ts
|
|
17
17
|
import { readFile, access } from "fs/promises";
|
|
@@ -440,4 +440,4 @@ export {
|
|
|
440
440
|
deleteSkill,
|
|
441
441
|
deleteProjectSkill
|
|
442
442
|
};
|
|
443
|
-
//# sourceMappingURL=chunk-
|
|
443
|
+
//# sourceMappingURL=chunk-BOSKQI62.js.map
|
|
@@ -108,6 +108,7 @@ var mcpServerSchema = z.object({
|
|
|
108
108
|
env: z.record(z.string(), z.string()).optional(),
|
|
109
109
|
url: z.string().optional(),
|
|
110
110
|
headers: z.record(z.string(), z.string()).optional(),
|
|
111
|
+
oauth: z.boolean().optional(),
|
|
111
112
|
disabledTools: z.array(z.string()).optional(),
|
|
112
113
|
cachedTools: z.array(cachedToolSchema).optional(),
|
|
113
114
|
timeout: z.number().positive().optional(),
|
|
@@ -370,4 +371,4 @@ export {
|
|
|
370
371
|
removeProvider,
|
|
371
372
|
activateProvider
|
|
372
373
|
};
|
|
373
|
-
//# sourceMappingURL=chunk-
|
|
374
|
+
//# sourceMappingURL=chunk-C372UH7N.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveDefaultAgentId
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JNHKKUGJ.js";
|
|
4
4
|
import {
|
|
5
5
|
getDatabase
|
|
6
6
|
} from "./chunk-LCQ5AN6Y.js";
|
|
@@ -245,7 +245,14 @@ function listSessions() {
|
|
|
245
245
|
return rows.map(mapSessionSummaryRow);
|
|
246
246
|
}
|
|
247
247
|
function listSessionsByProject(projectId, limit = 20, offset = 0) {
|
|
248
|
+
return listSessionsPaged(projectId, limit, offset);
|
|
249
|
+
}
|
|
250
|
+
function listSessionsLimited(limit = 20, offset = 0) {
|
|
251
|
+
return listSessionsPaged(null, limit, offset);
|
|
252
|
+
}
|
|
253
|
+
function listSessionsPaged(projectId, limit, offset) {
|
|
248
254
|
const db = getDatabase();
|
|
255
|
+
const where = projectId ? "WHERE s.project_id = ?" : "";
|
|
249
256
|
const rows = db.prepare(
|
|
250
257
|
`
|
|
251
258
|
SELECT
|
|
@@ -264,15 +271,48 @@ function listSessionsByProject(projectId, limit = 20, offset = 0) {
|
|
|
264
271
|
s.provider_model,
|
|
265
272
|
s.message_count
|
|
266
273
|
FROM sessions s
|
|
267
|
-
|
|
274
|
+
${where}
|
|
268
275
|
ORDER BY s.updated_at DESC
|
|
269
276
|
LIMIT ? OFFSET ?
|
|
270
277
|
`
|
|
271
|
-
).all(projectId, limit + 1, offset);
|
|
278
|
+
).all(...projectId ? [projectId] : [], limit + 1, offset);
|
|
272
279
|
const hasMore = rows.length > limit;
|
|
273
280
|
const sessions = rows.slice(0, limit).map(mapSessionSummaryRow);
|
|
274
281
|
return { sessions, hasMore };
|
|
275
282
|
}
|
|
283
|
+
function listHomeSessions(sessionsPerProject = 5) {
|
|
284
|
+
const db = getDatabase();
|
|
285
|
+
const rows = db.prepare(
|
|
286
|
+
`
|
|
287
|
+
SELECT
|
|
288
|
+
s.id,
|
|
289
|
+
s.project_id,
|
|
290
|
+
s.workdir,
|
|
291
|
+
s.workspace,
|
|
292
|
+
s.branch,
|
|
293
|
+
s.mode,
|
|
294
|
+
s.workflow_phase,
|
|
295
|
+
s.is_running,
|
|
296
|
+
s.created_at,
|
|
297
|
+
s.updated_at,
|
|
298
|
+
s.title,
|
|
299
|
+
s.provider_id,
|
|
300
|
+
s.provider_model,
|
|
301
|
+
s.message_count
|
|
302
|
+
FROM sessions s
|
|
303
|
+
ORDER BY s.updated_at DESC
|
|
304
|
+
`
|
|
305
|
+
).all();
|
|
306
|
+
const seen = /* @__PURE__ */ new Map();
|
|
307
|
+
const result = [];
|
|
308
|
+
for (const row of rows) {
|
|
309
|
+
const count = seen.get(row.project_id) ?? 0;
|
|
310
|
+
if (count >= sessionsPerProject) continue;
|
|
311
|
+
seen.set(row.project_id, count + 1);
|
|
312
|
+
result.push(mapSessionSummaryRow(row));
|
|
313
|
+
}
|
|
314
|
+
return result;
|
|
315
|
+
}
|
|
276
316
|
function updateSessionWorkdir(id, workdir, workspace, branch) {
|
|
277
317
|
const db = getDatabase();
|
|
278
318
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -360,6 +400,8 @@ export {
|
|
|
360
400
|
getSessionMessageCount,
|
|
361
401
|
listSessions,
|
|
362
402
|
listSessionsByProject,
|
|
403
|
+
listSessionsLimited,
|
|
404
|
+
listHomeSessions,
|
|
363
405
|
updateSessionWorkdir,
|
|
364
406
|
updateSessionBranch,
|
|
365
407
|
deleteSession,
|
|
@@ -368,4 +410,4 @@ export {
|
|
|
368
410
|
getActiveWorkflowExecution,
|
|
369
411
|
clearWorkflowExecution
|
|
370
412
|
};
|
|
371
|
-
//# sourceMappingURL=chunk-
|
|
413
|
+
//# sourceMappingURL=chunk-C5NQF2K4.js.map
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
import {
|
|
18
18
|
LLMError,
|
|
19
19
|
OpenAIHttpClient
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-PCC4DBPF.js";
|
|
21
21
|
import {
|
|
22
22
|
logger
|
|
23
23
|
} from "./chunk-K44MW7JJ.js";
|
|
@@ -310,4 +310,4 @@ function createLLMClient(config, initialBackend = "unknown") {
|
|
|
310
310
|
export {
|
|
311
311
|
createLLMClient
|
|
312
312
|
};
|
|
313
|
-
//# sourceMappingURL=chunk-
|
|
313
|
+
//# sourceMappingURL=chunk-ERYUSG5C.js.map
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getEventStore
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-NB2D6I64.js";
|
|
4
4
|
import {
|
|
5
5
|
createChatPathConfirmationMessage
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-SYJMUIRC.js";
|
|
7
|
+
import {
|
|
8
|
+
getPlatformShell
|
|
9
|
+
} from "./chunk-N4RTAGFY.js";
|
|
7
10
|
|
|
8
11
|
// src/server/tools/path-security.ts
|
|
9
12
|
import { realpath } from "fs/promises";
|
|
@@ -120,11 +123,19 @@ function looksLikeRegex(str) {
|
|
|
120
123
|
return /[*?+[\]\\]/.test(str);
|
|
121
124
|
}
|
|
122
125
|
var isWindows = () => process.platform === "win32";
|
|
126
|
+
function usesPosixPaths() {
|
|
127
|
+
if (process.platform !== "win32") return true;
|
|
128
|
+
return /^(?:ba|z|)sh(?:\.exe)?$/i.test(win32.basename(getPlatformShell().command));
|
|
129
|
+
}
|
|
123
130
|
function isWindowsAbsolutePath(str) {
|
|
124
131
|
return /^[A-Za-z]:[\\/]/.test(str);
|
|
125
132
|
}
|
|
126
133
|
function normalizeExtracted(path) {
|
|
127
|
-
|
|
134
|
+
if (isWindowsAbsolutePath(path)) return win32.normalize(path);
|
|
135
|
+
if (isWindows() && /^\/[A-Za-z]\//.test(path)) {
|
|
136
|
+
return win32.normalize(`${path[1].toUpperCase()}:\\${path.slice(3)}`);
|
|
137
|
+
}
|
|
138
|
+
return posix.normalize(path);
|
|
128
139
|
}
|
|
129
140
|
function isPlaceholderToken(str) {
|
|
130
141
|
return str.includes("__URL__") || str.includes("__FILEURL__") || str.includes("__SED__") || str.includes("__COMMIT_MSG__");
|
|
@@ -135,6 +146,7 @@ function extractAbsolutePathsFromCommand(command) {
|
|
|
135
146
|
}
|
|
136
147
|
const paths = [];
|
|
137
148
|
const home = homedir();
|
|
149
|
+
const posixShell = usesPosixPaths();
|
|
138
150
|
let sanitized = command.replace(/https?:\/\/[^\s'"]+/g, " __URL__ ").replace(/ftp:\/\/[^\s'"]+/g, " __URL__ ");
|
|
139
151
|
sanitized = sanitized.replace(/(?<!\w)s\/[^/]*\/[^/]*\/[gip]*/g, " __SED__ ");
|
|
140
152
|
sanitized = sanitized.replace(/(?<!\w)s\|[^|]*\|[^|]*\|[gip]*/g, " __SED__ ");
|
|
@@ -175,7 +187,7 @@ function extractAbsolutePathsFromCommand(command) {
|
|
|
175
187
|
if (!isSafePath(resolved)) {
|
|
176
188
|
paths.push(resolved);
|
|
177
189
|
}
|
|
178
|
-
} else if (
|
|
190
|
+
} else if (posixShell && content.startsWith("/")) {
|
|
179
191
|
const resolved = normalizeExtracted(content);
|
|
180
192
|
if (!isSafePath(resolved)) {
|
|
181
193
|
paths.push(resolved);
|
|
@@ -199,7 +211,8 @@ function extractAbsolutePathsFromCommand(command) {
|
|
|
199
211
|
paths.push(resolved);
|
|
200
212
|
}
|
|
201
213
|
}
|
|
202
|
-
}
|
|
214
|
+
}
|
|
215
|
+
if (posixShell) {
|
|
203
216
|
const absolutePattern = /(?:^|[\s=(])(\/[^\s"'|&;<>`()]+)/g;
|
|
204
217
|
while ((match = absolutePattern.exec(sanitized)) !== null) {
|
|
205
218
|
const candidate = match[1];
|
|
@@ -238,9 +251,12 @@ function extractSensitivePathsFromCommand(command) {
|
|
|
238
251
|
}
|
|
239
252
|
return [...new Set(paths)];
|
|
240
253
|
}
|
|
254
|
+
var WINDOWS_DEVICE_NAMES = /* @__PURE__ */ new Set(["nul", "con", "prn", "aux"]);
|
|
241
255
|
function isSafePath(path) {
|
|
242
256
|
const normalized = posix.normalize(path);
|
|
243
|
-
|
|
257
|
+
if (SAFE_PATHS.has(normalized)) return true;
|
|
258
|
+
if (!isWindows()) return false;
|
|
259
|
+
return WINDOWS_DEVICE_NAMES.has(win32.basename(path.replace(/^\\\\[.?]\\/, "")).toLowerCase());
|
|
244
260
|
}
|
|
245
261
|
async function checkPathsAccess(paths, workdir, sessionId) {
|
|
246
262
|
if (paths.length === 0) {
|
|
@@ -274,9 +290,30 @@ var DANGEROUS_PATTERNS = [
|
|
|
274
290
|
/dd\s+if=/,
|
|
275
291
|
/:\(\)\s*\{\s*:\s*\|\s*:\s*&\s*\}\s*;/
|
|
276
292
|
];
|
|
293
|
+
var WINDOWS_DANGEROUS_PATTERNS = [
|
|
294
|
+
/\b(?:rd|rmdir)\s+(?:\/[a-z]\s+)*\/s\b/i,
|
|
295
|
+
// rd /s /q <dir>
|
|
296
|
+
/\bdel\s+(?:\/[a-z]\s+)*\/s\b/i,
|
|
297
|
+
// del /f /s /q <pattern>
|
|
298
|
+
// The operand is a bare drive ("D:", "D:\"), never a file path — that is what
|
|
299
|
+
// keeps "npm run format -- C:\src\x.ts" out of the dangerous bucket.
|
|
300
|
+
/\bformat\s+(?:\/\S+\s+)*[a-z]:\\?(?=\s|$)/i,
|
|
301
|
+
// format D: / format /q D: / format /fs:NTFS D:
|
|
302
|
+
/\bRemove-Item\b(?=[^|;]*-Recurse\b)(?=[^|;]*-Force\b)/i,
|
|
303
|
+
// PowerShell recursive force delete (flag order-independent)
|
|
304
|
+
/\brunas\b/i,
|
|
305
|
+
// sudo equivalent
|
|
306
|
+
/\bStart-Process\b[^|;]*-Verb\s+RunAs\b/i,
|
|
307
|
+
// sudo equivalent (PowerShell)
|
|
308
|
+
/\bicacls\b[^|;]*\/grant\b[^|;]*Everyone/i,
|
|
309
|
+
// chmod 777 equivalent
|
|
310
|
+
/\bdiskpart\b/i
|
|
311
|
+
// raw disk write, dd/mkfs equivalent
|
|
312
|
+
];
|
|
277
313
|
function extractDangerousPatterns(command) {
|
|
314
|
+
const patterns = isWindows() ? [...DANGEROUS_PATTERNS, ...WINDOWS_DANGEROUS_PATTERNS] : DANGEROUS_PATTERNS;
|
|
278
315
|
const dangerous = [];
|
|
279
|
-
for (const pattern of
|
|
316
|
+
for (const pattern of patterns) {
|
|
280
317
|
if (pattern.test(command)) {
|
|
281
318
|
dangerous.push(pattern.source);
|
|
282
319
|
}
|
|
@@ -498,4 +535,4 @@ export {
|
|
|
498
535
|
getConfirmationSessionId,
|
|
499
536
|
getPendingConfirmationsBySession
|
|
500
537
|
};
|
|
501
|
-
//# sourceMappingURL=chunk-
|
|
538
|
+
//# sourceMappingURL=chunk-FFPCVN5M.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createLLMClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ERYUSG5C.js";
|
|
4
4
|
import {
|
|
5
5
|
getModelProfile
|
|
6
6
|
} from "./chunk-V4IE7HJY.js";
|
|
@@ -804,4 +804,4 @@ export {
|
|
|
804
804
|
parseDefaultModelSelection,
|
|
805
805
|
createProviderManager
|
|
806
806
|
};
|
|
807
|
-
//# sourceMappingURL=chunk-
|
|
807
|
+
//# sourceMappingURL=chunk-FSYRANYR.js.map
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
logger
|
|
3
|
+
} from "./chunk-K44MW7JJ.js";
|
|
4
|
+
import {
|
|
5
|
+
getGlobalConfigDir
|
|
6
|
+
} from "./chunk-CQGTEGKL.js";
|
|
7
|
+
|
|
8
|
+
// src/server/mcp/oauth-store.ts
|
|
9
|
+
import { chmod, mkdir, readFile, rename, writeFile } from "fs/promises";
|
|
10
|
+
import { dirname, join } from "path";
|
|
11
|
+
var storeMode = "production";
|
|
12
|
+
var storePathOverride;
|
|
13
|
+
function setMcpOAuthStoreMode(mode) {
|
|
14
|
+
storeMode = mode;
|
|
15
|
+
}
|
|
16
|
+
function setMcpOAuthStorePath(path) {
|
|
17
|
+
storePathOverride = path;
|
|
18
|
+
}
|
|
19
|
+
function getMcpOAuthStorePath() {
|
|
20
|
+
return storePathOverride ?? join(getGlobalConfigDir(storeMode), "mcp-auth.json");
|
|
21
|
+
}
|
|
22
|
+
async function readStore() {
|
|
23
|
+
const path = getMcpOAuthStorePath();
|
|
24
|
+
let raw;
|
|
25
|
+
try {
|
|
26
|
+
raw = await readFile(path, "utf-8");
|
|
27
|
+
} catch {
|
|
28
|
+
return { version: 1, servers: {} };
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(raw);
|
|
32
|
+
const servers = parsed.servers;
|
|
33
|
+
if (!servers || typeof servers !== "object") throw new Error("no servers object");
|
|
34
|
+
const kept = {};
|
|
35
|
+
for (const [name, entry] of Object.entries(servers)) {
|
|
36
|
+
if (entry && typeof entry === "object" && typeof entry.serverUrl === "string") {
|
|
37
|
+
kept[name] = entry;
|
|
38
|
+
} else {
|
|
39
|
+
logger.warn("Dropping an unreadable MCP OAuth entry, this server will have to authorize again", {
|
|
40
|
+
path,
|
|
41
|
+
server: name
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { version: 1, servers: kept };
|
|
46
|
+
} catch {
|
|
47
|
+
logger.error("The MCP OAuth store is unreadable, stored authorizations will be ignored", { path });
|
|
48
|
+
return { version: 1, servers: {} };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function writeStore(store) {
|
|
52
|
+
const path = getMcpOAuthStorePath();
|
|
53
|
+
await mkdir(dirname(path), { recursive: true });
|
|
54
|
+
const tmpPath = `${path}.tmp`;
|
|
55
|
+
await writeFile(tmpPath, JSON.stringify(store, null, 2), { mode: 384 });
|
|
56
|
+
try {
|
|
57
|
+
await chmod(tmpPath, 384);
|
|
58
|
+
} catch {
|
|
59
|
+
logger.warn("Could not restrict permissions on the MCP OAuth store", { path });
|
|
60
|
+
}
|
|
61
|
+
await rename(tmpPath, path);
|
|
62
|
+
}
|
|
63
|
+
var writeQueue = Promise.resolve();
|
|
64
|
+
function serialize(work) {
|
|
65
|
+
const result = writeQueue.then(work, work);
|
|
66
|
+
writeQueue = result.catch(() => void 0);
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
async function mutateEntry(name, serverUrl, mutate) {
|
|
70
|
+
await serialize(async () => {
|
|
71
|
+
const store = await readStore();
|
|
72
|
+
const current = store.servers[name];
|
|
73
|
+
const base = current && current.serverUrl === serverUrl ? current : { serverUrl };
|
|
74
|
+
store.servers[name] = mutate(base);
|
|
75
|
+
await writeStore(store);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function withoutAuthorizationState(entry) {
|
|
79
|
+
const next = { serverUrl: entry.serverUrl };
|
|
80
|
+
if (entry.clientInformation) next.clientInformation = entry.clientInformation;
|
|
81
|
+
if (entry.tokens) next.tokens = entry.tokens;
|
|
82
|
+
return next;
|
|
83
|
+
}
|
|
84
|
+
async function readMcpOAuthEntry(name, serverUrl) {
|
|
85
|
+
const store = await readStore();
|
|
86
|
+
const entry = store.servers[name];
|
|
87
|
+
if (!entry || entry.serverUrl !== serverUrl) return void 0;
|
|
88
|
+
return entry;
|
|
89
|
+
}
|
|
90
|
+
async function saveMcpOAuthClientInformation(name, serverUrl, clientInformation) {
|
|
91
|
+
await mutateEntry(name, serverUrl, (entry) => ({ ...entry, clientInformation }));
|
|
92
|
+
}
|
|
93
|
+
async function saveMcpOAuthTokens(name, serverUrl, tokens) {
|
|
94
|
+
await mutateEntry(name, serverUrl, (entry) => ({ ...withoutAuthorizationState(entry), tokens }));
|
|
95
|
+
}
|
|
96
|
+
async function saveMcpOAuthCodeVerifier(name, serverUrl, codeVerifier) {
|
|
97
|
+
await mutateEntry(name, serverUrl, (entry) => ({ ...entry, codeVerifier }));
|
|
98
|
+
}
|
|
99
|
+
async function saveMcpOAuthState(name, serverUrl, state) {
|
|
100
|
+
await mutateEntry(name, serverUrl, (entry) => ({ ...entry, state }));
|
|
101
|
+
}
|
|
102
|
+
async function clearMcpOAuthTokens(name, serverUrl) {
|
|
103
|
+
await mutateEntry(name, serverUrl, (entry) => {
|
|
104
|
+
const next = withoutAuthorizationState(entry);
|
|
105
|
+
delete next.tokens;
|
|
106
|
+
return next;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
async function clearMcpOAuthAuthorizationState(name, serverUrl) {
|
|
110
|
+
await mutateEntry(name, serverUrl, withoutAuthorizationState);
|
|
111
|
+
}
|
|
112
|
+
async function clearMcpOAuthEntry(name) {
|
|
113
|
+
await serialize(async () => {
|
|
114
|
+
const store = await readStore();
|
|
115
|
+
if (!(name in store.servers)) return;
|
|
116
|
+
delete store.servers[name];
|
|
117
|
+
await writeStore(store);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
async function findMcpOAuthEntryByState(state) {
|
|
121
|
+
const store = await readStore();
|
|
122
|
+
for (const [name, entry] of Object.entries(store.servers)) {
|
|
123
|
+
if (entry.state && entry.state === state) return { name, entry };
|
|
124
|
+
}
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export {
|
|
129
|
+
setMcpOAuthStoreMode,
|
|
130
|
+
setMcpOAuthStorePath,
|
|
131
|
+
getMcpOAuthStorePath,
|
|
132
|
+
readMcpOAuthEntry,
|
|
133
|
+
saveMcpOAuthClientInformation,
|
|
134
|
+
saveMcpOAuthTokens,
|
|
135
|
+
saveMcpOAuthCodeVerifier,
|
|
136
|
+
saveMcpOAuthState,
|
|
137
|
+
clearMcpOAuthTokens,
|
|
138
|
+
clearMcpOAuthAuthorizationState,
|
|
139
|
+
clearMcpOAuthEntry,
|
|
140
|
+
findMcpOAuthEntryByState
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=chunk-IJ53Y77N.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
updateSessionMcpDisabledServers
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-C5NQF2K4.js";
|
|
4
4
|
import {
|
|
5
5
|
getDatabase
|
|
6
6
|
} from "./chunk-LCQ5AN6Y.js";
|
|
@@ -62,4 +62,4 @@ export {
|
|
|
62
62
|
clearSessionOverrides,
|
|
63
63
|
getAllSessionOverrides
|
|
64
64
|
};
|
|
65
|
-
//# sourceMappingURL=chunk-
|
|
65
|
+
//# sourceMappingURL=chunk-JDT63SSP.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SETTINGS_KEYS,
|
|
3
3
|
getSetting
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RT2A2RRL.js";
|
|
5
5
|
import {
|
|
6
6
|
logger
|
|
7
7
|
} from "./chunk-K44MW7JJ.js";
|
|
@@ -455,4 +455,4 @@ export {
|
|
|
455
455
|
getOverrideAgentIds,
|
|
456
456
|
resolveDefaultAgentId
|
|
457
457
|
};
|
|
458
|
-
//# sourceMappingURL=chunk-
|
|
458
|
+
//# sourceMappingURL=chunk-JNHKKUGJ.js.map
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
normalizeAskOptions
|
|
3
|
+
} from "./chunk-LCLH6ZUL.js";
|
|
4
|
+
|
|
1
5
|
// src/server/utils/async.ts
|
|
2
6
|
function createDeferred() {
|
|
3
7
|
let resolve;
|
|
@@ -56,8 +60,21 @@ var askUserTool = {
|
|
|
56
60
|
},
|
|
57
61
|
options: {
|
|
58
62
|
type: "array",
|
|
59
|
-
|
|
60
|
-
|
|
63
|
+
description: "Options for choice-type questions. Each entry may be a plain string or an object {value, label, description?} (or legacy {label, description?}). The server normalizes everything to {value, label, description?}.",
|
|
64
|
+
items: {
|
|
65
|
+
oneOf: [
|
|
66
|
+
{ type: "string" },
|
|
67
|
+
{
|
|
68
|
+
type: "object",
|
|
69
|
+
properties: {
|
|
70
|
+
value: { type: "string" },
|
|
71
|
+
label: { type: "string" },
|
|
72
|
+
description: { type: "string" }
|
|
73
|
+
},
|
|
74
|
+
required: ["label"]
|
|
75
|
+
}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
61
78
|
}
|
|
62
79
|
},
|
|
63
80
|
required: ["question"]
|
|
@@ -67,7 +84,7 @@ var askUserTool = {
|
|
|
67
84
|
async execute(args, context) {
|
|
68
85
|
const question = args["question"];
|
|
69
86
|
const type = args["type"] ?? "text";
|
|
70
|
-
const options = args["options"];
|
|
87
|
+
const options = normalizeAskOptions(args["options"]);
|
|
71
88
|
const callId = context.toolCallId ?? crypto.randomUUID();
|
|
72
89
|
const deferred = createDeferred();
|
|
73
90
|
void deferred.promise.catch(() => {
|
|
@@ -156,4 +173,4 @@ export {
|
|
|
156
173
|
awaitAnswer,
|
|
157
174
|
getPendingQuestionsForSession
|
|
158
175
|
};
|
|
159
|
-
//# sourceMappingURL=chunk-
|
|
176
|
+
//# sourceMappingURL=chunk-JURM3RPZ.js.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// src/shared/ask-options.ts
|
|
2
|
+
function normalizeAskOptions(raw) {
|
|
3
|
+
if (raw == null) return void 0;
|
|
4
|
+
if (typeof raw === "string") {
|
|
5
|
+
const parts = raw.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
6
|
+
return parts.length > 0 ? parts.map((label) => ({ value: label, label })) : void 0;
|
|
7
|
+
}
|
|
8
|
+
if (!Array.isArray(raw)) return void 0;
|
|
9
|
+
const out = [];
|
|
10
|
+
for (const item of raw) {
|
|
11
|
+
if (typeof item === "string") {
|
|
12
|
+
const trimmed = item.trim();
|
|
13
|
+
if (trimmed.length > 0) {
|
|
14
|
+
out.push({ value: trimmed, label: trimmed });
|
|
15
|
+
}
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
if (item != null && typeof item === "object") {
|
|
19
|
+
const obj = item;
|
|
20
|
+
const labelRaw = obj["label"];
|
|
21
|
+
const valueRaw = obj["value"];
|
|
22
|
+
if (typeof labelRaw === "string" && labelRaw.trim().length > 0) {
|
|
23
|
+
const label = labelRaw.trim();
|
|
24
|
+
const value = typeof valueRaw === "string" && valueRaw.length > 0 ? valueRaw : label;
|
|
25
|
+
const descRaw = obj["description"];
|
|
26
|
+
const opt = {
|
|
27
|
+
value,
|
|
28
|
+
label
|
|
29
|
+
};
|
|
30
|
+
if (typeof descRaw === "string" && descRaw.length > 0) {
|
|
31
|
+
opt.description = descRaw;
|
|
32
|
+
}
|
|
33
|
+
out.push(opt);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return out.length > 0 ? out : void 0;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export {
|
|
41
|
+
normalizeAskOptions
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=chunk-LCLH6ZUL.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SETTINGS_KEYS,
|
|
3
3
|
getSetting
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-RT2A2RRL.js";
|
|
5
5
|
|
|
6
6
|
// src/server/utils/platform.ts
|
|
7
7
|
import os from "os";
|
|
@@ -63,4 +63,4 @@ export {
|
|
|
63
63
|
isWindowsPath,
|
|
64
64
|
isAbsolutePath
|
|
65
65
|
};
|
|
66
|
-
//# sourceMappingURL=chunk-
|
|
66
|
+
//# sourceMappingURL=chunk-N4RTAGFY.js.map
|