openfox 2.0.66 → 2.0.68
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/dist/{chat-handler-ZRDNSLOG.js → chat-handler-QFEHJBWN.js} +13 -12
- package/dist/{chunk-R7EED6ZU.js → chunk-32KLLK4N.js} +3 -3
- package/dist/{chunk-WNA5VPZG.js → chunk-4QBDV6LX.js} +16 -13
- package/dist/{chunk-TMHWQYWE.js → chunk-64GN6OPR.js} +2 -2
- package/dist/{chunk-3ACDQKK6.js → chunk-6LK47TNE.js} +37 -138
- package/dist/{chunk-5EO6SEGV.js → chunk-7OW6X764.js} +2 -2
- package/dist/{chunk-ZUM2ZJOX.js → chunk-COWJRBV4.js} +54 -16
- package/dist/{chunk-OE5B44P6.js → chunk-DWZEGLHJ.js} +409 -143
- package/dist/{chunk-B7WGOK7G.js → chunk-E4POUD2M.js} +2 -2
- package/dist/{chunk-UBIHP5Z7.js → chunk-FCLCEIY4.js} +7 -33
- package/dist/{chunk-BL5LOLVA.js → chunk-JHGKXQBO.js} +161 -28
- package/dist/{chunk-R4UTFE63.js → chunk-QFSDJIUS.js} +8 -5
- package/dist/{chunk-BGTEIA2S.js → chunk-TFCHWMOJ.js} +23 -30
- package/dist/{chunk-OBK3I4KD.js → chunk-VLV3XWZS.js} +57 -3
- package/dist/chunk-X5DOUA3Z.js +66 -0
- package/dist/{chunk-PVRSNXD4.js → chunk-XUPKS5FL.js} +5 -3
- package/dist/{chunk-5V5DM5E4.js → chunk-YQ3MEZJL.js} +2 -2
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{client-BUX62J2K.js → client-63U5CTPE.js} +3 -3
- package/dist/{client-pure-U6ZYUPJQ.js → client-pure-XHH4RRLB.js} +2 -2
- package/dist/{compactor-V43WJ3WX.js → compactor-IPMMFFHM.js} +6 -4
- package/dist/{inspect-proxy-PKMDR47R.js → inspect-proxy-OVEFBJ26.js} +2 -2
- package/dist/{manager-344C5JLZ.js → manager-JXYRGR6B.js} +6 -2
- package/dist/{orchestrator-LZQTDOWM.js → orchestrator-GNXKJPX4.js} +12 -13
- package/dist/package.json +4 -2
- package/dist/platform-AB3GIEGO.js +21 -0
- package/dist/{processor-7KAXESY5.js → processor-TIQEQDP7.js} +13 -12
- package/dist/{protocol-42f_Png6.d.ts → protocol-DIhV-tAc.d.ts} +1 -1
- package/dist/provider/index.d.ts +4 -4
- package/dist/{provider-BDH6JGZB.js → provider-IBIWR4AI.js} +4 -4
- package/dist/{provider-manager-D3KIOD5E.js → provider-manager-7C3JVOLW.js} +4 -4
- package/dist/{serve-HGHFN3D2.js → serve-QVVZ5SJE.js} +17 -16
- package/dist/server/index.d.ts +3 -3
- package/dist/server/index.js +16 -15
- package/dist/{server-W42ENYFX.js → server-ECKS2Y3R.js} +14 -13
- package/dist/{settings-ZZ6AKFPD.js → settings-6ZPWOBWL.js} +2 -2
- package/dist/shared/index.d.ts +3 -3
- package/dist/{tools-2EB7C6H2.js → tools-QAEN5KHA.js} +11 -10
- package/dist/{types-vezAEt_y.d.ts → types-BsfYpEai.d.ts} +2 -1
- package/dist/{types-apiMd7Df.d.ts → types-CBC6lLqc.d.ts} +1 -1
- package/dist/web/assets/{index-B0Q5uK2h.css → index-BA_65WJ5.css} +1 -1
- package/dist/web/assets/index-CsZQdTAd.js +303 -0
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/dist/{worktree-EIF75WGF.js → worktree-6U45P63P.js} +6 -2
- package/package.json +4 -2
- package/plugins-registry.json +14 -0
- package/dist/web/assets/index-BhQN93bI.js +0 -303
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
tokenFromPassword,
|
|
22
22
|
verifyPassword,
|
|
23
23
|
workflowExists
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-COWJRBV4.js";
|
|
25
25
|
import {
|
|
26
26
|
agentExists,
|
|
27
27
|
createToolRegistry,
|
|
@@ -66,22 +66,22 @@ import {
|
|
|
66
66
|
setSkillEnabled,
|
|
67
67
|
skillExists,
|
|
68
68
|
updateOwnedSkill
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-6LK47TNE.js";
|
|
70
70
|
import {
|
|
71
71
|
ALWAYS_ALLOWED,
|
|
72
72
|
ALWAYS_ALLOWED_FOR_SUBAGENTS,
|
|
73
73
|
TOP_LEVEL_ONLY_TOOLS
|
|
74
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-QFSDJIUS.js";
|
|
75
75
|
import {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
} from "./chunk-BGTEIA2S.js";
|
|
76
|
+
getProject
|
|
77
|
+
} from "./chunk-KXVFHMSM.js";
|
|
79
78
|
import {
|
|
80
79
|
createMcpTools
|
|
81
80
|
} from "./chunk-NWO6GRYE.js";
|
|
82
81
|
import {
|
|
83
|
-
ensureWorktree
|
|
84
|
-
|
|
82
|
+
ensureWorktree,
|
|
83
|
+
syncIgnoredAssets
|
|
84
|
+
} from "./chunk-VLV3XWZS.js";
|
|
85
85
|
import {
|
|
86
86
|
createSession,
|
|
87
87
|
deleteSession,
|
|
@@ -113,26 +113,27 @@ import {
|
|
|
113
113
|
import {
|
|
114
114
|
createContextStateMessage
|
|
115
115
|
} from "./chunk-F4PMNP7S.js";
|
|
116
|
+
import {
|
|
117
|
+
getPathSeparator,
|
|
118
|
+
isAbsolutePath
|
|
119
|
+
} from "./chunk-X5DOUA3Z.js";
|
|
116
120
|
import {
|
|
117
121
|
deleteSetting,
|
|
118
122
|
getSetting,
|
|
119
123
|
setSetting
|
|
120
|
-
} from "./chunk-
|
|
121
|
-
import {
|
|
122
|
-
EventEmitter
|
|
123
|
-
} from "./chunk-EU3WWTFH.js";
|
|
124
|
-
import {
|
|
125
|
-
getProject
|
|
126
|
-
} from "./chunk-KXVFHMSM.js";
|
|
124
|
+
} from "./chunk-XUPKS5FL.js";
|
|
127
125
|
import {
|
|
128
126
|
initDatabase
|
|
129
127
|
} from "./chunk-GMXKJGJ2.js";
|
|
128
|
+
import {
|
|
129
|
+
EventEmitter
|
|
130
|
+
} from "./chunk-EU3WWTFH.js";
|
|
130
131
|
import {
|
|
131
132
|
createProviderManager,
|
|
132
133
|
detectModel,
|
|
133
134
|
getLlmStatus,
|
|
134
135
|
parseDefaultModelSelection
|
|
135
|
-
} from "./chunk-
|
|
136
|
+
} from "./chunk-7OW6X764.js";
|
|
136
137
|
import {
|
|
137
138
|
getModelProfile
|
|
138
139
|
} from "./chunk-V4IE7HJY.js";
|
|
@@ -160,9 +161,9 @@ import {
|
|
|
160
161
|
import express from "express";
|
|
161
162
|
import cors from "cors";
|
|
162
163
|
import { createServer as createHttpServer } from "http";
|
|
163
|
-
import { fileURLToPath as
|
|
164
|
-
import { dirname as
|
|
165
|
-
import { readFile as
|
|
164
|
+
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
165
|
+
import { dirname as dirname8, resolve as resolve7, join as join10 } from "path";
|
|
166
|
+
import { readFile as readFile5 } from "fs/promises";
|
|
166
167
|
import { createServer as createViteServer } from "vite";
|
|
167
168
|
|
|
168
169
|
// src/server/llm/mock.ts
|
|
@@ -1603,6 +1604,35 @@ var McpManager = class {
|
|
|
1603
1604
|
}
|
|
1604
1605
|
};
|
|
1605
1606
|
|
|
1607
|
+
// src/server/git/worktree-config.ts
|
|
1608
|
+
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
1609
|
+
import { resolve, join } from "path";
|
|
1610
|
+
var CONFIG_FILENAME = ".openfox/worktree.json";
|
|
1611
|
+
function getConfigPath(workdir) {
|
|
1612
|
+
return join(resolve(workdir), CONFIG_FILENAME);
|
|
1613
|
+
}
|
|
1614
|
+
async function loadWorktreeConfig(workdir) {
|
|
1615
|
+
try {
|
|
1616
|
+
const configPath = getConfigPath(workdir);
|
|
1617
|
+
const raw = await readFile(configPath, "utf-8");
|
|
1618
|
+
const parsed = JSON.parse(raw);
|
|
1619
|
+
if (!parsed.ignoredAssets) return null;
|
|
1620
|
+
return {
|
|
1621
|
+
ignoredAssets: parsed.ignoredAssets,
|
|
1622
|
+
overrides: parsed.overrides ?? void 0
|
|
1623
|
+
};
|
|
1624
|
+
} catch {
|
|
1625
|
+
return null;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
async function saveWorktreeConfig(workdir, config3) {
|
|
1629
|
+
const resolved = resolve(workdir);
|
|
1630
|
+
const dirPath = join(resolved, ".openfox");
|
|
1631
|
+
await mkdir(dirPath, { recursive: true });
|
|
1632
|
+
const configPath = getConfigPath(workdir);
|
|
1633
|
+
await writeFile(configPath, JSON.stringify(config3, null, 2) + "\n", "utf-8");
|
|
1634
|
+
}
|
|
1635
|
+
|
|
1606
1636
|
// src/server/lsp/server.ts
|
|
1607
1637
|
import { spawn } from "child_process";
|
|
1608
1638
|
import { extname } from "path";
|
|
@@ -1925,19 +1955,19 @@ var LspServer = class {
|
|
|
1925
1955
|
*/
|
|
1926
1956
|
async getDiagnosticsWithWait(path, timeoutMs = DIAGNOSTIC_WAIT_MS) {
|
|
1927
1957
|
if (this.openDocuments.has(path)) {
|
|
1928
|
-
return new Promise((
|
|
1958
|
+
return new Promise((resolve8) => {
|
|
1929
1959
|
const existing = this.diagnostics.get(path);
|
|
1930
1960
|
if (existing !== void 0) {
|
|
1931
1961
|
setTimeout(() => {
|
|
1932
|
-
|
|
1962
|
+
resolve8(this.diagnostics.get(path) ?? []);
|
|
1933
1963
|
}, 100);
|
|
1934
1964
|
return;
|
|
1935
1965
|
}
|
|
1936
1966
|
const timeout = setTimeout(() => {
|
|
1937
1967
|
this.pendingDiagnostics.delete(path);
|
|
1938
|
-
|
|
1968
|
+
resolve8(this.diagnostics.get(path) ?? []);
|
|
1939
1969
|
}, timeoutMs);
|
|
1940
|
-
this.pendingDiagnostics.set(path, { resolve:
|
|
1970
|
+
this.pendingDiagnostics.set(path, { resolve: resolve8, timeout });
|
|
1941
1971
|
});
|
|
1942
1972
|
}
|
|
1943
1973
|
return this.diagnostics.get(path) ?? [];
|
|
@@ -2148,14 +2178,14 @@ import { readFileSync as readFileSync2 } from "fs";
|
|
|
2148
2178
|
|
|
2149
2179
|
// src/server/utils/which.ts
|
|
2150
2180
|
import { access, constants } from "fs/promises";
|
|
2151
|
-
import { join, dirname } from "path";
|
|
2181
|
+
import { join as join2, dirname } from "path";
|
|
2152
2182
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
2153
2183
|
var __dirname = dirname(fileURLToPath2(import.meta.url));
|
|
2154
2184
|
function getBundledBinPaths() {
|
|
2155
2185
|
const paths = [];
|
|
2156
|
-
paths.push(
|
|
2157
|
-
paths.push(
|
|
2158
|
-
paths.push(
|
|
2186
|
+
paths.push(join2(process.cwd(), "node_modules", ".bin"));
|
|
2187
|
+
paths.push(join2(__dirname, "..", "..", "..", "node_modules", ".bin"));
|
|
2188
|
+
paths.push(join2(__dirname, "..", "..", "..", "..", "node_modules", ".bin"));
|
|
2159
2189
|
return paths;
|
|
2160
2190
|
}
|
|
2161
2191
|
async function existsExecutable(path) {
|
|
@@ -2174,13 +2204,13 @@ async function which(command, workdir) {
|
|
|
2174
2204
|
return null;
|
|
2175
2205
|
}
|
|
2176
2206
|
for (const binDir of getBundledBinPaths()) {
|
|
2177
|
-
const fullPath =
|
|
2207
|
+
const fullPath = join2(binDir, command);
|
|
2178
2208
|
if (await existsExecutable(fullPath)) {
|
|
2179
2209
|
return fullPath;
|
|
2180
2210
|
}
|
|
2181
2211
|
}
|
|
2182
2212
|
if (workdir) {
|
|
2183
|
-
const projectBin =
|
|
2213
|
+
const projectBin = join2(workdir, "node_modules", ".bin", command);
|
|
2184
2214
|
if (await existsExecutable(projectBin)) {
|
|
2185
2215
|
return projectBin;
|
|
2186
2216
|
}
|
|
@@ -2189,7 +2219,7 @@ async function which(command, workdir) {
|
|
|
2189
2219
|
const paths = pathEnv.split(getPathSeparator());
|
|
2190
2220
|
for (const dir of paths) {
|
|
2191
2221
|
if (!dir) continue;
|
|
2192
|
-
const fullPath =
|
|
2222
|
+
const fullPath = join2(dir, command);
|
|
2193
2223
|
if (await existsExecutable(fullPath)) {
|
|
2194
2224
|
return fullPath;
|
|
2195
2225
|
}
|
|
@@ -2201,9 +2231,9 @@ async function which(command, workdir) {
|
|
|
2201
2231
|
import { extname as extname2, basename } from "path";
|
|
2202
2232
|
import { readFileSync } from "fs";
|
|
2203
2233
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2204
|
-
import { dirname as dirname2, resolve } from "path";
|
|
2234
|
+
import { dirname as dirname2, resolve as resolve2 } from "path";
|
|
2205
2235
|
var __dirname2 = dirname2(fileURLToPath3(import.meta.url));
|
|
2206
|
-
var languagesJson = JSON.parse(readFileSync(
|
|
2236
|
+
var languagesJson = JSON.parse(readFileSync(resolve2(__dirname2, "languages.json"), "utf-8"));
|
|
2207
2237
|
var LANGUAGES = languagesJson;
|
|
2208
2238
|
var extensionToLanguage = /* @__PURE__ */ new Map();
|
|
2209
2239
|
for (const lang of LANGUAGES) {
|
|
@@ -3181,6 +3211,10 @@ var SessionManager = class {
|
|
|
3181
3211
|
if (!project) throw new Error(`Project not found: ${session.projectId}`);
|
|
3182
3212
|
if (session.worktree) throw new Error("Session already has a worktree");
|
|
3183
3213
|
const result = await ensureWorktree(project.workdir, name);
|
|
3214
|
+
const wtConfig = await loadWorktreeConfig(project.workdir);
|
|
3215
|
+
if (wtConfig) {
|
|
3216
|
+
await syncIgnoredAssets(project.workdir, result.path, wtConfig);
|
|
3217
|
+
}
|
|
3184
3218
|
updateSessionWorkdir(sessionId, project.workdir, result.path);
|
|
3185
3219
|
try {
|
|
3186
3220
|
await shutdownLspManager(sessionId);
|
|
@@ -3245,6 +3279,11 @@ All file and git operations should use this directory.
|
|
|
3245
3279
|
if (!project) throw new Error(`Project not found: ${session.projectId}`);
|
|
3246
3280
|
const closedPath = session.worktree;
|
|
3247
3281
|
const branchName = closedPath.includes("/worktrees/") ? closedPath.split("/worktrees/")[1] ?? closedPath : closedPath;
|
|
3282
|
+
try {
|
|
3283
|
+
await devServerManager.stop(closedPath);
|
|
3284
|
+
} catch (err) {
|
|
3285
|
+
logger.error("Error stopping dev server for worktree close", { sessionId, worktree: closedPath, error: err });
|
|
3286
|
+
}
|
|
3248
3287
|
updateSessionWorkdir(sessionId, project.workdir, null);
|
|
3249
3288
|
try {
|
|
3250
3289
|
await shutdownLspManager(sessionId);
|
|
@@ -3367,15 +3406,15 @@ Operating in the original project directory at ${project.workdir}.
|
|
|
3367
3406
|
// src/server/routes/skills.ts
|
|
3368
3407
|
import { Router as Router2 } from "express";
|
|
3369
3408
|
import multer from "multer";
|
|
3370
|
-
import { access as access2, mkdir as
|
|
3409
|
+
import { access as access2, mkdir as mkdir3, realpath, stat } from "fs/promises";
|
|
3371
3410
|
import { constants as constants2 } from "fs";
|
|
3372
3411
|
import { homedir } from "os";
|
|
3373
|
-
import { isAbsolute as isAbsolute2, join as
|
|
3412
|
+
import { isAbsolute as isAbsolute2, join as join5, resolve as resolve3 } from "path";
|
|
3374
3413
|
|
|
3375
3414
|
// src/server/skills/installer.ts
|
|
3376
3415
|
import { randomUUID } from "crypto";
|
|
3377
|
-
import { mkdir, readFile, rename, rm, writeFile } from "fs/promises";
|
|
3378
|
-
import { dirname as dirname3, isAbsolute, join as
|
|
3416
|
+
import { mkdir as mkdir2, readFile as readFile2, rename, rm, writeFile as writeFile2 } from "fs/promises";
|
|
3417
|
+
import { dirname as dirname3, isAbsolute, join as join3 } from "path";
|
|
3379
3418
|
import matter from "gray-matter";
|
|
3380
3419
|
var SkillInstallError = class extends Error {
|
|
3381
3420
|
constructor(message, status) {
|
|
@@ -3407,17 +3446,17 @@ async function installSkillPackage(libraryDir, packageName, files) {
|
|
|
3407
3446
|
totalBytes += file.content.byteLength;
|
|
3408
3447
|
}
|
|
3409
3448
|
if (totalBytes > 50 * 1024 * 1024) throw new SkillInstallError("Package exceeds 50 MiB", 413);
|
|
3410
|
-
const destination =
|
|
3449
|
+
const destination = join3(libraryDir, packageName);
|
|
3411
3450
|
if (await pathExists(destination)) throw new SkillInstallError("A package with this name already exists", 409);
|
|
3412
|
-
const staging =
|
|
3451
|
+
const staging = join3(libraryDir, `.${packageName}.openfox-upload-${randomUUID()}`);
|
|
3413
3452
|
try {
|
|
3414
|
-
await
|
|
3453
|
+
await mkdir2(staging, { recursive: false });
|
|
3415
3454
|
for (const file of files) {
|
|
3416
|
-
const target =
|
|
3417
|
-
await
|
|
3418
|
-
await
|
|
3455
|
+
const target = join3(staging, file.path);
|
|
3456
|
+
await mkdir2(dirname3(target), { recursive: true });
|
|
3457
|
+
await writeFile2(target, file.content);
|
|
3419
3458
|
}
|
|
3420
|
-
const parsed = matter(await
|
|
3459
|
+
const parsed = matter(await readFile2(join3(staging, "SKILL.md"), "utf-8"));
|
|
3421
3460
|
const name = typeof parsed.data["name"] === "string" ? parsed.data["name"].trim() : "";
|
|
3422
3461
|
const description = typeof parsed.data["description"] === "string" ? parsed.data["description"].trim() : "";
|
|
3423
3462
|
if (!name || !description || !parsed.content.trim()) {
|
|
@@ -3434,7 +3473,7 @@ async function installSkillPackage(libraryDir, packageName, files) {
|
|
|
3434
3473
|
|
|
3435
3474
|
// src/server/routes/crud-helpers.ts
|
|
3436
3475
|
import { Router } from "express";
|
|
3437
|
-
import { join as
|
|
3476
|
+
import { join as join4 } from "path";
|
|
3438
3477
|
function computeOverrideIds(defaults, userItems) {
|
|
3439
3478
|
return userItems.filter((u) => defaults.some((d) => d.metadata.id === u.metadata.id)).map((u) => u.metadata.id);
|
|
3440
3479
|
}
|
|
@@ -3446,7 +3485,7 @@ function validateNameIdPrompt(body) {
|
|
|
3446
3485
|
return null;
|
|
3447
3486
|
}
|
|
3448
3487
|
function getProjectItemPath(projectDir, dirName, id, ext) {
|
|
3449
|
-
return
|
|
3488
|
+
return join4(projectDir, ".openfox", dirName, `${id}${ext}`);
|
|
3450
3489
|
}
|
|
3451
3490
|
async function isProjectItem(projectDir, dirName, id, ext) {
|
|
3452
3491
|
if (!projectDir) return false;
|
|
@@ -3591,7 +3630,7 @@ var upload = multer({
|
|
|
3591
3630
|
});
|
|
3592
3631
|
function expandHome(path) {
|
|
3593
3632
|
if (path === "~") return homedir();
|
|
3594
|
-
return path.startsWith("~/") ?
|
|
3633
|
+
return path.startsWith("~/") ? join5(homedir(), path.slice(2)) : path;
|
|
3595
3634
|
}
|
|
3596
3635
|
function configuredDirectory() {
|
|
3597
3636
|
const raw = getSetting(SKILL_DIRECTORIES_SETTING);
|
|
@@ -3604,13 +3643,13 @@ function configuredDirectory() {
|
|
|
3604
3643
|
}
|
|
3605
3644
|
}
|
|
3606
3645
|
function defaultLibrary(configDir) {
|
|
3607
|
-
const path =
|
|
3646
|
+
const path = resolve3(configDir, "skills");
|
|
3608
3647
|
return { configuredPath: path, resolvedPath: path, available: true, custom: false };
|
|
3609
3648
|
}
|
|
3610
3649
|
async function resolveLibrary(path) {
|
|
3611
3650
|
const expanded = expandHome(path);
|
|
3612
3651
|
if (!isAbsolute2(expanded)) throw new Error("Selected path must be absolute");
|
|
3613
|
-
const absolute =
|
|
3652
|
+
const absolute = resolve3(expanded);
|
|
3614
3653
|
const info = await stat(absolute);
|
|
3615
3654
|
if (!info.isDirectory()) throw new Error("Selected path is not a directory");
|
|
3616
3655
|
await access2(absolute, constants2.R_OK);
|
|
@@ -3699,7 +3738,7 @@ function createSkillRoutes(configDir, projectDir) {
|
|
|
3699
3738
|
try {
|
|
3700
3739
|
const configured = configuredDirectory();
|
|
3701
3740
|
const library = configured ? await resolveLibrary(configured) : defaultLibrary(configDir);
|
|
3702
|
-
await
|
|
3741
|
+
await mkdir3(library.resolvedPath, { recursive: true });
|
|
3703
3742
|
const packageName = String(req.body["packageName"] ?? "");
|
|
3704
3743
|
const paths = JSON.parse(String(req.body["paths"] ?? "[]"));
|
|
3705
3744
|
const files = req.files;
|
|
@@ -3749,19 +3788,19 @@ function createSkillRoutes(configDir, projectDir) {
|
|
|
3749
3788
|
}
|
|
3750
3789
|
|
|
3751
3790
|
// src/server/commands/registry.ts
|
|
3752
|
-
import { writeFile as
|
|
3753
|
-
import { join as
|
|
3791
|
+
import { writeFile as writeFile3, mkdir as mkdir4, unlink } from "fs/promises";
|
|
3792
|
+
import { join as join6, dirname as dirname4 } from "path";
|
|
3754
3793
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
3755
3794
|
import matter2 from "gray-matter";
|
|
3756
3795
|
var __bundleDir = dirname4(fileURLToPath4(import.meta.url));
|
|
3757
|
-
var DEFAULTS_DIR =
|
|
3758
|
-
var DEFAULTS_DIR_ALT =
|
|
3796
|
+
var DEFAULTS_DIR = join6(__bundleDir, "defaults");
|
|
3797
|
+
var DEFAULTS_DIR_ALT = join6(__bundleDir, "command-defaults");
|
|
3759
3798
|
var COMMAND_EXTENSION = ".command.md";
|
|
3760
3799
|
function getCommandsDir(configDir) {
|
|
3761
|
-
return
|
|
3800
|
+
return join6(configDir, "commands");
|
|
3762
3801
|
}
|
|
3763
3802
|
function getProjectCommandsDir(projectDir) {
|
|
3764
|
-
return
|
|
3803
|
+
return join6(projectDir, ".openfox", "commands");
|
|
3765
3804
|
}
|
|
3766
3805
|
async function loadDefaultCommands() {
|
|
3767
3806
|
let defaults = await loadItemsFromDir(DEFAULTS_DIR, {
|
|
@@ -3818,19 +3857,19 @@ function findCommandById(commandId, commands) {
|
|
|
3818
3857
|
return commands.find((c) => c.metadata.id === commandId);
|
|
3819
3858
|
}
|
|
3820
3859
|
async function commandExists(configDir, commandId, projectDir) {
|
|
3821
|
-
if (await pathExists(
|
|
3822
|
-
if (projectDir && await pathExists(
|
|
3860
|
+
if (await pathExists(join6(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`))) return true;
|
|
3861
|
+
if (projectDir && await pathExists(join6(getProjectCommandsDir(projectDir), `${commandId}${COMMAND_EXTENSION}`)))
|
|
3823
3862
|
return true;
|
|
3824
3863
|
return false;
|
|
3825
3864
|
}
|
|
3826
3865
|
async function saveCommand(configDir, command) {
|
|
3827
3866
|
const commandsDir = getCommandsDir(configDir);
|
|
3828
3867
|
if (!await pathExists(commandsDir)) {
|
|
3829
|
-
await
|
|
3868
|
+
await mkdir4(commandsDir, { recursive: true });
|
|
3830
3869
|
}
|
|
3831
|
-
const filePath =
|
|
3870
|
+
const filePath = join6(commandsDir, `${command.metadata.id}${COMMAND_EXTENSION}`);
|
|
3832
3871
|
const content = matter2.stringify(command.prompt, command.metadata);
|
|
3833
|
-
await
|
|
3872
|
+
await writeFile3(filePath, content, "utf-8");
|
|
3834
3873
|
}
|
|
3835
3874
|
async function saveCommandToProject(projectDir, command) {
|
|
3836
3875
|
await saveItemToDir(
|
|
@@ -3848,7 +3887,7 @@ async function deleteCommand(configDir, commandId) {
|
|
|
3848
3887
|
if (isDefault) {
|
|
3849
3888
|
return { success: false, reason: "Cannot delete built-in defaults" };
|
|
3850
3889
|
}
|
|
3851
|
-
const filePath =
|
|
3890
|
+
const filePath = join6(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`);
|
|
3852
3891
|
try {
|
|
3853
3892
|
await unlink(filePath);
|
|
3854
3893
|
return { success: true };
|
|
@@ -4028,10 +4067,38 @@ function createDevServerRoutes() {
|
|
|
4028
4067
|
return router;
|
|
4029
4068
|
}
|
|
4030
4069
|
|
|
4031
|
-
// src/server/routes/
|
|
4070
|
+
// src/server/routes/worktree-config.ts
|
|
4032
4071
|
import { Router as Router5 } from "express";
|
|
4033
|
-
function
|
|
4072
|
+
function createWorktreeConfigRoutes() {
|
|
4034
4073
|
const router = Router5();
|
|
4074
|
+
router.get("/config", async (req, res) => {
|
|
4075
|
+
const workdir = req.query["workdir"];
|
|
4076
|
+
if (!workdir) return res.status(400).json({ error: "workdir required" });
|
|
4077
|
+
const config3 = await loadWorktreeConfig(workdir);
|
|
4078
|
+
res.json({ config: config3 });
|
|
4079
|
+
});
|
|
4080
|
+
router.post("/config", async (req, res) => {
|
|
4081
|
+
const workdir = req.query["workdir"];
|
|
4082
|
+
if (!workdir) return res.status(400).json({ error: "workdir required" });
|
|
4083
|
+
const { ignoredAssets, overrides } = req.body;
|
|
4084
|
+
if (!ignoredAssets || !["symlink", "copy", "skip"].includes(ignoredAssets)) {
|
|
4085
|
+
return res.status(400).json({ error: "ignoredAssets must be one of: symlink, copy, skip" });
|
|
4086
|
+
}
|
|
4087
|
+
try {
|
|
4088
|
+
const config3 = { ignoredAssets, overrides: overrides ?? void 0 };
|
|
4089
|
+
await saveWorktreeConfig(workdir, config3);
|
|
4090
|
+
res.json({ config: config3 });
|
|
4091
|
+
} catch (err) {
|
|
4092
|
+
res.status(500).json({ error: err instanceof Error ? err.message : "Failed to save config" });
|
|
4093
|
+
}
|
|
4094
|
+
});
|
|
4095
|
+
return router;
|
|
4096
|
+
}
|
|
4097
|
+
|
|
4098
|
+
// src/server/routes/terminals.ts
|
|
4099
|
+
import { Router as Router6 } from "express";
|
|
4100
|
+
function createTerminalRoutes() {
|
|
4101
|
+
const router = Router6();
|
|
4035
4102
|
router.get("/", (req, res) => {
|
|
4036
4103
|
const projectId = req.query["projectId"];
|
|
4037
4104
|
const sessions = projectId ? terminalManager.getByProject(projectId) : [];
|
|
@@ -4070,20 +4137,20 @@ function createTerminalRoutes() {
|
|
|
4070
4137
|
}
|
|
4071
4138
|
|
|
4072
4139
|
// src/server/routes/directories.ts
|
|
4073
|
-
import { Router as
|
|
4140
|
+
import { Router as Router7 } from "express";
|
|
4074
4141
|
import { readdir } from "fs/promises";
|
|
4075
|
-
import { resolve as
|
|
4142
|
+
import { resolve as resolve4, join as join7, dirname as dirname5, basename as basename2 } from "path";
|
|
4076
4143
|
function createDirectoryRoutes() {
|
|
4077
|
-
const router =
|
|
4144
|
+
const router = Router7();
|
|
4078
4145
|
const DEFAULT_BASE_PATH = process.cwd();
|
|
4079
4146
|
router.get("/", async (req, res) => {
|
|
4080
4147
|
const path = req.query["path"] || DEFAULT_BASE_PATH;
|
|
4081
4148
|
try {
|
|
4082
|
-
const resolvedPath =
|
|
4149
|
+
const resolvedPath = resolve4(path);
|
|
4083
4150
|
const entries = await readdir(resolvedPath, { withFileTypes: true });
|
|
4084
4151
|
const directories = entries.filter((entry) => entry.isDirectory()).map((entry) => ({
|
|
4085
4152
|
name: entry.name,
|
|
4086
|
-
path:
|
|
4153
|
+
path: join7(resolvedPath, entry.name)
|
|
4087
4154
|
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
4088
4155
|
const parent = dirname5(resolvedPath);
|
|
4089
4156
|
const hasParent = parent !== resolvedPath;
|
|
@@ -4107,10 +4174,10 @@ function createDirectoryRoutes() {
|
|
|
4107
4174
|
}
|
|
4108
4175
|
|
|
4109
4176
|
// src/server/routes/file-search.ts
|
|
4110
|
-
import { Router as
|
|
4177
|
+
import { Router as Router8 } from "express";
|
|
4111
4178
|
import fg from "fast-glob";
|
|
4112
4179
|
function createFileSearchRoutes() {
|
|
4113
|
-
const router =
|
|
4180
|
+
const router = Router8();
|
|
4114
4181
|
router.get("/", async (req, res) => {
|
|
4115
4182
|
const query = req.query["q"] || "";
|
|
4116
4183
|
const workdir = req.query["workdir"] || process.cwd();
|
|
@@ -4186,11 +4253,11 @@ function fuzzyScore(filePath, query) {
|
|
|
4186
4253
|
}
|
|
4187
4254
|
|
|
4188
4255
|
// src/server/routes/auto-update.ts
|
|
4189
|
-
import { Router as
|
|
4256
|
+
import { Router as Router9 } from "express";
|
|
4190
4257
|
import { spawn as spawn2 } from "child_process";
|
|
4191
4258
|
|
|
4192
4259
|
// src/constants.ts
|
|
4193
|
-
var VERSION = "2.0.
|
|
4260
|
+
var VERSION = "2.0.68";
|
|
4194
4261
|
|
|
4195
4262
|
// src/server/routes/auto-update.ts
|
|
4196
4263
|
var updateInProgress = false;
|
|
@@ -4208,12 +4275,12 @@ async function checkAuth(req, opts) {
|
|
|
4208
4275
|
return true;
|
|
4209
4276
|
}
|
|
4210
4277
|
function createAutoUpdateRoutes(options = {}) {
|
|
4211
|
-
const router =
|
|
4278
|
+
const router = Router9();
|
|
4212
4279
|
router.get("/check", async (_req, res) => {
|
|
4213
4280
|
const isService = isRunningAsService();
|
|
4214
4281
|
const current = VERSION;
|
|
4215
4282
|
try {
|
|
4216
|
-
const latest = await new Promise((
|
|
4283
|
+
const latest = await new Promise((resolve8, reject) => {
|
|
4217
4284
|
const child = spawn2("npm", ["view", "openfox", "version"], {
|
|
4218
4285
|
stdio: ["ignore", "pipe", "pipe"],
|
|
4219
4286
|
windowsHide: true
|
|
@@ -4224,7 +4291,7 @@ function createAutoUpdateRoutes(options = {}) {
|
|
|
4224
4291
|
});
|
|
4225
4292
|
child.on("close", (code) => {
|
|
4226
4293
|
if (code === 0) {
|
|
4227
|
-
|
|
4294
|
+
resolve8(stdout.trim());
|
|
4228
4295
|
} else {
|
|
4229
4296
|
reject(new Error(`npm view exited with code ${code}`));
|
|
4230
4297
|
}
|
|
@@ -4268,9 +4335,9 @@ function createAutoUpdateRoutes(options = {}) {
|
|
|
4268
4335
|
const timeout = setTimeout(() => {
|
|
4269
4336
|
child.kill();
|
|
4270
4337
|
}, UPDATE_TIMEOUT);
|
|
4271
|
-
const exitCode = await new Promise((
|
|
4272
|
-
child.on("close",
|
|
4273
|
-
child.on("error", () =>
|
|
4338
|
+
const exitCode = await new Promise((resolve8) => {
|
|
4339
|
+
child.on("close", resolve8);
|
|
4340
|
+
child.on("error", () => resolve8(1));
|
|
4274
4341
|
});
|
|
4275
4342
|
clearTimeout(timeout);
|
|
4276
4343
|
if (exitCode === 0) {
|
|
@@ -4308,9 +4375,9 @@ function createAutoUpdateRoutes(options = {}) {
|
|
|
4308
4375
|
}
|
|
4309
4376
|
|
|
4310
4377
|
// src/server/routes/provider-auth.ts
|
|
4311
|
-
import { Router as
|
|
4378
|
+
import { Router as Router10 } from "express";
|
|
4312
4379
|
function createProviderAuthRoutes(config3, providerManager, registry) {
|
|
4313
|
-
const router =
|
|
4380
|
+
const router = Router10();
|
|
4314
4381
|
function resolveAuthContext(providerId, res) {
|
|
4315
4382
|
const provider = providerManager.getProviders().find((item) => item.id === providerId);
|
|
4316
4383
|
if (!provider) {
|
|
@@ -4433,14 +4500,16 @@ var ProviderRegistry = class {
|
|
|
4433
4500
|
}
|
|
4434
4501
|
register(map, id, value, kind) {
|
|
4435
4502
|
if (!id.trim()) throw new Error(`Provider ${kind} id cannot be empty`);
|
|
4436
|
-
if (map.has(id))
|
|
4503
|
+
if (map.has(id)) {
|
|
4504
|
+
map.delete(id);
|
|
4505
|
+
}
|
|
4437
4506
|
map.set(id, value);
|
|
4438
4507
|
}
|
|
4439
4508
|
};
|
|
4440
4509
|
|
|
4441
4510
|
// src/server/providers/plugins/loader.ts
|
|
4442
|
-
import { readdir as readdir2, readFile as
|
|
4443
|
-
import { dirname as dirname6, join as
|
|
4511
|
+
import { readdir as readdir2, readFile as readFile3, stat as stat2 } from "fs/promises";
|
|
4512
|
+
import { dirname as dirname6, join as join8, resolve as resolve5 } from "path";
|
|
4444
4513
|
import { fileURLToPath as fileURLToPath5, pathToFileURL } from "url";
|
|
4445
4514
|
async function packageDirectories(root) {
|
|
4446
4515
|
let entries;
|
|
@@ -4451,13 +4520,13 @@ async function packageDirectories(root) {
|
|
|
4451
4520
|
}
|
|
4452
4521
|
const directories = [];
|
|
4453
4522
|
for (const entry of entries) {
|
|
4454
|
-
const entryPath =
|
|
4523
|
+
const entryPath = join8(root, entry.name);
|
|
4455
4524
|
const isDirectory = entry.isDirectory() || entry.isSymbolicLink() && (await stat2(entryPath).catch(() => void 0))?.isDirectory();
|
|
4456
4525
|
if (!isDirectory) continue;
|
|
4457
4526
|
if (entry.name.startsWith("@")) {
|
|
4458
4527
|
const scoped = await readdir2(entryPath, { withFileTypes: true }).catch(() => []);
|
|
4459
4528
|
for (const child of scoped) {
|
|
4460
|
-
const childPath =
|
|
4529
|
+
const childPath = join8(entryPath, child.name);
|
|
4461
4530
|
const childIsDirectory = child.isDirectory() || child.isSymbolicLink() && (await stat2(childPath).catch(() => void 0))?.isDirectory();
|
|
4462
4531
|
if (childIsDirectory) directories.push(childPath);
|
|
4463
4532
|
}
|
|
@@ -4470,19 +4539,19 @@ async function packageDirectories(root) {
|
|
|
4470
4539
|
async function loadProviderPlugins(options) {
|
|
4471
4540
|
const moduleDirectory = dirname6(fileURLToPath5(import.meta.url));
|
|
4472
4541
|
const roots = [
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4542
|
+
join8(options.configDirectory, "plugins"),
|
|
4543
|
+
join8(options.cwd ?? process.cwd(), "node_modules"),
|
|
4544
|
+
resolve5(moduleDirectory, "node_modules"),
|
|
4545
|
+
resolve5(moduleDirectory, "../../../../node_modules")
|
|
4477
4546
|
];
|
|
4478
4547
|
const seen = /* @__PURE__ */ new Set();
|
|
4479
4548
|
const diagnostics = [];
|
|
4480
4549
|
for (const root of roots) {
|
|
4481
4550
|
for (const packageDir of await packageDirectories(root)) {
|
|
4482
|
-
const manifestPath =
|
|
4551
|
+
const manifestPath = join8(packageDir, "package.json");
|
|
4483
4552
|
let manifest;
|
|
4484
4553
|
try {
|
|
4485
|
-
manifest = JSON.parse(await
|
|
4554
|
+
manifest = JSON.parse(await readFile3(manifestPath, "utf8"));
|
|
4486
4555
|
} catch {
|
|
4487
4556
|
continue;
|
|
4488
4557
|
}
|
|
@@ -4520,7 +4589,7 @@ async function loadProviderPlugins(options) {
|
|
|
4520
4589
|
}
|
|
4521
4590
|
};
|
|
4522
4591
|
try {
|
|
4523
|
-
const module = await import(pathToFileURL(
|
|
4592
|
+
const module = await import(pathToFileURL(join8(packageDir, plugin)).href);
|
|
4524
4593
|
if (typeof module.register !== "function") throw new Error("Plugin does not export register(registry)");
|
|
4525
4594
|
await module.register(trackingRegistry);
|
|
4526
4595
|
diagnostic.loaded = true;
|
|
@@ -4532,8 +4601,199 @@ async function loadProviderPlugins(options) {
|
|
|
4532
4601
|
return diagnostics;
|
|
4533
4602
|
}
|
|
4534
4603
|
|
|
4604
|
+
// src/server/routes/plugins.ts
|
|
4605
|
+
import { Router as Router11 } from "express";
|
|
4606
|
+
import { fileURLToPath as fileURLToPath6, pathToFileURL as pathToFileURL2 } from "url";
|
|
4607
|
+
import { dirname as dirname7, resolve as resolve6, join as join9 } from "path";
|
|
4608
|
+
import { readFile as readFile4, readdir as readdir3, rm as rm2, rename as rename2 } from "fs/promises";
|
|
4609
|
+
import { platform } from "os";
|
|
4610
|
+
import { execFile } from "child_process";
|
|
4611
|
+
import { promisify } from "util";
|
|
4612
|
+
var execFileP = promisify(execFile);
|
|
4613
|
+
async function openFolder(dir, res) {
|
|
4614
|
+
try {
|
|
4615
|
+
await execFileP("mkdir", ["-p", dir], { timeout: 5e3 });
|
|
4616
|
+
const cmd = platform() === "darwin" ? "open" : platform() === "win32" ? "explorer" : "xdg-open";
|
|
4617
|
+
await execFileP(cmd, [dir], { timeout: 5e3 });
|
|
4618
|
+
res.json({ success: true });
|
|
4619
|
+
} catch (err) {
|
|
4620
|
+
res.status(500).json({ error: err instanceof Error ? err.message : "Failed to open folder" });
|
|
4621
|
+
}
|
|
4622
|
+
}
|
|
4623
|
+
function createPluginRoutes(options) {
|
|
4624
|
+
const router = Router11();
|
|
4625
|
+
const { config: config3, providerAdapters, pluginDiagnostics, logger: logger2 } = options;
|
|
4626
|
+
let registryCache = null;
|
|
4627
|
+
router.get("/registry", async (_req, res) => {
|
|
4628
|
+
try {
|
|
4629
|
+
const now = Date.now();
|
|
4630
|
+
if (registryCache && now - registryCache.ts < 3e5) {
|
|
4631
|
+
return res.json({ plugins: registryCache.data });
|
|
4632
|
+
}
|
|
4633
|
+
const moduleDir = dirname7(fileURLToPath6(import.meta.url));
|
|
4634
|
+
const registryPath = resolve6(moduleDir, "../../../plugins-registry.json");
|
|
4635
|
+
const data = JSON.parse(await readFile4(registryPath, "utf8"));
|
|
4636
|
+
registryCache = { data, ts: now };
|
|
4637
|
+
res.json({ plugins: data });
|
|
4638
|
+
} catch (err) {
|
|
4639
|
+
logger2.error("Failed to load plugin registry", { error: String(err) });
|
|
4640
|
+
res.json({ plugins: [] });
|
|
4641
|
+
}
|
|
4642
|
+
});
|
|
4643
|
+
router.post("/install", async (req, res) => {
|
|
4644
|
+
const { githubUrl } = req.body;
|
|
4645
|
+
if (!githubUrl || typeof githubUrl !== "string") {
|
|
4646
|
+
return res.status(400).json({ error: "githubUrl is required" });
|
|
4647
|
+
}
|
|
4648
|
+
const parsed = githubUrl.match(/github\.com\/([^/]+)\/([^/]+?)(?:\/|$)/);
|
|
4649
|
+
if (!parsed) {
|
|
4650
|
+
return res.status(400).json({ error: "Invalid GitHub URL" });
|
|
4651
|
+
}
|
|
4652
|
+
const repoName = parsed[2].replace(/\.git$/, "");
|
|
4653
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(repoName)) {
|
|
4654
|
+
return res.status(400).json({ error: "Invalid repository name" });
|
|
4655
|
+
}
|
|
4656
|
+
const pluginsDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
|
|
4657
|
+
const targetDir = join9(pluginsDir, repoName);
|
|
4658
|
+
const tmpDir = join9(pluginsDir, `.${repoName}-tmp-${Date.now()}`);
|
|
4659
|
+
try {
|
|
4660
|
+
await execFileP("mkdir", ["-p", pluginsDir], { timeout: 5e3 });
|
|
4661
|
+
} catch {
|
|
4662
|
+
return res.status(500).json({ error: "Failed to create plugins directory" });
|
|
4663
|
+
}
|
|
4664
|
+
let gitOk = false;
|
|
4665
|
+
try {
|
|
4666
|
+
const { stdout } = await execFileP("git", ["--version"], { timeout: 5e3 });
|
|
4667
|
+
gitOk = stdout.includes("git version");
|
|
4668
|
+
} catch {
|
|
4669
|
+
}
|
|
4670
|
+
if (!gitOk) {
|
|
4671
|
+
return res.status(500).json({ error: "git is not installed or not found in PATH" });
|
|
4672
|
+
}
|
|
4673
|
+
try {
|
|
4674
|
+
const cloneUrl = githubUrl.replace(/\/$/, "") + ".git";
|
|
4675
|
+
await execFileP("git", ["clone", "--depth", "1", cloneUrl, tmpDir], { timeout: 6e4 });
|
|
4676
|
+
await rm2(targetDir, { recursive: true, force: true });
|
|
4677
|
+
await rename2(tmpDir, targetDir);
|
|
4678
|
+
let loaded = false;
|
|
4679
|
+
let loadError;
|
|
4680
|
+
try {
|
|
4681
|
+
await execFileP("npm", ["install", "--no-audit", "--no-fund"], { cwd: targetDir, timeout: 12e4 });
|
|
4682
|
+
await execFileP("npm", ["run", "build"], { cwd: targetDir, timeout: 12e4 });
|
|
4683
|
+
} catch (err) {
|
|
4684
|
+
loadError = "Failed to install/build plugin dependencies";
|
|
4685
|
+
logger2.error("Plugin build failed", { repoName, error: String(err) });
|
|
4686
|
+
}
|
|
4687
|
+
if (!loadError) {
|
|
4688
|
+
try {
|
|
4689
|
+
const manifest = JSON.parse(await readFile4(join9(targetDir, "package.json"), "utf8"));
|
|
4690
|
+
const pluginEntry = manifest.openfox?.plugin;
|
|
4691
|
+
const apiVersion = manifest.openfox?.apiVersion;
|
|
4692
|
+
if (!pluginEntry || !manifest.name) {
|
|
4693
|
+
loadError = "Plugin package.json is missing openfox.plugin or name field";
|
|
4694
|
+
} else if (apiVersion !== 1) {
|
|
4695
|
+
loadError = `Unsupported plugin API version: ${String(apiVersion)}`;
|
|
4696
|
+
} else {
|
|
4697
|
+
const mod = await import(pathToFileURL2(join9(targetDir, pluginEntry)).href);
|
|
4698
|
+
if (typeof mod.register !== "function") {
|
|
4699
|
+
loadError = "Plugin does not export register(registry)";
|
|
4700
|
+
} else {
|
|
4701
|
+
const diagnostic = {
|
|
4702
|
+
packageName: manifest.name,
|
|
4703
|
+
version: manifest.version,
|
|
4704
|
+
source: targetDir,
|
|
4705
|
+
loaded: false,
|
|
4706
|
+
authAdapters: [],
|
|
4707
|
+
transportAdapters: [],
|
|
4708
|
+
presets: []
|
|
4709
|
+
};
|
|
4710
|
+
const trackingRegistry = {
|
|
4711
|
+
runtime: providerAdapters.runtime,
|
|
4712
|
+
registerAuth(adapter) {
|
|
4713
|
+
providerAdapters.registerAuth(adapter);
|
|
4714
|
+
diagnostic.authAdapters.push(adapter.id);
|
|
4715
|
+
},
|
|
4716
|
+
registerTransport(adapter) {
|
|
4717
|
+
providerAdapters.registerTransport(adapter);
|
|
4718
|
+
diagnostic.transportAdapters.push(adapter.id);
|
|
4719
|
+
},
|
|
4720
|
+
registerPreset(preset) {
|
|
4721
|
+
providerAdapters.registerPreset(preset);
|
|
4722
|
+
diagnostic.presets.push(preset.id);
|
|
4723
|
+
}
|
|
4724
|
+
};
|
|
4725
|
+
await mod.register(trackingRegistry);
|
|
4726
|
+
diagnostic.loaded = true;
|
|
4727
|
+
pluginDiagnostics.push(diagnostic);
|
|
4728
|
+
loaded = true;
|
|
4729
|
+
config3.providers = providerAdapters.resolveProviders(config3.providers ?? []);
|
|
4730
|
+
}
|
|
4731
|
+
}
|
|
4732
|
+
} catch (err) {
|
|
4733
|
+
loadError = err instanceof Error ? err.message : "Failed to load plugin";
|
|
4734
|
+
logger2.error("Plugin runtime load failed", { repoName, error: loadError });
|
|
4735
|
+
}
|
|
4736
|
+
}
|
|
4737
|
+
res.json({ success: true, loaded, loadError, path: targetDir });
|
|
4738
|
+
} catch (err) {
|
|
4739
|
+
await rm2(tmpDir, { recursive: true, force: true });
|
|
4740
|
+
const msg = err instanceof Error ? err.message : "Clone failed";
|
|
4741
|
+
logger2.error("Plugin install failed", { githubUrl, error: msg });
|
|
4742
|
+
res.status(500).json({ error: msg });
|
|
4743
|
+
}
|
|
4744
|
+
});
|
|
4745
|
+
router.get("/installed", async (_req, res) => {
|
|
4746
|
+
const pluginsDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
|
|
4747
|
+
try {
|
|
4748
|
+
const entries = await readdir3(pluginsDir, { withFileTypes: true });
|
|
4749
|
+
const installed = [];
|
|
4750
|
+
for (const entry of entries) {
|
|
4751
|
+
if (!entry.isDirectory()) continue;
|
|
4752
|
+
const pkgPath = join9(pluginsDir, entry.name, "package.json");
|
|
4753
|
+
let version = null;
|
|
4754
|
+
try {
|
|
4755
|
+
const pkg = JSON.parse(await readFile4(pkgPath, "utf8"));
|
|
4756
|
+
version = pkg.version ?? null;
|
|
4757
|
+
} catch {
|
|
4758
|
+
}
|
|
4759
|
+
installed.push({ name: entry.name, version });
|
|
4760
|
+
}
|
|
4761
|
+
res.json({ installed });
|
|
4762
|
+
} catch {
|
|
4763
|
+
res.json({ installed: [] });
|
|
4764
|
+
}
|
|
4765
|
+
});
|
|
4766
|
+
router.get("/open-folder", async (_req, res) => {
|
|
4767
|
+
const pluginsDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins");
|
|
4768
|
+
await openFolder(pluginsDir, res);
|
|
4769
|
+
});
|
|
4770
|
+
router.get("/:name/open-folder", async (req, res) => {
|
|
4771
|
+
const name = req.params.name;
|
|
4772
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(name)) return res.status(400).json({ error: "Invalid plugin name" });
|
|
4773
|
+
const targetDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
|
|
4774
|
+
await openFolder(targetDir, res);
|
|
4775
|
+
});
|
|
4776
|
+
router.delete("/:name", async (req, res) => {
|
|
4777
|
+
const name = req.params.name;
|
|
4778
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(name)) {
|
|
4779
|
+
return res.status(400).json({ error: "Invalid plugin name" });
|
|
4780
|
+
}
|
|
4781
|
+
const targetDir = join9(getGlobalConfigDir(config3.mode ?? "production"), "plugins", name);
|
|
4782
|
+
try {
|
|
4783
|
+
await rm2(targetDir, { recursive: true, force: true });
|
|
4784
|
+
for (let i = pluginDiagnostics.length - 1; i >= 0; i--) {
|
|
4785
|
+
if (pluginDiagnostics[i].source === targetDir) pluginDiagnostics.splice(i, 1);
|
|
4786
|
+
}
|
|
4787
|
+
res.json({ success: true });
|
|
4788
|
+
} catch (err) {
|
|
4789
|
+
res.status(500).json({ error: err instanceof Error ? err.message : "Failed to remove plugin" });
|
|
4790
|
+
}
|
|
4791
|
+
});
|
|
4792
|
+
return router;
|
|
4793
|
+
}
|
|
4794
|
+
|
|
4535
4795
|
// src/server/index.ts
|
|
4536
|
-
var __dirname3 =
|
|
4796
|
+
var __dirname3 = dirname8(fileURLToPath7(import.meta.url));
|
|
4537
4797
|
async function createServerHandle(config3) {
|
|
4538
4798
|
setRuntimeConfig(config3);
|
|
4539
4799
|
setLogLevel(config3.logging?.level ?? void 0, config3.mode);
|
|
@@ -4630,7 +4890,7 @@ async function createServerHandle(config3) {
|
|
|
4630
4890
|
setMcpTools(mcpTools);
|
|
4631
4891
|
logger.info("MCP tools registered", { count: mcpTools.length });
|
|
4632
4892
|
}
|
|
4633
|
-
const { signalMcpReady } = await import("./server-
|
|
4893
|
+
const { signalMcpReady } = await import("./server-ECKS2Y3R.js");
|
|
4634
4894
|
signalMcpReady();
|
|
4635
4895
|
});
|
|
4636
4896
|
const app = express();
|
|
@@ -4791,7 +5051,7 @@ async function createServerHandle(config3) {
|
|
|
4791
5051
|
const { getProject: getProject2 } = await import("./projects-7HSBZY2D.js");
|
|
4792
5052
|
const project = getProject2(req.params.id);
|
|
4793
5053
|
if (!project) return res.status(404).json({ error: "Project not found" });
|
|
4794
|
-
const { listBranches } = await import("./worktree-
|
|
5054
|
+
const { listBranches } = await import("./worktree-6U45P63P.js");
|
|
4795
5055
|
const branches = await listBranches(project.workdir);
|
|
4796
5056
|
res.json({ branches });
|
|
4797
5057
|
});
|
|
@@ -4801,7 +5061,7 @@ async function createServerHandle(config3) {
|
|
|
4801
5061
|
if (!project) return res.status(404).json({ error: "Project not found" });
|
|
4802
5062
|
const { branch } = req.body;
|
|
4803
5063
|
if (!branch || typeof branch !== "string") return res.status(400).json({ error: "branch is required" });
|
|
4804
|
-
const { checkoutBranch } = await import("./worktree-
|
|
5064
|
+
const { checkoutBranch } = await import("./worktree-6U45P63P.js");
|
|
4805
5065
|
try {
|
|
4806
5066
|
await checkoutBranch(project.workdir, branch);
|
|
4807
5067
|
res.json({ branch });
|
|
@@ -4815,7 +5075,7 @@ async function createServerHandle(config3) {
|
|
|
4815
5075
|
if (!project) return res.status(404).json({ error: "Project not found" });
|
|
4816
5076
|
const { name } = req.body;
|
|
4817
5077
|
if (!name || typeof name !== "string") return res.status(400).json({ error: "name is required" });
|
|
4818
|
-
const { createBranch } = await import("./worktree-
|
|
5078
|
+
const { createBranch } = await import("./worktree-6U45P63P.js");
|
|
4819
5079
|
try {
|
|
4820
5080
|
await createBranch(project.workdir, name);
|
|
4821
5081
|
res.json({ branch: name });
|
|
@@ -4827,7 +5087,7 @@ async function createServerHandle(config3) {
|
|
|
4827
5087
|
const { getProject: getProject2 } = await import("./projects-7HSBZY2D.js");
|
|
4828
5088
|
const project = getProject2(req.params.id);
|
|
4829
5089
|
if (!project) return res.status(404).json({ error: "Project not found" });
|
|
4830
|
-
const { listWorktrees } = await import("./worktree-
|
|
5090
|
+
const { listWorktrees } = await import("./worktree-6U45P63P.js");
|
|
4831
5091
|
const all = await listWorktrees(project.workdir);
|
|
4832
5092
|
const worktrees = all.filter((wt) => wt.path !== project.workdir);
|
|
4833
5093
|
res.json({ worktrees });
|
|
@@ -4902,7 +5162,7 @@ async function createServerHandle(config3) {
|
|
|
4902
5162
|
app.get("/api/sessions/:id", async (req, res) => {
|
|
4903
5163
|
const { getEventStore: getEventStore2 } = await import("./events-CDQ4HASP.js");
|
|
4904
5164
|
const { buildMessagesFromStoredEvents } = await import("./folding-V2K34EGN.js");
|
|
4905
|
-
const { getPendingQuestionsForSession } = await import("./tools-
|
|
5165
|
+
const { getPendingQuestionsForSession } = await import("./tools-QAEN5KHA.js");
|
|
4906
5166
|
const session = sessionManager.getSession(req.params.id);
|
|
4907
5167
|
if (!session) {
|
|
4908
5168
|
return res.status(404).json({ error: "Session not found" });
|
|
@@ -4921,8 +5181,8 @@ async function createServerHandle(config3) {
|
|
|
4921
5181
|
if (!session) {
|
|
4922
5182
|
return res.status(404).json({ error: "Session not found" });
|
|
4923
5183
|
}
|
|
4924
|
-
const { stopSessionExecution } = await import("./chat-handler-
|
|
4925
|
-
const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-
|
|
5184
|
+
const { stopSessionExecution } = await import("./chat-handler-QFEHJBWN.js");
|
|
5185
|
+
const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-QAEN5KHA.js");
|
|
4926
5186
|
sessionManager.clearMessageQueue(sessionId);
|
|
4927
5187
|
stopSessionExecution(sessionId, sessionManager);
|
|
4928
5188
|
abortSession(sessionId);
|
|
@@ -5076,7 +5336,7 @@ async function createServerHandle(config3) {
|
|
|
5076
5336
|
if (!callId || approved === void 0) {
|
|
5077
5337
|
return res.status(400).json({ error: "callId and approved are required" });
|
|
5078
5338
|
}
|
|
5079
|
-
const { providePathConfirmation } = await import("./tools-
|
|
5339
|
+
const { providePathConfirmation } = await import("./tools-QAEN5KHA.js");
|
|
5080
5340
|
const result = providePathConfirmation(callId, approved, alwaysAllow);
|
|
5081
5341
|
if (!result.found) {
|
|
5082
5342
|
return res.status(404).json({ error: "No pending path confirmation with that ID" });
|
|
@@ -5084,7 +5344,7 @@ async function createServerHandle(config3) {
|
|
|
5084
5344
|
const { getEventStore: getEventStore2 } = await import("./events-CDQ4HASP.js");
|
|
5085
5345
|
const { buildMessagesFromStoredEvents, foldPendingConfirmations } = await import("./folding-V2K34EGN.js");
|
|
5086
5346
|
const { createSessionStateMessage } = await import("./protocol-CTNE3ANP.js");
|
|
5087
|
-
const { getPendingQuestionsForSession } = await import("./tools-
|
|
5347
|
+
const { getPendingQuestionsForSession } = await import("./tools-QAEN5KHA.js");
|
|
5088
5348
|
const eventStore = getEventStore2();
|
|
5089
5349
|
const events = eventStore.getEvents(sessionId);
|
|
5090
5350
|
const messages = buildMessagesFromStoredEvents(events);
|
|
@@ -5105,7 +5365,7 @@ async function createServerHandle(config3) {
|
|
|
5105
5365
|
if (!skip && typeof answer !== "string") {
|
|
5106
5366
|
return res.status(400).json({ error: "answer is required when not skipping" });
|
|
5107
5367
|
}
|
|
5108
|
-
const { provideAnswer } = await import("./tools-
|
|
5368
|
+
const { provideAnswer } = await import("./tools-QAEN5KHA.js");
|
|
5109
5369
|
const found = provideAnswer(callId, answer ?? "", skip ?? false);
|
|
5110
5370
|
if (!found) {
|
|
5111
5371
|
return res.status(404).json({ error: "No pending question with that ID" });
|
|
@@ -5133,7 +5393,7 @@ async function createServerHandle(config3) {
|
|
|
5133
5393
|
if (!session) {
|
|
5134
5394
|
return res.status(404).json({ error: "Session not found" });
|
|
5135
5395
|
}
|
|
5136
|
-
const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-
|
|
5396
|
+
const { getSetting: getSetting2, SETTINGS_KEYS } = await import("./settings-6ZPWOBWL.js");
|
|
5137
5397
|
if (getSetting2(SETTINGS_KEYS.CACHE_WARMING) !== "true") {
|
|
5138
5398
|
return res.json({ success: false, reason: "disabled" });
|
|
5139
5399
|
}
|
|
@@ -5165,7 +5425,7 @@ async function createServerHandle(config3) {
|
|
|
5165
5425
|
backend: activeProvider?.backend ?? llmClient.getBackend(),
|
|
5166
5426
|
model: llmClient.getModel()
|
|
5167
5427
|
};
|
|
5168
|
-
const { runAgentTurn, TurnMetrics } = await import("./orchestrator-
|
|
5428
|
+
const { runAgentTurn, TurnMetrics } = await import("./orchestrator-GNXKJPX4.js");
|
|
5169
5429
|
runAgentTurn(
|
|
5170
5430
|
{
|
|
5171
5431
|
sessionManager,
|
|
@@ -5203,8 +5463,8 @@ async function createServerHandle(config3) {
|
|
|
5203
5463
|
if (!session) {
|
|
5204
5464
|
return res.status(404).json({ error: "Session not found" });
|
|
5205
5465
|
}
|
|
5206
|
-
const { stopSessionExecution } = await import("./chat-handler-
|
|
5207
|
-
const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-
|
|
5466
|
+
const { stopSessionExecution } = await import("./chat-handler-QFEHJBWN.js");
|
|
5467
|
+
const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-QAEN5KHA.js");
|
|
5208
5468
|
const queuedMessages = sessionManager.getQueueState(sessionId);
|
|
5209
5469
|
sessionManager.clearMessageQueue(sessionId);
|
|
5210
5470
|
stopSessionExecution(sessionId, sessionManager);
|
|
@@ -5284,7 +5544,7 @@ async function createServerHandle(config3) {
|
|
|
5284
5544
|
res.json({ accepted: true });
|
|
5285
5545
|
});
|
|
5286
5546
|
app.get("/api/settings", async (req, res) => {
|
|
5287
|
-
const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-
|
|
5547
|
+
const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-6ZPWOBWL.js");
|
|
5288
5548
|
const keysParam = req.query["keys"];
|
|
5289
5549
|
if (!keysParam) {
|
|
5290
5550
|
return res.status(400).json({ error: "keys query parameter is required" });
|
|
@@ -5297,19 +5557,19 @@ async function createServerHandle(config3) {
|
|
|
5297
5557
|
res.json(result);
|
|
5298
5558
|
});
|
|
5299
5559
|
app.get("/api/settings/:key", async (req, res) => {
|
|
5300
|
-
const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-
|
|
5560
|
+
const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-6ZPWOBWL.js");
|
|
5301
5561
|
const key = req.params.key;
|
|
5302
5562
|
const value = getSetting2(key) ?? SETTINGS_DEFAULTS[key] ?? null;
|
|
5303
5563
|
res.json({ key, value });
|
|
5304
5564
|
});
|
|
5305
5565
|
app.get("/api/settings/:key", async (req, res) => {
|
|
5306
|
-
const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-
|
|
5566
|
+
const { getSetting: getSetting2, SETTINGS_DEFAULTS } = await import("./settings-6ZPWOBWL.js");
|
|
5307
5567
|
const key = req.params.key;
|
|
5308
5568
|
const value = getSetting2(key) ?? SETTINGS_DEFAULTS[key] ?? null;
|
|
5309
5569
|
res.json({ key, value });
|
|
5310
5570
|
});
|
|
5311
5571
|
app.put("/api/settings/:key", async (req, res) => {
|
|
5312
|
-
const { setSetting: setSetting2 } = await import("./settings-
|
|
5572
|
+
const { setSetting: setSetting2 } = await import("./settings-6ZPWOBWL.js");
|
|
5313
5573
|
const key = req.params.key;
|
|
5314
5574
|
const { value } = req.body;
|
|
5315
5575
|
if (value === void 0) {
|
|
@@ -5321,20 +5581,24 @@ async function createServerHandle(config3) {
|
|
|
5321
5581
|
app.get("/api/tools/rtk-check", async (_req, res) => {
|
|
5322
5582
|
const { spawn: spawn3 } = await import("child_process");
|
|
5323
5583
|
try {
|
|
5324
|
-
const available = await new Promise((
|
|
5584
|
+
const available = await new Promise((resolve8) => {
|
|
5325
5585
|
const proc = spawn3("rtk", ["--version"], { stdio: ["ignore", "pipe", "pipe"] });
|
|
5326
5586
|
let out = "";
|
|
5327
5587
|
proc.stdout?.on("data", (d) => {
|
|
5328
5588
|
out += d.toString();
|
|
5329
5589
|
});
|
|
5330
|
-
proc.on("error", () =>
|
|
5331
|
-
proc.on("close", (code) =>
|
|
5590
|
+
proc.on("error", () => resolve8(false));
|
|
5591
|
+
proc.on("close", (code) => resolve8(code === 0 && out.startsWith("rtk ")));
|
|
5332
5592
|
});
|
|
5333
5593
|
res.json({ available });
|
|
5334
5594
|
} catch {
|
|
5335
5595
|
res.json({ available: false });
|
|
5336
5596
|
}
|
|
5337
5597
|
});
|
|
5598
|
+
app.get("/api/tools/shells", async (_req, res) => {
|
|
5599
|
+
const { listAvailableShells } = await import("./platform-AB3GIEGO.js");
|
|
5600
|
+
res.json({ shells: listAvailableShells() });
|
|
5601
|
+
});
|
|
5338
5602
|
app.get("/api/config", async (_req, res) => {
|
|
5339
5603
|
const llmClient = getLLMClient();
|
|
5340
5604
|
const activeProvider = providerManager.getActiveProvider();
|
|
@@ -5494,7 +5758,7 @@ async function createServerHandle(config3) {
|
|
|
5494
5758
|
const backend = req.query["backend"];
|
|
5495
5759
|
if (!url) return res.status(400).json({ error: "url is required" });
|
|
5496
5760
|
try {
|
|
5497
|
-
const { fetchModelsWithContext } = await import("./provider-manager-
|
|
5761
|
+
const { fetchModelsWithContext } = await import("./provider-manager-7C3JVOLW.js");
|
|
5498
5762
|
const { getModelProfile: getModelProfile2 } = await import("./profiles-5J7F4BML.js");
|
|
5499
5763
|
const models = await fetchModelsWithContext(
|
|
5500
5764
|
url,
|
|
@@ -5564,7 +5828,7 @@ async function createServerHandle(config3) {
|
|
|
5564
5828
|
}
|
|
5565
5829
|
const { getModelProfile: getModelProfile2 } = await import("./profiles-5J7F4BML.js");
|
|
5566
5830
|
const { getBackendCapabilities } = await import("./backend-P3GHHLHJ.js");
|
|
5567
|
-
const { buildNonStreamingCreateParams } = await import("./client-pure-
|
|
5831
|
+
const { buildNonStreamingCreateParams } = await import("./client-pure-XHH4RRLB.js");
|
|
5568
5832
|
const { OpenAIHttpClient } = await import("./http-client-PIWB7BXK.js");
|
|
5569
5833
|
const { ensureVersionPrefix } = await import("./url-utils-SAJP7AEX.js");
|
|
5570
5834
|
const profile = getModelProfile2(model);
|
|
@@ -5690,6 +5954,7 @@ async function createServerHandle(config3) {
|
|
|
5690
5954
|
});
|
|
5691
5955
|
}
|
|
5692
5956
|
});
|
|
5957
|
+
app.use("/api/plugins", createPluginRoutes({ config: config3, providerAdapters, pluginDiagnostics, logger }));
|
|
5693
5958
|
app.get("/api/plugins", (_req, res) => res.json({ plugins: pluginDiagnostics }));
|
|
5694
5959
|
app.get("/api/provider-presets", (_req, res) => res.json({ presets: providerAdapters.getPresets() }));
|
|
5695
5960
|
app.get(
|
|
@@ -5822,7 +6087,7 @@ async function createServerHandle(config3) {
|
|
|
5822
6087
|
});
|
|
5823
6088
|
async function rebuildMcpTools() {
|
|
5824
6089
|
const { createMcpTools: createMcpTools2 } = await import("./tool-adapter-MOGEI6TP.js");
|
|
5825
|
-
const { setMcpTools: setMcpTools2 } = await import("./tools-
|
|
6090
|
+
const { setMcpTools: setMcpTools2 } = await import("./tools-QAEN5KHA.js");
|
|
5826
6091
|
const mcpTools = createMcpTools2(mcpManager);
|
|
5827
6092
|
setMcpTools2(mcpTools);
|
|
5828
6093
|
}
|
|
@@ -5977,6 +6242,7 @@ async function createServerHandle(config3) {
|
|
|
5977
6242
|
app.use("/api/agents", createAgentRoutes(configDir, projectDir));
|
|
5978
6243
|
app.use("/api/workflows", createWorkflowRoutes(configDir, config3, projectDir));
|
|
5979
6244
|
app.use("/api/dev-server", createDevServerRoutes());
|
|
6245
|
+
app.use("/api/worktree", createWorktreeConfigRoutes());
|
|
5980
6246
|
app.use("/api/terminals", createTerminalRoutes());
|
|
5981
6247
|
app.use(
|
|
5982
6248
|
"/api/auto-update",
|
|
@@ -5993,13 +6259,13 @@ async function createServerHandle(config3) {
|
|
|
5993
6259
|
})
|
|
5994
6260
|
);
|
|
5995
6261
|
app.get("/api/sessions/:id/background-processes", async (req, res) => {
|
|
5996
|
-
const { getSessionProcesses } = await import("./manager-
|
|
6262
|
+
const { getSessionProcesses } = await import("./manager-JXYRGR6B.js");
|
|
5997
6263
|
const sessionId = req.params.id;
|
|
5998
6264
|
const processes = getSessionProcesses(sessionId);
|
|
5999
6265
|
res.json({ processes });
|
|
6000
6266
|
});
|
|
6001
6267
|
app.post("/api/sessions/:id/background-process/:processId/stop", async (req, res) => {
|
|
6002
|
-
const { stopProcess } = await import("./manager-
|
|
6268
|
+
const { stopProcess } = await import("./manager-JXYRGR6B.js");
|
|
6003
6269
|
const sessionId = req.params.id;
|
|
6004
6270
|
const processId = req.params.processId;
|
|
6005
6271
|
const session = sessionManager.getSession(sessionId);
|
|
@@ -6019,14 +6285,14 @@ async function createServerHandle(config3) {
|
|
|
6019
6285
|
});
|
|
6020
6286
|
app.use("/api/directories", createDirectoryRoutes());
|
|
6021
6287
|
app.use("/api/files", createFileSearchRoutes());
|
|
6022
|
-
const webDir =
|
|
6288
|
+
const webDir = resolve7(__dirname3, "../../web");
|
|
6023
6289
|
const isDev = config3.mode === "development";
|
|
6024
6290
|
let viteServer;
|
|
6025
6291
|
if (isDev) {
|
|
6026
6292
|
logger.info("Dev mode: using Vite middleware");
|
|
6027
6293
|
viteServer = await createViteServer({
|
|
6028
6294
|
root: webDir,
|
|
6029
|
-
configFile:
|
|
6295
|
+
configFile: resolve7(__dirname3, "../../web/vite.config.ts"),
|
|
6030
6296
|
server: { middlewareMode: true },
|
|
6031
6297
|
appType: "spa",
|
|
6032
6298
|
logLevel: "warn"
|
|
@@ -6046,7 +6312,7 @@ async function createServerHandle(config3) {
|
|
|
6046
6312
|
}
|
|
6047
6313
|
});
|
|
6048
6314
|
app.get("/fox.svg", (_req, res) => {
|
|
6049
|
-
|
|
6315
|
+
readFile5(join10(webDir, "fox.svg")).then((content) => {
|
|
6050
6316
|
res.set("Content-Type", "image/svg+xml");
|
|
6051
6317
|
res.send(content);
|
|
6052
6318
|
}).catch(() => {
|
|
@@ -6055,7 +6321,7 @@ async function createServerHandle(config3) {
|
|
|
6055
6321
|
});
|
|
6056
6322
|
app.use(
|
|
6057
6323
|
"/sounds",
|
|
6058
|
-
express.static(
|
|
6324
|
+
express.static(join10(webDir, "public", "sounds"), {
|
|
6059
6325
|
setHeaders: (res) => {
|
|
6060
6326
|
res.set("Content-Type", "audio/mpeg");
|
|
6061
6327
|
}
|
|
@@ -6064,13 +6330,13 @@ async function createServerHandle(config3) {
|
|
|
6064
6330
|
app.use("/__inspect__.js", (_req, res) => {
|
|
6065
6331
|
res.set("Access-Control-Allow-Origin", "*");
|
|
6066
6332
|
res.set("Content-Type", "application/javascript");
|
|
6067
|
-
|
|
6333
|
+
readFile5(join10(webDir, "public", "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
|
|
6068
6334
|
});
|
|
6069
6335
|
app.get("/*path", (req, res) => {
|
|
6070
6336
|
if (req.path.startsWith("/api/")) {
|
|
6071
6337
|
return;
|
|
6072
6338
|
}
|
|
6073
|
-
|
|
6339
|
+
readFile5(join10(webDir, "index.html"), "utf-8").then((indexHtml) => viteServer.transformIndexHtml(req.originalUrl, indexHtml)).then((transformed) => res.send(transformed)).catch((err) => {
|
|
6074
6340
|
logger.error("Error serving index.html", { error: err });
|
|
6075
6341
|
res.status(500).send("Server error");
|
|
6076
6342
|
});
|
|
@@ -6078,10 +6344,10 @@ async function createServerHandle(config3) {
|
|
|
6078
6344
|
logger.info("Vite middleware ready", { port: config3.server.port });
|
|
6079
6345
|
}
|
|
6080
6346
|
if (!isDev) {
|
|
6081
|
-
const distWebDir =
|
|
6347
|
+
const distWebDir = resolve7(__dirname3, "web");
|
|
6082
6348
|
app.use(
|
|
6083
6349
|
"/assets",
|
|
6084
|
-
express.static(
|
|
6350
|
+
express.static(join10(distWebDir, "assets"), {
|
|
6085
6351
|
setHeaders: (res, filepath) => {
|
|
6086
6352
|
if (filepath.endsWith(".css")) {
|
|
6087
6353
|
res.set("Content-Type", "text/css");
|
|
@@ -6089,11 +6355,11 @@ async function createServerHandle(config3) {
|
|
|
6089
6355
|
}
|
|
6090
6356
|
})
|
|
6091
6357
|
);
|
|
6092
|
-
app.use("/manifest.webmanifest", express.static(
|
|
6093
|
-
app.use("/registerSW.js", express.static(
|
|
6094
|
-
app.use("/sw.js", express.static(
|
|
6358
|
+
app.use("/manifest.webmanifest", express.static(join10(distWebDir, "manifest.webmanifest")));
|
|
6359
|
+
app.use("/registerSW.js", express.static(join10(distWebDir, "registerSW.js")));
|
|
6360
|
+
app.use("/sw.js", express.static(join10(distWebDir, "sw.js")));
|
|
6095
6361
|
app.get("/fox.svg", (_req, res) => {
|
|
6096
|
-
|
|
6362
|
+
readFile5(join10(distWebDir, "fox.svg")).then((content) => {
|
|
6097
6363
|
res.set("Content-Type", "image/svg+xml");
|
|
6098
6364
|
res.send(content);
|
|
6099
6365
|
}).catch(() => {
|
|
@@ -6102,7 +6368,7 @@ async function createServerHandle(config3) {
|
|
|
6102
6368
|
});
|
|
6103
6369
|
app.use(
|
|
6104
6370
|
"/sounds",
|
|
6105
|
-
express.static(
|
|
6371
|
+
express.static(join10(distWebDir, "sounds"), {
|
|
6106
6372
|
setHeaders: (res) => {
|
|
6107
6373
|
res.set("Content-Type", "audio/mpeg");
|
|
6108
6374
|
}
|
|
@@ -6111,10 +6377,10 @@ async function createServerHandle(config3) {
|
|
|
6111
6377
|
app.use("/__inspect__.js", (_req, res) => {
|
|
6112
6378
|
res.set("Access-Control-Allow-Origin", "*");
|
|
6113
6379
|
res.set("Content-Type", "application/javascript");
|
|
6114
|
-
|
|
6380
|
+
readFile5(join10(distWebDir, "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
|
|
6115
6381
|
});
|
|
6116
6382
|
app.get("/", (_req, res) => {
|
|
6117
|
-
|
|
6383
|
+
readFile5(join10(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
|
|
6118
6384
|
res.status(404).send("Web UI not built. Run `npm run build:web`");
|
|
6119
6385
|
});
|
|
6120
6386
|
});
|
|
@@ -6122,7 +6388,7 @@ async function createServerHandle(config3) {
|
|
|
6122
6388
|
if (req.path.startsWith("/api/") || req.path.startsWith("/assets/") || req.path.startsWith("/sounds/") || req.path.startsWith("/manifest.webmanifest") || req.path.startsWith("/registerSW.js") || req.path.startsWith("/sw.js") || req.path === "/fox.svg") {
|
|
6123
6389
|
return;
|
|
6124
6390
|
}
|
|
6125
|
-
|
|
6391
|
+
readFile5(join10(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
|
|
6126
6392
|
res.status(404).send("Web UI not built");
|
|
6127
6393
|
});
|
|
6128
6394
|
});
|
|
@@ -6142,7 +6408,7 @@ async function createServerHandle(config3) {
|
|
|
6142
6408
|
const state = sessionManager.getContextState(sessionId);
|
|
6143
6409
|
wssExports.broadcastForSession(sessionId, createContextStateMessage(state));
|
|
6144
6410
|
});
|
|
6145
|
-
const { QueueProcessor } = await import("./processor-
|
|
6411
|
+
const { QueueProcessor } = await import("./processor-TIQEQDP7.js");
|
|
6146
6412
|
const queueProcessor = new QueueProcessor({
|
|
6147
6413
|
sessionManager,
|
|
6148
6414
|
providerManager,
|
|
@@ -6165,7 +6431,7 @@ async function createServerHandle(config3) {
|
|
|
6165
6431
|
return {
|
|
6166
6432
|
httpServer,
|
|
6167
6433
|
ctx: { config: config3, sessionManager, llmClient: getLLMClient(), toolRegistry, providerManager },
|
|
6168
|
-
start: (port) => new Promise((
|
|
6434
|
+
start: (port) => new Promise((resolve8, reject) => {
|
|
6169
6435
|
const listenPort = port ?? config3.server.port;
|
|
6170
6436
|
const host = config3.server.host;
|
|
6171
6437
|
httpServer.listen(listenPort, host, () => {
|
|
@@ -6175,16 +6441,16 @@ async function createServerHandle(config3) {
|
|
|
6175
6441
|
logger.info(`OpenFox server running at http://${host}:${actualPort}`);
|
|
6176
6442
|
logger.info(`WebSocket available at ws://${host}:${actualPort}/ws`);
|
|
6177
6443
|
logger.info(`LLM backend: ${client.getBackend()}, model: ${client.getModel()}, url: ${config3.llm.baseUrl}`);
|
|
6178
|
-
|
|
6444
|
+
resolve8({ port: actualPort });
|
|
6179
6445
|
});
|
|
6180
6446
|
httpServer.on("error", reject);
|
|
6181
6447
|
}),
|
|
6182
|
-
close: () => new Promise((
|
|
6448
|
+
close: () => new Promise((resolve8) => {
|
|
6183
6449
|
logger.info("Shutting down...");
|
|
6184
6450
|
void (async () => {
|
|
6185
6451
|
await devServerManager.stopAll();
|
|
6186
6452
|
await mcpManager.disconnectAll();
|
|
6187
|
-
const { stopAllInspectProxies } = await import("./inspect-proxy-
|
|
6453
|
+
const { stopAllInspectProxies } = await import("./inspect-proxy-OVEFBJ26.js");
|
|
6188
6454
|
stopAllInspectProxies();
|
|
6189
6455
|
const { cleanupAllProcesses } = await import("./store-FXTCHBI4.js");
|
|
6190
6456
|
cleanupAllProcesses();
|
|
@@ -6198,7 +6464,7 @@ async function createServerHandle(config3) {
|
|
|
6198
6464
|
client.terminate();
|
|
6199
6465
|
}
|
|
6200
6466
|
wss.close();
|
|
6201
|
-
httpServer.close(() =>
|
|
6467
|
+
httpServer.close(() => resolve8());
|
|
6202
6468
|
})();
|
|
6203
6469
|
})
|
|
6204
6470
|
};
|
|
@@ -6223,4 +6489,4 @@ export {
|
|
|
6223
6489
|
createServerHandle,
|
|
6224
6490
|
createServer
|
|
6225
6491
|
};
|
|
6226
|
-
//# sourceMappingURL=chunk-
|
|
6492
|
+
//# sourceMappingURL=chunk-DWZEGLHJ.js.map
|