openfox 2.0.110 → 2.0.112
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 +25 -0
- package/README.md +1 -0
- package/dist/CHANGELOG.md +25 -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-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-IJ53Y77N.js +142 -0
- package/dist/{chunk-ZJW3KOII.js → chunk-IYTDCPEQ.js} +293 -98
- 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-P5AA7OYJ.js +7 -0
- 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-QRASX3HC.js → chunk-UAF2FOI5.js} +7 -7
- 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 +13 -10
- 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-WHFUNQ6Z.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-BRUFGGTW.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 +13 -10
- package/scripts/postinstall.mjs +8 -0
- package/dist/chunk-64374FPB.js +0 -7
- package/dist/server-R6DDJNF3.js +0 -47
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.112 - 2026-08-03
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
- **Updates install again** — the postinstall script is now bundled with the release, so `openfox update` no longer fails halfway with a missing file
|
|
8
|
+
|
|
9
|
+
## 2.0.111 - 2026-08-03
|
|
10
|
+
|
|
11
|
+
### Enhancements
|
|
12
|
+
|
|
13
|
+
- **OAuth login for MCP servers** — servers that require OAuth authorization now connect through a browser-based login flow instead of failing
|
|
14
|
+
- **Manual model entry in the provider setup** — if a provider exposes no model list, type the model name directly instead of hitting a dead-end "No models found"
|
|
15
|
+
- **You choose when to restart after an update** — updates download first and restart on your OK; service installs can opt into automatic restart
|
|
16
|
+
- **Homepage loads faster** — the session list shows the five most recent per project up front and fills in the rest lazily
|
|
17
|
+
- **Leaner session storage** — finished tool-call streaming buffers are dropped from snapshots and stale backups auto-prune after 10 days
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
- **Tool calls no longer misread as interrupted** — an output that merely contains the interrupt marker text now shows as successful
|
|
22
|
+
- **Multi-statement shell commands keep their tails** — output is no longer cut at the first line for compound commands
|
|
23
|
+
- **Windows paths shorten to names again** — workspace and file names show their basename instead of the full path
|
|
24
|
+
- **Auto-compaction honors configured thresholds** — the internal cap is raised from 85%, so thresholds up to 95% work as set
|
|
25
|
+
- **Windows path-safety gaps closed** — dangerous commands outside the workdir are confirmed again in edge cases, including under Git Bash
|
|
26
|
+
- **Choice options survive reloads** — structured choices stay stable across page refreshes
|
|
27
|
+
|
|
3
28
|
## 2.0.110 - 2026-08-02
|
|
4
29
|
|
|
5
30
|
### Bug Fixes
|
package/README.md
CHANGED
|
@@ -139,6 +139,7 @@ _Vision Fallback — Image processing configuration_
|
|
|
139
139
|
| `OPENFOX_LLM_IDLE_TIMEOUT` | `300000` | LLM stream idle timeout in ms |
|
|
140
140
|
| `OPENFOX_PORT` | `10369` | Server listen port |
|
|
141
141
|
| `OPENFOX_HOST` | `127.0.0.1` | Server bind host |
|
|
142
|
+
| `OPENFOX_PUBLIC_URL` | — | Public origin used to build the MCP OAuth redirect URI |
|
|
142
143
|
| `OPENFOX_WORKDIR` | `cwd` | Working directory |
|
|
143
144
|
| `OPENFOX_DB_PATH` | `./openfox.db` | SQLite database path |
|
|
144
145
|
| `OPENFOX_LOG_LEVEL` | `info` | Log level: `debug`, `info`, `warn`, `error` |
|
package/dist/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2.0.112 - 2026-08-03
|
|
4
|
+
|
|
5
|
+
### Bug Fixes
|
|
6
|
+
|
|
7
|
+
- **Updates install again** — the postinstall script is now bundled with the release, so `openfox update` no longer fails halfway with a missing file
|
|
8
|
+
|
|
9
|
+
## 2.0.111 - 2026-08-03
|
|
10
|
+
|
|
11
|
+
### Enhancements
|
|
12
|
+
|
|
13
|
+
- **OAuth login for MCP servers** — servers that require OAuth authorization now connect through a browser-based login flow instead of failing
|
|
14
|
+
- **Manual model entry in the provider setup** — if a provider exposes no model list, type the model name directly instead of hitting a dead-end "No models found"
|
|
15
|
+
- **You choose when to restart after an update** — updates download first and restart on your OK; service installs can opt into automatic restart
|
|
16
|
+
- **Homepage loads faster** — the session list shows the five most recent per project up front and fills in the rest lazily
|
|
17
|
+
- **Leaner session storage** — finished tool-call streaming buffers are dropped from snapshots and stale backups auto-prune after 10 days
|
|
18
|
+
|
|
19
|
+
### Bug Fixes
|
|
20
|
+
|
|
21
|
+
- **Tool calls no longer misread as interrupted** — an output that merely contains the interrupt marker text now shows as successful
|
|
22
|
+
- **Multi-statement shell commands keep their tails** — output is no longer cut at the first line for compound commands
|
|
23
|
+
- **Windows paths shorten to names again** — workspace and file names show their basename instead of the full path
|
|
24
|
+
- **Auto-compaction honors configured thresholds** — the internal cap is raised from 85%, so thresholds up to 95% work as set
|
|
25
|
+
- **Windows path-safety gaps closed** — dangerous commands outside the workdir are confirmed again in edge cases, including under Git Bash
|
|
26
|
+
- **Choice options survive reloads** — structured choices stay stable across page refreshes
|
|
27
|
+
|
|
3
28
|
## 2.0.110 - 2026-08-02
|
|
4
29
|
|
|
5
30
|
### Bug Fixes
|
|
@@ -7,7 +7,8 @@ import {
|
|
|
7
7
|
getPendingQuestionsForSession,
|
|
8
8
|
hasPendingQuestion,
|
|
9
9
|
provideAnswer
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-JURM3RPZ.js";
|
|
11
|
+
import "./chunk-LCLH6ZUL.js";
|
|
11
12
|
import "./chunk-5WRI5ZAA.js";
|
|
12
13
|
export {
|
|
13
14
|
AskUserInterrupt,
|
|
@@ -19,4 +20,4 @@ export {
|
|
|
19
20
|
hasPendingQuestion,
|
|
20
21
|
provideAnswer
|
|
21
22
|
};
|
|
22
|
-
//# sourceMappingURL=ask-
|
|
23
|
+
//# sourceMappingURL=ask-ZYPCJKZD.js.map
|
|
@@ -2,48 +2,49 @@ import {
|
|
|
2
2
|
buildRunChatTurnParams,
|
|
3
3
|
finalizeTurnCompletion,
|
|
4
4
|
generateSessionNameForSession
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-3UILDGOO.js";
|
|
6
6
|
import {
|
|
7
7
|
runChatTurn
|
|
8
|
-
} from "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
8
|
+
} from "./chunk-SDGNV45R.js";
|
|
9
|
+
import "./chunk-Z56SEG4Z.js";
|
|
10
|
+
import "./chunk-RAKPI4OE.js";
|
|
11
|
+
import "./chunk-BOSKQI62.js";
|
|
12
12
|
import "./chunk-JR54MDZI.js";
|
|
13
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-XWNCKIPO.js";
|
|
14
14
|
import "./chunk-33Q7LCVD.js";
|
|
15
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-SVJFMZ2Q.js";
|
|
16
16
|
import "./chunk-I72ACQ6R.js";
|
|
17
17
|
import "./chunk-JE7LW7Y6.js";
|
|
18
|
-
import "./chunk-
|
|
18
|
+
import "./chunk-OAN4BXEW.js";
|
|
19
19
|
import "./chunk-FR5LUTLQ.js";
|
|
20
20
|
import "./chunk-J7GAZGZT.js";
|
|
21
|
-
import "./chunk-
|
|
22
|
-
import "./chunk-
|
|
21
|
+
import "./chunk-JDT63SSP.js";
|
|
22
|
+
import "./chunk-FFPCVN5M.js";
|
|
23
23
|
import {
|
|
24
24
|
getEventStore
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-NB2D6I64.js";
|
|
26
26
|
import {
|
|
27
27
|
createChatMessageMessage,
|
|
28
28
|
createPhaseChangedMessage,
|
|
29
29
|
createSessionRunningMessage
|
|
30
|
-
} from "./chunk-
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
33
|
-
import "./chunk-
|
|
30
|
+
} from "./chunk-SYJMUIRC.js";
|
|
31
|
+
import "./chunk-N4RTAGFY.js";
|
|
32
|
+
import "./chunk-JURM3RPZ.js";
|
|
33
|
+
import "./chunk-RISQXU32.js";
|
|
34
34
|
import "./chunk-6FPGJR7O.js";
|
|
35
|
-
import "./chunk-
|
|
36
|
-
import "./chunk-
|
|
37
|
-
import "./chunk-
|
|
35
|
+
import "./chunk-QGXLZZBS.js";
|
|
36
|
+
import "./chunk-LCLH6ZUL.js";
|
|
37
|
+
import "./chunk-C5NQF2K4.js";
|
|
38
|
+
import "./chunk-JNHKKUGJ.js";
|
|
38
39
|
import "./chunk-J2GP3J3X.js";
|
|
39
40
|
import "./chunk-V4IE7HJY.js";
|
|
40
41
|
import "./chunk-YHEQTVFV.js";
|
|
41
42
|
import "./chunk-L737Y63F.js";
|
|
42
|
-
import "./chunk-
|
|
43
|
+
import "./chunk-RT2A2RRL.js";
|
|
43
44
|
import "./chunk-LCQ5AN6Y.js";
|
|
44
45
|
import "./chunk-K44MW7JJ.js";
|
|
45
|
-
import "./chunk-
|
|
46
|
-
import "./chunk-
|
|
46
|
+
import "./chunk-P45RJGOT.js";
|
|
47
|
+
import "./chunk-C372UH7N.js";
|
|
47
48
|
import "./chunk-CQGTEGKL.js";
|
|
48
49
|
import "./chunk-5WRI5ZAA.js";
|
|
49
50
|
|
|
@@ -166,4 +167,4 @@ export {
|
|
|
166
167
|
startChatSession,
|
|
167
168
|
stopSessionExecution
|
|
168
169
|
};
|
|
169
|
-
//# sourceMappingURL=chat-handler-
|
|
170
|
+
//# sourceMappingURL=chat-handler-BYXZIIV3.js.map
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
2
|
combineEventsWithSnapshot,
|
|
3
3
|
getEventStore
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-NB2D6I64.js";
|
|
5
5
|
import {
|
|
6
6
|
createContextStateMessage,
|
|
7
7
|
createSessionStateMessage
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SYJMUIRC.js";
|
|
9
9
|
import {
|
|
10
10
|
getPendingQuestionsForSession
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-JURM3RPZ.js";
|
|
12
12
|
import {
|
|
13
13
|
buildMessagesFromStoredEvents,
|
|
14
14
|
foldPendingConfirmations
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-QGXLZZBS.js";
|
|
16
16
|
import {
|
|
17
17
|
updateSessionMetadata
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-C5NQF2K4.js";
|
|
19
19
|
import {
|
|
20
20
|
getRuntimeConfig
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-JNHKKUGJ.js";
|
|
22
22
|
import {
|
|
23
23
|
getMaxVisibleItems
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-RT2A2RRL.js";
|
|
25
25
|
import {
|
|
26
26
|
logger
|
|
27
27
|
} from "./chunk-K44MW7JJ.js";
|
|
@@ -153,7 +153,7 @@ async function generateSessionNameForSession(sessionId, userMessage, deps, signa
|
|
|
153
153
|
client = deps.getLLMClient();
|
|
154
154
|
client.setModel(providerConfig.model);
|
|
155
155
|
} else if (providerConfig) {
|
|
156
|
-
const { createLLMClient } = await import("./client-
|
|
156
|
+
const { createLLMClient } = await import("./client-QNQTX5EA.js");
|
|
157
157
|
client = createLLMClient({
|
|
158
158
|
llm: {
|
|
159
159
|
baseUrl: providerConfig.baseUrl,
|
|
@@ -204,4 +204,4 @@ export {
|
|
|
204
204
|
needsNameGeneration,
|
|
205
205
|
generateSessionNameForSession
|
|
206
206
|
};
|
|
207
|
-
//# sourceMappingURL=chunk-
|
|
207
|
+
//# sourceMappingURL=chunk-3UILDGOO.js.map
|
|
@@ -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
|