openfox 1.6.90 → 1.6.92
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/{auto-compaction-6A34RHDV.js → auto-compaction-7AGIGW6F.js} +7 -7
- package/dist/{chat-handler-6ATTKNZT.js → chat-handler-UPAEF6HR.js} +10 -10
- package/dist/{chunk-ZORPFD4C.js → chunk-2BS6LMIU.js} +507 -474
- package/dist/{chunk-N7W42N5Y.js → chunk-2TKN2X2A.js} +3 -3
- package/dist/{chunk-7WHJUQ4Y.js → chunk-7KO2BQFQ.js} +9 -8
- package/dist/{chunk-6GGYIEBM.js → chunk-7QG6LY5Q.js} +3 -3
- package/dist/{chunk-UEZDAB5X.js → chunk-ARJIHQ3S.js} +240 -143
- package/dist/{chunk-TLOL4I7K.js → chunk-BHZL3N2F.js} +3 -3
- package/dist/{chunk-WSRF5L3S.js → chunk-CHICEUV6.js} +3 -3
- package/dist/{chunk-RCECKE5L.js → chunk-PQCFNTFJ.js} +15 -9
- package/dist/{chunk-YNIAFX24.js → chunk-RJIPM7CO.js} +4 -4
- package/dist/{chunk-B5AP3RSV.js → chunk-RW25DL5R.js} +3 -3
- package/dist/{chunk-JDDNBK6T.js → chunk-WBQNIWAQ.js} +5 -5
- package/dist/{chunk-DF5BZBP6.js → chunk-XGJ7HDQ7.js} +2 -2
- package/dist/{chunk-6P5WQP6Y.js → chunk-YTPPQK55.js} +2 -2
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{config-HMMPXQ46.js → config-7XJQNOKX.js} +5 -5
- package/dist/{events-AQKDXJFK.js → events-K6AYMXFT.js} +3 -3
- package/dist/{orchestrator-YUAFANFC.js → orchestrator-M4WINFF3.js} +8 -8
- package/dist/package.json +1 -1
- package/dist/{processor-4SOP4Q6S.js → processor-D4XQ5QMB.js} +5 -5
- package/dist/{protocol--8PKNwb_.d.ts → protocol-XRiJzlOK.d.ts} +1 -1
- package/dist/{provider-LDZFYLK6.js → provider-UO5PAZQQ.js} +7 -7
- package/dist/{runtime-config-CBJJJGBD.js → runtime-config-CYHDAC7W.js} +2 -2
- package/dist/{serve-YO7HQKUD.js → serve-Z5FNJUDT.js} +12 -12
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +10 -10
- package/dist/{service-TU4XSXYJ.js → service-3CLVG2HV.js} +20 -2
- package/dist/{settings-VTVOBDYG.js → settings-AYSWDZUI.js} +2 -2
- package/dist/shared/index.d.ts +2 -2
- package/dist/{tools-7MGUWXDP.js → tools-NFFQWH6M.js} +7 -7
- package/dist/{vision-fallback-WT66NURB.js → vision-fallback-GZZWU7CR.js} +2 -2
- package/dist/web/assets/{index-7tHnjaI4.css → index-CM0cLwa6.css} +2 -2
- package/dist/web/assets/index-SkaCnTiV.js +176 -0
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/package.json +1 -1
- package/dist/web/assets/index-CdF408Qk.js +0 -158
- /package/dist/web/{workbox-8c29f6e4.js → workbox-7fc22fbe.js} +0 -0
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createVerifierNudgeConfig,
|
|
3
3
|
runBuilderTurn,
|
|
4
4
|
runChatTurn
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-2TKN2X2A.js";
|
|
6
6
|
import {
|
|
7
7
|
TurnMetrics,
|
|
8
8
|
agentExists,
|
|
@@ -10,34 +10,43 @@ import {
|
|
|
10
10
|
createMessageStartEvent,
|
|
11
11
|
createToolRegistry,
|
|
12
12
|
deleteAgent,
|
|
13
|
+
deleteItemFromDir,
|
|
14
|
+
deleteProjectAgent,
|
|
15
|
+
deleteProjectSkill,
|
|
13
16
|
deleteSkill,
|
|
14
17
|
devServerManager,
|
|
15
18
|
executeSubAgent,
|
|
16
19
|
findAgentById,
|
|
17
20
|
findSkillById,
|
|
18
|
-
getDefaultAgentContent,
|
|
19
21
|
getDefaultAgentIds,
|
|
20
22
|
getDefaultIds,
|
|
21
|
-
getDefaultSkillContent,
|
|
22
23
|
getDefaultSkillIds,
|
|
23
24
|
getToolRegistryForAgent,
|
|
25
|
+
getTopLevelAgents,
|
|
26
|
+
isDefaultAgent,
|
|
27
|
+
isDefaultSkill,
|
|
24
28
|
isSkillEnabled,
|
|
29
|
+
jsonSerializer,
|
|
25
30
|
loadAllAgents,
|
|
26
31
|
loadAllAgentsDefault,
|
|
27
32
|
loadAllSkills,
|
|
28
33
|
loadDefaultAgents,
|
|
29
34
|
loadDefaultSkills,
|
|
30
35
|
loadItemsFromDir,
|
|
36
|
+
loadProjectAgents,
|
|
37
|
+
loadProjectSkills,
|
|
31
38
|
loadUserAgents,
|
|
32
39
|
loadUserSkills,
|
|
33
40
|
pathExists,
|
|
34
41
|
performManualContextCompaction,
|
|
35
42
|
saveAgent,
|
|
43
|
+
saveAgentToProject,
|
|
44
|
+
saveItemToDir,
|
|
36
45
|
saveSkill,
|
|
37
|
-
|
|
46
|
+
saveSkillToProject,
|
|
38
47
|
skillExists,
|
|
39
48
|
spawnShellProcess
|
|
40
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-ARJIHQ3S.js";
|
|
41
50
|
import {
|
|
42
51
|
getProject
|
|
43
52
|
} from "./chunk-ZHBL5G5X.js";
|
|
@@ -50,18 +59,18 @@ import {
|
|
|
50
59
|
import {
|
|
51
60
|
createProviderManager,
|
|
52
61
|
parseDefaultModelSelection
|
|
53
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-7QG6LY5Q.js";
|
|
54
63
|
import {
|
|
55
64
|
SessionNotFoundError,
|
|
56
65
|
createLLMClient,
|
|
57
66
|
detectModel,
|
|
58
67
|
getLlmStatus
|
|
59
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-WBQNIWAQ.js";
|
|
60
69
|
import {
|
|
61
70
|
detectBackend,
|
|
62
71
|
getBackendDisplayName,
|
|
63
72
|
getModelProfile
|
|
64
|
-
} from "./chunk-
|
|
73
|
+
} from "./chunk-RJIPM7CO.js";
|
|
65
74
|
import {
|
|
66
75
|
createSession,
|
|
67
76
|
deleteSession,
|
|
@@ -87,7 +96,7 @@ import {
|
|
|
87
96
|
updateSessionProvider,
|
|
88
97
|
updateSessionRunning,
|
|
89
98
|
updateSessionSummary
|
|
90
|
-
} from "./chunk-
|
|
99
|
+
} from "./chunk-YTPPQK55.js";
|
|
91
100
|
import {
|
|
92
101
|
initDatabase
|
|
93
102
|
} from "./chunk-5GVCNVKV.js";
|
|
@@ -126,7 +135,7 @@ import {
|
|
|
126
135
|
import {
|
|
127
136
|
getRuntimeConfig,
|
|
128
137
|
setRuntimeConfig
|
|
129
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-RW25DL5R.js";
|
|
130
139
|
import {
|
|
131
140
|
logger,
|
|
132
141
|
setLogLevel
|
|
@@ -137,7 +146,7 @@ import express from "express";
|
|
|
137
146
|
import cors from "cors";
|
|
138
147
|
import { createServer as createHttpServer } from "http";
|
|
139
148
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
140
|
-
import { dirname as dirname5, resolve, join as
|
|
149
|
+
import { dirname as dirname5, resolve, join as join6 } from "path";
|
|
141
150
|
import { readFile as readFile3 } from "fs/promises";
|
|
142
151
|
import { createServer as createViteServer } from "vite";
|
|
143
152
|
|
|
@@ -1531,6 +1540,9 @@ var WORKFLOW_EXTENSION = ".workflow.json";
|
|
|
1531
1540
|
function getWorkflowsDir(configDir) {
|
|
1532
1541
|
return join(configDir, "workflows");
|
|
1533
1542
|
}
|
|
1543
|
+
function getProjectWorkflowsDir(projectDir) {
|
|
1544
|
+
return join(projectDir, ".openfox", "workflows");
|
|
1545
|
+
}
|
|
1534
1546
|
async function pathExists2(path) {
|
|
1535
1547
|
try {
|
|
1536
1548
|
await access(path, constants.R_OK);
|
|
@@ -1575,7 +1587,10 @@ async function loadDefaultWorkflows() {
|
|
|
1575
1587
|
async function loadUserWorkflows(configDir) {
|
|
1576
1588
|
return loadWorkflowsFromDir(getWorkflowsDir(configDir));
|
|
1577
1589
|
}
|
|
1578
|
-
async function
|
|
1590
|
+
async function loadProjectWorkflows(projectDir) {
|
|
1591
|
+
return loadWorkflowsFromDir(getProjectWorkflowsDir(projectDir));
|
|
1592
|
+
}
|
|
1593
|
+
async function loadAllWorkflows(configDir, projectDir) {
|
|
1579
1594
|
const [defaultWorkflows, userWorkflows] = await Promise.all([loadDefaultWorkflows(), loadUserWorkflows(configDir)]);
|
|
1580
1595
|
const workflowMap = /* @__PURE__ */ new Map();
|
|
1581
1596
|
for (const workflow of defaultWorkflows) {
|
|
@@ -1584,8 +1599,20 @@ async function loadAllWorkflows(configDir) {
|
|
|
1584
1599
|
for (const workflow of userWorkflows) {
|
|
1585
1600
|
workflowMap.set(workflow.metadata.id, workflow);
|
|
1586
1601
|
}
|
|
1602
|
+
if (projectDir) {
|
|
1603
|
+
const projectWorkflows = await loadProjectWorkflows(projectDir);
|
|
1604
|
+
for (const workflow of projectWorkflows) {
|
|
1605
|
+
workflowMap.set(workflow.metadata.id, workflow);
|
|
1606
|
+
}
|
|
1607
|
+
}
|
|
1587
1608
|
return Array.from(workflowMap.values());
|
|
1588
1609
|
}
|
|
1610
|
+
async function saveWorkflowToProject(projectDir, workflow) {
|
|
1611
|
+
await saveItemToDir(getProjectWorkflowsDir(projectDir), workflow, WORKFLOW_EXTENSION, jsonSerializer);
|
|
1612
|
+
}
|
|
1613
|
+
async function deleteProjectWorkflow(projectDir, workflowId) {
|
|
1614
|
+
return deleteItemFromDir(getProjectWorkflowsDir(projectDir), workflowId, WORKFLOW_EXTENSION);
|
|
1615
|
+
}
|
|
1589
1616
|
async function getDefaultWorkflowIds() {
|
|
1590
1617
|
for (const dir of [DEFAULTS_DIR, DEFAULTS_DIR_ALT]) {
|
|
1591
1618
|
try {
|
|
@@ -1596,10 +1623,6 @@ async function getDefaultWorkflowIds() {
|
|
|
1596
1623
|
}
|
|
1597
1624
|
return [];
|
|
1598
1625
|
}
|
|
1599
|
-
async function getDefaultWorkflowContent(workflowId) {
|
|
1600
|
-
const defaults = await loadDefaultWorkflows();
|
|
1601
|
-
return defaults.find((w) => w.metadata.id === workflowId) ?? null;
|
|
1602
|
-
}
|
|
1603
1626
|
async function isDefaultWorkflow(workflowId) {
|
|
1604
1627
|
const defaultIds = await getDefaultWorkflowIds();
|
|
1605
1628
|
return defaultIds.includes(workflowId);
|
|
@@ -1607,9 +1630,11 @@ async function isDefaultWorkflow(workflowId) {
|
|
|
1607
1630
|
function findWorkflowById(workflowId, workflows) {
|
|
1608
1631
|
return workflows.find((p) => p.metadata.id === workflowId);
|
|
1609
1632
|
}
|
|
1610
|
-
async function workflowExists(configDir, workflowId) {
|
|
1611
|
-
|
|
1612
|
-
|
|
1633
|
+
async function workflowExists(configDir, workflowId, projectDir) {
|
|
1634
|
+
if (await pathExists2(join(getWorkflowsDir(configDir), `${workflowId}${WORKFLOW_EXTENSION}`))) return true;
|
|
1635
|
+
if (projectDir && await pathExists2(join(getProjectWorkflowsDir(projectDir), `${workflowId}${WORKFLOW_EXTENSION}`)))
|
|
1636
|
+
return true;
|
|
1637
|
+
return false;
|
|
1613
1638
|
}
|
|
1614
1639
|
async function saveWorkflow(configDir, workflow) {
|
|
1615
1640
|
const workflowsDir = getWorkflowsDir(configDir);
|
|
@@ -2480,7 +2505,7 @@ function processQueueAndRestartTurn(sessionManager, sessionId, drainFn, queueMod
|
|
|
2480
2505
|
}
|
|
2481
2506
|
var activeAgents = /* @__PURE__ */ new Map();
|
|
2482
2507
|
var MAX_SEND_QUEUE_SIZE = 1e3;
|
|
2483
|
-
function createWebSocketServer(httpServer,
|
|
2508
|
+
function createWebSocketServer(httpServer, config4, getLLMClient, getActiveProvider, sessionManager, providerManager) {
|
|
2484
2509
|
const wss = new WebSocketServer({ server: httpServer });
|
|
2485
2510
|
const clients = /* @__PURE__ */ new Map();
|
|
2486
2511
|
moduleClients = clients;
|
|
@@ -2507,9 +2532,9 @@ function createWebSocketServer(httpServer, config, getLLMClient, getActiveProvid
|
|
|
2507
2532
|
}
|
|
2508
2533
|
const baseUrl = provider.url.includes("/v1") ? provider.url : `${provider.url}/v1`;
|
|
2509
2534
|
const sessionConfig = {
|
|
2510
|
-
...
|
|
2535
|
+
...config4,
|
|
2511
2536
|
llm: {
|
|
2512
|
-
...
|
|
2537
|
+
...config4.llm,
|
|
2513
2538
|
baseUrl,
|
|
2514
2539
|
model: session.providerModel,
|
|
2515
2540
|
...provider.apiKey && { apiKey: provider.apiKey }
|
|
@@ -3113,10 +3138,10 @@ var LspServer = class {
|
|
|
3113
3138
|
// Pending diagnostic waiters
|
|
3114
3139
|
pendingDiagnostics = /* @__PURE__ */ new Map();
|
|
3115
3140
|
commandPath;
|
|
3116
|
-
constructor(
|
|
3117
|
-
this.config =
|
|
3141
|
+
constructor(config4, workdir, commandPath) {
|
|
3142
|
+
this.config = config4;
|
|
3118
3143
|
this.workdir = workdir;
|
|
3119
|
-
this.commandPath = commandPath ??
|
|
3144
|
+
this.commandPath = commandPath ?? config4.serverCommand;
|
|
3120
3145
|
}
|
|
3121
3146
|
// ============================================================================
|
|
3122
3147
|
// Lifecycle
|
|
@@ -3939,8 +3964,8 @@ var LspManager = class {
|
|
|
3939
3964
|
// ============================================================================
|
|
3940
3965
|
// Server Management
|
|
3941
3966
|
// ============================================================================
|
|
3942
|
-
async getOrCreateServer(
|
|
3943
|
-
const langId =
|
|
3967
|
+
async getOrCreateServer(config4) {
|
|
3968
|
+
const langId = config4.id;
|
|
3944
3969
|
const existing = this.servers.get(langId);
|
|
3945
3970
|
if (existing?.isRunning()) {
|
|
3946
3971
|
return existing;
|
|
@@ -3952,7 +3977,7 @@ var LspManager = class {
|
|
|
3952
3977
|
if (pending) {
|
|
3953
3978
|
return pending;
|
|
3954
3979
|
}
|
|
3955
|
-
const promise = this.startServer(
|
|
3980
|
+
const promise = this.startServer(config4);
|
|
3956
3981
|
this.serverPromises.set(langId, promise);
|
|
3957
3982
|
try {
|
|
3958
3983
|
const server = await promise;
|
|
@@ -3961,19 +3986,19 @@ var LspManager = class {
|
|
|
3961
3986
|
this.serverPromises.delete(langId);
|
|
3962
3987
|
}
|
|
3963
3988
|
}
|
|
3964
|
-
async startServer(
|
|
3965
|
-
const langId =
|
|
3966
|
-
const commandPath = await which(
|
|
3989
|
+
async startServer(config4) {
|
|
3990
|
+
const langId = config4.id;
|
|
3991
|
+
const commandPath = await which(config4.serverCommand, this.workdir);
|
|
3967
3992
|
if (!commandPath) {
|
|
3968
3993
|
logger.warn("LSP server not installed, skipping", {
|
|
3969
3994
|
language: langId,
|
|
3970
|
-
command:
|
|
3995
|
+
command: config4.serverCommand,
|
|
3971
3996
|
sessionId: this.sessionId
|
|
3972
3997
|
});
|
|
3973
3998
|
this.unavailableServers.add(langId);
|
|
3974
3999
|
return null;
|
|
3975
4000
|
}
|
|
3976
|
-
const server = new LspServer(
|
|
4001
|
+
const server = new LspServer(config4, this.workdir, commandPath);
|
|
3977
4002
|
try {
|
|
3978
4003
|
await server.start();
|
|
3979
4004
|
this.servers.set(langId, server);
|
|
@@ -3993,11 +4018,11 @@ var LspManager = class {
|
|
|
3993
4018
|
}
|
|
3994
4019
|
}
|
|
3995
4020
|
async getServerForFile(path) {
|
|
3996
|
-
const
|
|
3997
|
-
if (!
|
|
4021
|
+
const config4 = detectLanguage(path);
|
|
4022
|
+
if (!config4) {
|
|
3998
4023
|
return null;
|
|
3999
4024
|
}
|
|
4000
|
-
return this.getOrCreateServer(
|
|
4025
|
+
return this.getOrCreateServer(config4);
|
|
4001
4026
|
}
|
|
4002
4027
|
// ============================================================================
|
|
4003
4028
|
// Public Interface
|
|
@@ -4028,11 +4053,11 @@ var LspManager = class {
|
|
|
4028
4053
|
* Get current diagnostics for a file without triggering a change.
|
|
4029
4054
|
*/
|
|
4030
4055
|
getDiagnostics(path) {
|
|
4031
|
-
const
|
|
4032
|
-
if (!
|
|
4056
|
+
const config4 = detectLanguage(path);
|
|
4057
|
+
if (!config4) {
|
|
4033
4058
|
return [];
|
|
4034
4059
|
}
|
|
4035
|
-
const server = this.servers.get(
|
|
4060
|
+
const server = this.servers.get(config4.id);
|
|
4036
4061
|
if (!server?.isRunning()) {
|
|
4037
4062
|
return [];
|
|
4038
4063
|
}
|
|
@@ -4043,11 +4068,11 @@ var LspManager = class {
|
|
|
4043
4068
|
* Returns true if we have or can start a server for this file type.
|
|
4044
4069
|
*/
|
|
4045
4070
|
isAvailableFor(path) {
|
|
4046
|
-
const
|
|
4047
|
-
if (!
|
|
4071
|
+
const config4 = detectLanguage(path);
|
|
4072
|
+
if (!config4) {
|
|
4048
4073
|
return false;
|
|
4049
4074
|
}
|
|
4050
|
-
if (this.unavailableServers.has(
|
|
4075
|
+
if (this.unavailableServers.has(config4.id)) {
|
|
4051
4076
|
return false;
|
|
4052
4077
|
}
|
|
4053
4078
|
return true;
|
|
@@ -4835,130 +4860,197 @@ ${summary}`,
|
|
|
4835
4860
|
}
|
|
4836
4861
|
};
|
|
4837
4862
|
|
|
4838
|
-
// src/server/routes/skills.ts
|
|
4839
|
-
import { Router } from "express";
|
|
4840
|
-
|
|
4841
4863
|
// src/server/routes/crud-helpers.ts
|
|
4864
|
+
import { Router } from "express";
|
|
4865
|
+
import { join as join4 } from "path";
|
|
4842
4866
|
function computeOverrideIds(defaults, userItems) {
|
|
4843
4867
|
return userItems.filter((u) => defaults.some((d) => d.metadata.id === u.metadata.id)).map((u) => u.metadata.id);
|
|
4844
4868
|
}
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4869
|
+
var ID_REGEX = /^[a-z0-9-]+$/;
|
|
4870
|
+
function validateNameIdPrompt(body) {
|
|
4871
|
+
const meta = body["metadata"];
|
|
4872
|
+
if (!meta?.["name"] || !body["prompt"]) return "Missing required fields: metadata.name, prompt";
|
|
4873
|
+
if (meta["id"] && !ID_REGEX.test(String(meta["id"]))) return "ID must be lowercase alphanumeric with hyphens only";
|
|
4874
|
+
return null;
|
|
4875
|
+
}
|
|
4876
|
+
function getProjectItemPath(projectDir, dirName, id, ext) {
|
|
4877
|
+
return join4(projectDir, ".openfox", dirName, `${id}${ext}`);
|
|
4878
|
+
}
|
|
4879
|
+
async function isProjectItem(projectDir, dirName, id, ext) {
|
|
4880
|
+
if (!projectDir) return false;
|
|
4881
|
+
return pathExists(getProjectItemPath(projectDir, dirName, id, ext));
|
|
4882
|
+
}
|
|
4883
|
+
function createCrudRoutes(config4, configDir, projectDir) {
|
|
4848
4884
|
const router = Router();
|
|
4849
4885
|
router.get("/", async (_req, res) => {
|
|
4850
|
-
const [defaults, userItems] = await Promise.all([
|
|
4851
|
-
|
|
4886
|
+
const [defaults, userItems, projectItems] = await Promise.all([
|
|
4887
|
+
config4.loadDefaults(),
|
|
4888
|
+
config4.loadUser(configDir),
|
|
4889
|
+
projectDir ? config4.loadProject(projectDir) : []
|
|
4890
|
+
]);
|
|
4891
|
+
const userOverrideIds = computeOverrideIds(defaults, userItems);
|
|
4892
|
+
const projectOverrideIds = computeOverrideIds(defaults, projectItems);
|
|
4893
|
+
const extra = config4.extraGetData ? await config4.extraGetData() : {};
|
|
4852
4894
|
res.json({
|
|
4853
|
-
defaults: defaults.map(
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
...s.metadata,
|
|
4859
|
-
enabled: isSkillEnabled(s.metadata.id)
|
|
4860
|
-
})),
|
|
4861
|
-
overrideIds
|
|
4895
|
+
defaults: defaults.map(config4.mapToResponse),
|
|
4896
|
+
userItems: userItems.map(config4.mapToResponse),
|
|
4897
|
+
projectItems: projectItems.map(config4.mapToResponse),
|
|
4898
|
+
overrideIds: [...userOverrideIds, ...projectOverrideIds],
|
|
4899
|
+
...extra
|
|
4862
4900
|
});
|
|
4863
4901
|
});
|
|
4864
4902
|
router.get("/defaults/:id", async (req, res) => {
|
|
4865
4903
|
const { id } = req.params;
|
|
4866
|
-
const
|
|
4867
|
-
|
|
4868
|
-
|
|
4904
|
+
const allDefaults = await config4.loadDefaults();
|
|
4905
|
+
const item = allDefaults.find((d) => d.metadata.id === id);
|
|
4906
|
+
if (!item) {
|
|
4907
|
+
return res.status(404).json({ error: "Default not found" });
|
|
4869
4908
|
}
|
|
4870
|
-
res.json(
|
|
4909
|
+
res.json(item);
|
|
4871
4910
|
});
|
|
4872
4911
|
router.get("/default-ids", async (_req, res) => {
|
|
4873
|
-
const ids = await
|
|
4912
|
+
const ids = config4.getDefaultIds ? await config4.getDefaultIds() : [];
|
|
4874
4913
|
res.json({ ids });
|
|
4875
4914
|
});
|
|
4876
|
-
router.post("/:id/toggle", (req, res) => {
|
|
4877
|
-
const { id } = req.params;
|
|
4878
|
-
const currentlyEnabled = isSkillEnabled(id);
|
|
4879
|
-
setSkillEnabled(id, !currentlyEnabled);
|
|
4880
|
-
res.json({ id, enabled: !currentlyEnabled });
|
|
4881
|
-
});
|
|
4882
4915
|
router.get("/:id", async (req, res) => {
|
|
4883
4916
|
const { id } = req.params;
|
|
4884
|
-
const
|
|
4885
|
-
const
|
|
4886
|
-
if (!
|
|
4887
|
-
return res.status(404).json({ error: "
|
|
4917
|
+
const items = await config4.loadAll(configDir, projectDir);
|
|
4918
|
+
const item = config4.findById(id, items);
|
|
4919
|
+
if (!item) {
|
|
4920
|
+
return res.status(404).json({ error: "Not found" });
|
|
4888
4921
|
}
|
|
4889
|
-
res.json(
|
|
4922
|
+
res.json(item);
|
|
4890
4923
|
});
|
|
4891
4924
|
router.post("/", async (req, res) => {
|
|
4892
4925
|
const body = req.body;
|
|
4893
|
-
|
|
4894
|
-
|
|
4926
|
+
const meta = body["metadata"];
|
|
4927
|
+
const customError = config4.validateCreate?.(body);
|
|
4928
|
+
if (!meta?.["id"] || customError) {
|
|
4929
|
+
return res.status(400).json({ error: customError ?? "Missing required fields" });
|
|
4895
4930
|
}
|
|
4896
|
-
|
|
4897
|
-
|
|
4931
|
+
const id = String(meta["id"]);
|
|
4932
|
+
const destination = body["destination"] ?? "user";
|
|
4933
|
+
if (destination === "project" && !projectDir) {
|
|
4934
|
+
return res.status(400).json({ error: "No project directory configured" });
|
|
4898
4935
|
}
|
|
4899
|
-
const exists = await
|
|
4936
|
+
const exists = await config4.exists(configDir, id, projectDir);
|
|
4900
4937
|
if (exists) {
|
|
4901
|
-
return res.status(409).json({ error: "
|
|
4938
|
+
return res.status(409).json({ error: "An item with this ID already exists" });
|
|
4939
|
+
}
|
|
4940
|
+
if (destination === "project") {
|
|
4941
|
+
await config4.saveToProject(projectDir, body);
|
|
4942
|
+
} else {
|
|
4943
|
+
await config4.save(configDir, body);
|
|
4902
4944
|
}
|
|
4903
|
-
await saveSkill(configDir, body);
|
|
4904
4945
|
res.status(201).json(body);
|
|
4905
4946
|
});
|
|
4906
4947
|
router.put("/:id", async (req, res) => {
|
|
4907
4948
|
const { id } = req.params;
|
|
4908
|
-
const
|
|
4909
|
-
const existing =
|
|
4949
|
+
const items = await config4.loadAll(configDir, projectDir);
|
|
4950
|
+
const existing = config4.findById(id, items);
|
|
4910
4951
|
if (!existing) {
|
|
4911
|
-
return res.status(404).json({ error: "
|
|
4952
|
+
return res.status(404).json({ error: "Not found" });
|
|
4912
4953
|
}
|
|
4913
4954
|
const body = req.body;
|
|
4955
|
+
const meta = body["metadata"];
|
|
4914
4956
|
const updated = {
|
|
4915
|
-
|
|
4916
|
-
|
|
4957
|
+
...existing,
|
|
4958
|
+
...body,
|
|
4959
|
+
metadata: { ...existing.metadata, ...meta, id }
|
|
4917
4960
|
};
|
|
4918
|
-
await
|
|
4961
|
+
const isProject = await isProjectItem(projectDir, config4.dirName, id, config4.ext);
|
|
4962
|
+
if (isProject) {
|
|
4963
|
+
await config4.saveToProject(projectDir, updated);
|
|
4964
|
+
} else {
|
|
4965
|
+
await config4.save(configDir, updated);
|
|
4966
|
+
}
|
|
4919
4967
|
res.json(updated);
|
|
4920
4968
|
});
|
|
4921
4969
|
router.delete("/:id", async (req, res) => {
|
|
4922
4970
|
const { id } = req.params;
|
|
4923
|
-
const
|
|
4971
|
+
const isProject = await isProjectItem(projectDir, config4.dirName, id, config4.ext);
|
|
4972
|
+
if (isProject) {
|
|
4973
|
+
const result2 = await config4.deleteProject(projectDir, id);
|
|
4974
|
+
if (!result2.success) {
|
|
4975
|
+
return res.status(500).json({ error: "Failed to delete project item" });
|
|
4976
|
+
}
|
|
4977
|
+
return res.json({ success: true });
|
|
4978
|
+
}
|
|
4979
|
+
const isDefault = await config4.isDefault(id);
|
|
4980
|
+
if (isDefault) {
|
|
4981
|
+
return res.status(403).json({ error: "Cannot delete built-in defaults" });
|
|
4982
|
+
}
|
|
4983
|
+
const result = await config4.delete(configDir, id);
|
|
4924
4984
|
if (!result.success) {
|
|
4925
|
-
return res.status(403).json({ error: result.reason ?? "Cannot delete this
|
|
4985
|
+
return res.status(403).json({ error: result.reason ?? "Cannot delete this item" });
|
|
4926
4986
|
}
|
|
4927
4987
|
res.json({ success: true });
|
|
4928
4988
|
});
|
|
4929
4989
|
router.post("/:id/duplicate", async (req, res) => {
|
|
4930
4990
|
const { id } = req.params;
|
|
4931
|
-
const
|
|
4932
|
-
const
|
|
4933
|
-
const source = defaults.find((s) => s.metadata.id === id) ?? userItems.find((s) => s.metadata.id === id);
|
|
4991
|
+
const items = await config4.loadAll(configDir, projectDir);
|
|
4992
|
+
const source = config4.findById(id, items);
|
|
4934
4993
|
if (!source) {
|
|
4935
|
-
return res.status(404).json({ error: "
|
|
4994
|
+
return res.status(404).json({ error: "Not found" });
|
|
4936
4995
|
}
|
|
4937
4996
|
const newId = `${id}-copy-${Date.now()}`;
|
|
4938
4997
|
const duplicated = {
|
|
4939
|
-
|
|
4940
|
-
|
|
4998
|
+
...source,
|
|
4999
|
+
metadata: { ...source.metadata, id: newId, name: `${source.metadata.name} (copy)` }
|
|
4941
5000
|
};
|
|
4942
|
-
|
|
5001
|
+
const destination = req.body.destination ?? "user";
|
|
5002
|
+
if (destination === "project") {
|
|
5003
|
+
if (!projectDir) return res.status(400).json({ error: "No project directory configured" });
|
|
5004
|
+
await config4.saveToProject(projectDir, duplicated);
|
|
5005
|
+
} else {
|
|
5006
|
+
await config4.save(configDir, duplicated);
|
|
5007
|
+
}
|
|
4943
5008
|
res.status(201).json(duplicated);
|
|
4944
5009
|
});
|
|
5010
|
+
config4.extraRoutes?.(router);
|
|
4945
5011
|
return router;
|
|
4946
5012
|
}
|
|
4947
5013
|
|
|
4948
|
-
// src/server/routes/
|
|
4949
|
-
|
|
5014
|
+
// src/server/routes/skills.ts
|
|
5015
|
+
var config = {
|
|
5016
|
+
dirName: "skills",
|
|
5017
|
+
ext: ".skill.md",
|
|
5018
|
+
loadDefaults: loadDefaultSkills,
|
|
5019
|
+
loadUser: loadUserSkills,
|
|
5020
|
+
loadProject: loadProjectSkills,
|
|
5021
|
+
loadAll: loadAllSkills,
|
|
5022
|
+
findById: findSkillById,
|
|
5023
|
+
save: saveSkill,
|
|
5024
|
+
saveToProject: saveSkillToProject,
|
|
5025
|
+
delete: deleteSkill,
|
|
5026
|
+
deleteProject: deleteProjectSkill,
|
|
5027
|
+
exists: skillExists,
|
|
5028
|
+
isDefault: isDefaultSkill,
|
|
5029
|
+
getDefaultIds: getDefaultSkillIds,
|
|
5030
|
+
validateCreate: validateNameIdPrompt,
|
|
5031
|
+
mapToResponse: (s) => ({
|
|
5032
|
+
...s.metadata,
|
|
5033
|
+
enabled: isSkillEnabled(s.metadata.id)
|
|
5034
|
+
})
|
|
5035
|
+
};
|
|
5036
|
+
function createSkillRoutes(configDir, projectDir) {
|
|
5037
|
+
return createCrudRoutes(config, configDir, projectDir);
|
|
5038
|
+
}
|
|
4950
5039
|
|
|
4951
5040
|
// src/server/commands/registry.ts
|
|
4952
5041
|
import { writeFile as writeFile3, mkdir as mkdir3, unlink as unlink2 } from "fs/promises";
|
|
4953
|
-
import { join as
|
|
5042
|
+
import { join as join5, dirname as dirname4 } from "path";
|
|
4954
5043
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4955
5044
|
import matter from "gray-matter";
|
|
4956
5045
|
var __bundleDir2 = dirname4(fileURLToPath3(import.meta.url));
|
|
4957
|
-
var DEFAULTS_DIR2 =
|
|
4958
|
-
var DEFAULTS_DIR_ALT2 =
|
|
5046
|
+
var DEFAULTS_DIR2 = join5(__bundleDir2, "defaults");
|
|
5047
|
+
var DEFAULTS_DIR_ALT2 = join5(__bundleDir2, "command-defaults");
|
|
4959
5048
|
var COMMAND_EXTENSION = ".command.md";
|
|
4960
5049
|
function getCommandsDir(configDir) {
|
|
4961
|
-
return
|
|
5050
|
+
return join5(configDir, "commands");
|
|
5051
|
+
}
|
|
5052
|
+
function getProjectCommandsDir(projectDir) {
|
|
5053
|
+
return join5(projectDir, ".openfox", "commands");
|
|
4962
5054
|
}
|
|
4963
5055
|
async function loadDefaultCommands() {
|
|
4964
5056
|
let defaults = await loadItemsFromDir(DEFAULTS_DIR2, {
|
|
@@ -4979,7 +5071,13 @@ async function loadUserCommands(configDir) {
|
|
|
4979
5071
|
logName: "command"
|
|
4980
5072
|
});
|
|
4981
5073
|
}
|
|
4982
|
-
async function
|
|
5074
|
+
async function loadProjectCommands(projectDir) {
|
|
5075
|
+
return loadItemsFromDir(getProjectCommandsDir(projectDir), {
|
|
5076
|
+
extension: COMMAND_EXTENSION,
|
|
5077
|
+
logName: "command"
|
|
5078
|
+
});
|
|
5079
|
+
}
|
|
5080
|
+
async function loadAllCommands(configDir, projectDir) {
|
|
4983
5081
|
const [defaultCommands, userCommands] = await Promise.all([loadDefaultCommands(), loadUserCommands(configDir)]);
|
|
4984
5082
|
const commandMap = /* @__PURE__ */ new Map();
|
|
4985
5083
|
for (const cmd of defaultCommands) {
|
|
@@ -4988,6 +5086,12 @@ async function loadAllCommands(configDir) {
|
|
|
4988
5086
|
for (const cmd of userCommands) {
|
|
4989
5087
|
commandMap.set(cmd.metadata.id, cmd);
|
|
4990
5088
|
}
|
|
5089
|
+
if (projectDir) {
|
|
5090
|
+
const projectCommands = await loadProjectCommands(projectDir);
|
|
5091
|
+
for (const cmd of projectCommands) {
|
|
5092
|
+
commandMap.set(cmd.metadata.id, cmd);
|
|
5093
|
+
}
|
|
5094
|
+
}
|
|
4991
5095
|
return Array.from(commandMap.values());
|
|
4992
5096
|
}
|
|
4993
5097
|
async function getDefaultCommandIds() {
|
|
@@ -4995,10 +5099,6 @@ async function getDefaultCommandIds() {
|
|
|
4995
5099
|
if (ids.length) return ids;
|
|
4996
5100
|
return getDefaultIds(DEFAULTS_DIR_ALT2, COMMAND_EXTENSION);
|
|
4997
5101
|
}
|
|
4998
|
-
async function getDefaultCommandContent(commandId) {
|
|
4999
|
-
const defaults = await loadDefaultCommands();
|
|
5000
|
-
return defaults.find((c) => c.metadata.id === commandId) ?? null;
|
|
5001
|
-
}
|
|
5002
5102
|
async function isDefaultCommand(commandId) {
|
|
5003
5103
|
const defaultIds = await getDefaultCommandIds();
|
|
5004
5104
|
return defaultIds.includes(commandId);
|
|
@@ -5006,24 +5106,38 @@ async function isDefaultCommand(commandId) {
|
|
|
5006
5106
|
function findCommandById(commandId, commands) {
|
|
5007
5107
|
return commands.find((c) => c.metadata.id === commandId);
|
|
5008
5108
|
}
|
|
5009
|
-
async function commandExists(configDir, commandId) {
|
|
5010
|
-
|
|
5109
|
+
async function commandExists(configDir, commandId, projectDir) {
|
|
5110
|
+
if (await pathExists(join5(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`))) return true;
|
|
5111
|
+
if (projectDir && await pathExists(join5(getProjectCommandsDir(projectDir), `${commandId}${COMMAND_EXTENSION}`)))
|
|
5112
|
+
return true;
|
|
5113
|
+
return false;
|
|
5011
5114
|
}
|
|
5012
5115
|
async function saveCommand(configDir, command) {
|
|
5013
5116
|
const commandsDir = getCommandsDir(configDir);
|
|
5014
5117
|
if (!await pathExists(commandsDir)) {
|
|
5015
5118
|
await mkdir3(commandsDir, { recursive: true });
|
|
5016
5119
|
}
|
|
5017
|
-
const filePath =
|
|
5120
|
+
const filePath = join5(commandsDir, `${command.metadata.id}${COMMAND_EXTENSION}`);
|
|
5018
5121
|
const content = matter.stringify(command.prompt, command.metadata);
|
|
5019
5122
|
await writeFile3(filePath, content, "utf-8");
|
|
5020
5123
|
}
|
|
5124
|
+
async function saveCommandToProject(projectDir, command) {
|
|
5125
|
+
await saveItemToDir(
|
|
5126
|
+
getProjectCommandsDir(projectDir),
|
|
5127
|
+
command,
|
|
5128
|
+
COMMAND_EXTENSION,
|
|
5129
|
+
(c) => matter.stringify(c.prompt, c.metadata)
|
|
5130
|
+
);
|
|
5131
|
+
}
|
|
5132
|
+
async function deleteProjectCommand(projectDir, commandId) {
|
|
5133
|
+
return deleteItemFromDir(getProjectCommandsDir(projectDir), commandId, COMMAND_EXTENSION);
|
|
5134
|
+
}
|
|
5021
5135
|
async function deleteCommand(configDir, commandId) {
|
|
5022
5136
|
const isDefault = await isDefaultCommand(commandId);
|
|
5023
5137
|
if (isDefault) {
|
|
5024
5138
|
return { success: false, reason: "Cannot delete built-in defaults" };
|
|
5025
5139
|
}
|
|
5026
|
-
const filePath =
|
|
5140
|
+
const filePath = join5(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`);
|
|
5027
5141
|
try {
|
|
5028
5142
|
await unlink2(filePath);
|
|
5029
5143
|
return { success: true };
|
|
@@ -5033,292 +5147,106 @@ async function deleteCommand(configDir, commandId) {
|
|
|
5033
5147
|
}
|
|
5034
5148
|
|
|
5035
5149
|
// src/server/routes/commands.ts
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5039
|
-
|
|
5040
|
-
|
|
5041
|
-
|
|
5042
|
-
|
|
5043
|
-
|
|
5044
|
-
|
|
5045
|
-
|
|
5046
|
-
|
|
5047
|
-
|
|
5048
|
-
|
|
5049
|
-
|
|
5050
|
-
|
|
5051
|
-
|
|
5052
|
-
|
|
5053
|
-
|
|
5054
|
-
|
|
5055
|
-
|
|
5056
|
-
const ids = await getDefaultCommandIds();
|
|
5057
|
-
res.json({ ids });
|
|
5058
|
-
});
|
|
5059
|
-
router.get("/:id", async (req, res) => {
|
|
5060
|
-
const { id } = req.params;
|
|
5061
|
-
const commands = await loadAllCommands(configDir);
|
|
5062
|
-
const command = findCommandById(id, commands);
|
|
5063
|
-
if (!command) {
|
|
5064
|
-
return res.status(404).json({ error: "Command not found" });
|
|
5065
|
-
}
|
|
5066
|
-
res.json(command);
|
|
5067
|
-
});
|
|
5068
|
-
router.post("/", async (req, res) => {
|
|
5069
|
-
const body = req.body;
|
|
5070
|
-
if (!body.metadata?.id || !body.metadata?.name || !body.prompt) {
|
|
5071
|
-
return res.status(400).json({ error: "Missing required fields: metadata.id, metadata.name, prompt" });
|
|
5072
|
-
}
|
|
5073
|
-
if (!/^[a-z0-9-]+$/.test(body.metadata.id)) {
|
|
5074
|
-
return res.status(400).json({ error: "Command ID must be lowercase alphanumeric with hyphens only" });
|
|
5075
|
-
}
|
|
5076
|
-
const exists = await commandExists(configDir, body.metadata.id);
|
|
5077
|
-
if (exists) {
|
|
5078
|
-
return res.status(409).json({ error: "A command with this ID already exists" });
|
|
5079
|
-
}
|
|
5080
|
-
await saveCommand(configDir, body);
|
|
5081
|
-
res.status(201).json(body);
|
|
5082
|
-
});
|
|
5083
|
-
router.put("/:id", async (req, res) => {
|
|
5084
|
-
const { id } = req.params;
|
|
5085
|
-
const commands = await loadAllCommands(configDir);
|
|
5086
|
-
const existing = findCommandById(id, commands);
|
|
5087
|
-
if (!existing) {
|
|
5088
|
-
return res.status(404).json({ error: "Command not found" });
|
|
5089
|
-
}
|
|
5090
|
-
const body = req.body;
|
|
5091
|
-
const updated = {
|
|
5092
|
-
metadata: { ...existing.metadata, ...body.metadata, id },
|
|
5093
|
-
prompt: body.prompt ?? existing.prompt
|
|
5094
|
-
};
|
|
5095
|
-
await saveCommand(configDir, updated);
|
|
5096
|
-
res.json(updated);
|
|
5097
|
-
});
|
|
5098
|
-
router.delete("/:id", async (req, res) => {
|
|
5099
|
-
const { id } = req.params;
|
|
5100
|
-
const result = await deleteCommand(configDir, id);
|
|
5101
|
-
if (!result.success) {
|
|
5102
|
-
return res.status(403).json({ error: result.reason ?? "Cannot delete this command" });
|
|
5103
|
-
}
|
|
5104
|
-
res.json({ success: true });
|
|
5105
|
-
});
|
|
5106
|
-
router.post("/:id/duplicate", async (req, res) => {
|
|
5107
|
-
const { id } = req.params;
|
|
5108
|
-
const defaults = await loadDefaultCommands();
|
|
5109
|
-
const userItems = await loadUserCommands(configDir);
|
|
5110
|
-
const source = defaults.find((c) => c.metadata.id === id) ?? userItems.find((c) => c.metadata.id === id);
|
|
5111
|
-
if (!source) {
|
|
5112
|
-
return res.status(404).json({ error: "Command not found" });
|
|
5113
|
-
}
|
|
5114
|
-
const newId = `${id}-copy-${Date.now()}`;
|
|
5115
|
-
const duplicated = {
|
|
5116
|
-
metadata: { ...source.metadata, id: newId, name: `${source.metadata.name} (copy)` },
|
|
5117
|
-
prompt: source.prompt
|
|
5118
|
-
};
|
|
5119
|
-
await saveCommand(configDir, duplicated);
|
|
5120
|
-
res.status(201).json(duplicated);
|
|
5121
|
-
});
|
|
5122
|
-
return router;
|
|
5150
|
+
var config2 = {
|
|
5151
|
+
dirName: "commands",
|
|
5152
|
+
ext: ".command.md",
|
|
5153
|
+
loadDefaults: loadDefaultCommands,
|
|
5154
|
+
loadUser: loadUserCommands,
|
|
5155
|
+
loadProject: loadProjectCommands,
|
|
5156
|
+
loadAll: loadAllCommands,
|
|
5157
|
+
findById: findCommandById,
|
|
5158
|
+
save: saveCommand,
|
|
5159
|
+
saveToProject: saveCommandToProject,
|
|
5160
|
+
delete: deleteCommand,
|
|
5161
|
+
deleteProject: deleteProjectCommand,
|
|
5162
|
+
exists: commandExists,
|
|
5163
|
+
isDefault: isDefaultCommand,
|
|
5164
|
+
getDefaultIds: getDefaultCommandIds,
|
|
5165
|
+
validateCreate: validateNameIdPrompt,
|
|
5166
|
+
mapToResponse: (c) => c.metadata
|
|
5167
|
+
};
|
|
5168
|
+
function createCommandRoutes(configDir, projectDir) {
|
|
5169
|
+
return createCrudRoutes(config2, configDir, projectDir);
|
|
5123
5170
|
}
|
|
5124
5171
|
|
|
5125
5172
|
// src/server/routes/agents.ts
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
|
|
5130
|
-
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
}
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
router.get("/:id", async (req, res) => {
|
|
5151
|
-
const { id } = req.params;
|
|
5152
|
-
const agents = await loadAllAgents(configDir);
|
|
5153
|
-
const agent = findAgentById(id, agents);
|
|
5154
|
-
if (!agent) {
|
|
5155
|
-
return res.status(404).json({ error: "Agent not found" });
|
|
5156
|
-
}
|
|
5157
|
-
res.json(agent);
|
|
5158
|
-
});
|
|
5159
|
-
router.post("/", async (req, res) => {
|
|
5160
|
-
const body = req.body;
|
|
5161
|
-
if (!body?.metadata?.id || !body?.prompt) {
|
|
5162
|
-
return res.status(400).json({ error: "Missing required fields: metadata.id, prompt" });
|
|
5163
|
-
}
|
|
5164
|
-
const exists = await agentExists(configDir, body.metadata.id);
|
|
5165
|
-
if (exists) {
|
|
5166
|
-
return res.status(409).json({ error: "An agent with this ID already exists" });
|
|
5167
|
-
}
|
|
5168
|
-
await saveAgent(configDir, body);
|
|
5169
|
-
res.status(201).json(body);
|
|
5170
|
-
});
|
|
5171
|
-
router.put("/:id", async (req, res) => {
|
|
5172
|
-
const { id } = req.params;
|
|
5173
|
-
if (!id) {
|
|
5174
|
-
return res.status(400).json({ error: "Missing agent ID" });
|
|
5175
|
-
}
|
|
5176
|
-
const body = req.body;
|
|
5177
|
-
const agents = await loadAllAgents(configDir);
|
|
5178
|
-
const existing = findAgentById(id, agents);
|
|
5179
|
-
if (!existing) {
|
|
5180
|
-
return res.status(404).json({ error: "Agent not found" });
|
|
5181
|
-
}
|
|
5182
|
-
const updated = {
|
|
5183
|
-
metadata: { ...existing.metadata, ...body.metadata, id },
|
|
5184
|
-
prompt: body.prompt ?? existing.prompt
|
|
5185
|
-
};
|
|
5186
|
-
await saveAgent(configDir, updated);
|
|
5187
|
-
res.json(updated);
|
|
5188
|
-
});
|
|
5189
|
-
router.delete("/:id", async (req, res) => {
|
|
5190
|
-
const { id } = req.params;
|
|
5191
|
-
const result = await deleteAgent(configDir, id);
|
|
5192
|
-
if (!result.success) {
|
|
5193
|
-
return res.status(403).json({ error: result.reason ?? "Cannot delete this agent" });
|
|
5194
|
-
}
|
|
5195
|
-
res.json({ success: true });
|
|
5196
|
-
});
|
|
5197
|
-
router.post("/:id/duplicate", async (req, res) => {
|
|
5198
|
-
const { id } = req.params;
|
|
5199
|
-
const defaults = await loadDefaultAgents();
|
|
5200
|
-
const userItems = await loadUserAgents(configDir);
|
|
5201
|
-
const source = defaults.find((a) => a.metadata.id === id) ?? userItems.find((a) => a.metadata.id === id);
|
|
5202
|
-
if (!source) {
|
|
5203
|
-
return res.status(404).json({ error: "Agent not found" });
|
|
5204
|
-
}
|
|
5205
|
-
const newId = `${id}-copy-${Date.now()}`;
|
|
5206
|
-
const duplicated = {
|
|
5207
|
-
metadata: { ...source.metadata, id: newId, name: `${source.metadata.name} (copy)` },
|
|
5208
|
-
prompt: source.prompt
|
|
5209
|
-
};
|
|
5210
|
-
await saveAgent(configDir, duplicated);
|
|
5211
|
-
res.status(201).json(duplicated);
|
|
5212
|
-
});
|
|
5213
|
-
return router;
|
|
5173
|
+
var config3 = {
|
|
5174
|
+
dirName: "agents",
|
|
5175
|
+
ext: ".agent.md",
|
|
5176
|
+
loadDefaults: loadDefaultAgents,
|
|
5177
|
+
loadUser: loadUserAgents,
|
|
5178
|
+
loadProject: loadProjectAgents,
|
|
5179
|
+
loadAll: loadAllAgents,
|
|
5180
|
+
findById: findAgentById,
|
|
5181
|
+
save: saveAgent,
|
|
5182
|
+
saveToProject: saveAgentToProject,
|
|
5183
|
+
delete: deleteAgent,
|
|
5184
|
+
deleteProject: deleteProjectAgent,
|
|
5185
|
+
exists: agentExists,
|
|
5186
|
+
isDefault: isDefaultAgent,
|
|
5187
|
+
getDefaultIds: getDefaultAgentIds,
|
|
5188
|
+
validateCreate: (body) => {
|
|
5189
|
+
const meta = body["metadata"];
|
|
5190
|
+
if (!meta?.["id"] || !body["prompt"]) return "Missing required fields: metadata.id, prompt";
|
|
5191
|
+
return null;
|
|
5192
|
+
},
|
|
5193
|
+
mapToResponse: (a) => a.metadata
|
|
5194
|
+
};
|
|
5195
|
+
function createAgentRoutes(configDir, projectDir) {
|
|
5196
|
+
return createCrudRoutes(config3, configDir, projectDir);
|
|
5214
5197
|
}
|
|
5215
5198
|
|
|
5216
5199
|
// src/server/routes/workflows.ts
|
|
5217
|
-
import
|
|
5218
|
-
function createWorkflowRoutes(configDir,
|
|
5219
|
-
const
|
|
5220
|
-
|
|
5221
|
-
|
|
5222
|
-
|
|
5223
|
-
|
|
5224
|
-
|
|
5225
|
-
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
|
|
5234
|
-
|
|
5235
|
-
|
|
5236
|
-
|
|
5237
|
-
return
|
|
5238
|
-
}
|
|
5239
|
-
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5243
|
-
|
|
5244
|
-
|
|
5245
|
-
|
|
5246
|
-
|
|
5247
|
-
|
|
5248
|
-
const workflow = findWorkflowById(id, workflows);
|
|
5249
|
-
if (!workflow) {
|
|
5250
|
-
return res.status(404).json({ error: "Workflow not found" });
|
|
5251
|
-
}
|
|
5252
|
-
res.json(workflow);
|
|
5253
|
-
});
|
|
5254
|
-
router.post("/", async (req, res) => {
|
|
5255
|
-
const body = req.body;
|
|
5256
|
-
if (!body?.metadata?.id || !body?.steps?.length) {
|
|
5257
|
-
return res.status(400).json({ error: "Missing required fields: metadata.id, steps" });
|
|
5258
|
-
}
|
|
5259
|
-
const exists = await workflowExists(configDir, body.metadata.id);
|
|
5260
|
-
if (exists) {
|
|
5261
|
-
return res.status(409).json({ error: "A workflow with this ID already exists" });
|
|
5262
|
-
}
|
|
5263
|
-
await saveWorkflow(configDir, body);
|
|
5264
|
-
res.status(201).json(body);
|
|
5265
|
-
});
|
|
5266
|
-
router.put("/:id", async (req, res) => {
|
|
5267
|
-
const { id } = req.params;
|
|
5268
|
-
const workflows = await loadAllWorkflows(configDir);
|
|
5269
|
-
const existing = findWorkflowById(id, workflows);
|
|
5270
|
-
if (!existing) {
|
|
5271
|
-
return res.status(404).json({ error: "Workflow not found" });
|
|
5272
|
-
}
|
|
5273
|
-
const body = req.body;
|
|
5274
|
-
const updated = {
|
|
5275
|
-
...body,
|
|
5276
|
-
metadata: { ...body.metadata, id }
|
|
5277
|
-
};
|
|
5278
|
-
await saveWorkflow(configDir, updated);
|
|
5279
|
-
res.json(updated);
|
|
5280
|
-
});
|
|
5281
|
-
router.delete("/:id", async (req, res) => {
|
|
5282
|
-
const { id } = req.params;
|
|
5283
|
-
const result = await deleteWorkflow(configDir, id);
|
|
5284
|
-
if (!result.success) {
|
|
5285
|
-
return res.status(403).json({ error: result.reason ?? "Cannot delete this workflow" });
|
|
5286
|
-
}
|
|
5287
|
-
res.json({ success: true });
|
|
5288
|
-
});
|
|
5289
|
-
router.post("/:id/duplicate", async (req, res) => {
|
|
5290
|
-
const { id } = req.params;
|
|
5291
|
-
const defaults = await loadDefaultWorkflows();
|
|
5292
|
-
const userItems = await loadUserWorkflows(configDir);
|
|
5293
|
-
const source = defaults.find((w) => w.metadata.id === id) ?? userItems.find((w) => w.metadata.id === id);
|
|
5294
|
-
if (!source) {
|
|
5295
|
-
return res.status(404).json({ error: "Workflow not found" });
|
|
5200
|
+
import "express";
|
|
5201
|
+
function createWorkflowRoutes(configDir, config4, projectDir) {
|
|
5202
|
+
const crudConfig = {
|
|
5203
|
+
dirName: "workflows",
|
|
5204
|
+
ext: ".workflow.json",
|
|
5205
|
+
loadDefaults: loadDefaultWorkflows,
|
|
5206
|
+
loadUser: loadUserWorkflows,
|
|
5207
|
+
loadProject: loadProjectWorkflows,
|
|
5208
|
+
loadAll: loadAllWorkflows,
|
|
5209
|
+
findById: findWorkflowById,
|
|
5210
|
+
save: saveWorkflow,
|
|
5211
|
+
saveToProject: saveWorkflowToProject,
|
|
5212
|
+
delete: deleteWorkflow,
|
|
5213
|
+
deleteProject: deleteProjectWorkflow,
|
|
5214
|
+
exists: workflowExists,
|
|
5215
|
+
isDefault: isDefaultWorkflow,
|
|
5216
|
+
getDefaultIds: getDefaultWorkflowIds,
|
|
5217
|
+
validateCreate: (body) => {
|
|
5218
|
+
const steps = body["steps"];
|
|
5219
|
+
if (!Array.isArray(steps) || steps.length === 0) return "Missing required fields: metadata.id, steps";
|
|
5220
|
+
return null;
|
|
5221
|
+
},
|
|
5222
|
+
mapToResponse: (w) => ({
|
|
5223
|
+
...w.metadata,
|
|
5224
|
+
startCondition: w.startCondition
|
|
5225
|
+
}),
|
|
5226
|
+
extraGetData: () => Promise.resolve({ activeWorkflowId: config4.activeWorkflowId ?? "default" }),
|
|
5227
|
+
extraRoutes: (router) => {
|
|
5228
|
+
router.get("/template-variables", (_req, res) => {
|
|
5229
|
+
res.json({ variables: TEMPLATE_VARIABLES });
|
|
5230
|
+
});
|
|
5296
5231
|
}
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
...source,
|
|
5300
|
-
metadata: { ...source.metadata, id: newId, name: `${source.metadata.name} (copy)` }
|
|
5301
|
-
};
|
|
5302
|
-
await saveWorkflow(configDir, duplicated);
|
|
5303
|
-
res.status(201).json(duplicated);
|
|
5304
|
-
});
|
|
5305
|
-
return router;
|
|
5232
|
+
};
|
|
5233
|
+
return createCrudRoutes(crudConfig, configDir, projectDir);
|
|
5306
5234
|
}
|
|
5307
5235
|
|
|
5308
5236
|
// src/server/routes/dev-server.ts
|
|
5309
|
-
import { Router as
|
|
5237
|
+
import { Router as Router3 } from "express";
|
|
5310
5238
|
function createDevServerRoutes() {
|
|
5311
|
-
const router =
|
|
5239
|
+
const router = Router3();
|
|
5312
5240
|
router.get("/", async (req, res) => {
|
|
5313
5241
|
const workdir = req.query["workdir"];
|
|
5314
5242
|
if (!workdir) return res.status(400).json({ error: "workdir required" });
|
|
5315
5243
|
const status = devServerManager.getStatus(workdir);
|
|
5316
5244
|
if (!status.config) {
|
|
5317
|
-
const
|
|
5318
|
-
if (
|
|
5319
|
-
status.config =
|
|
5320
|
-
status.url =
|
|
5321
|
-
status.hotReload =
|
|
5245
|
+
const config4 = await devServerManager.loadConfig(workdir);
|
|
5246
|
+
if (config4) {
|
|
5247
|
+
status.config = config4;
|
|
5248
|
+
status.url = config4.url;
|
|
5249
|
+
status.hotReload = config4.hotReload;
|
|
5322
5250
|
}
|
|
5323
5251
|
}
|
|
5324
5252
|
res.json(status);
|
|
@@ -5364,8 +5292,8 @@ function createDevServerRoutes() {
|
|
|
5364
5292
|
router.get("/config", async (req, res) => {
|
|
5365
5293
|
const workdir = req.query["workdir"];
|
|
5366
5294
|
if (!workdir) return res.status(400).json({ error: "workdir required" });
|
|
5367
|
-
const
|
|
5368
|
-
res.json({ config });
|
|
5295
|
+
const config4 = await devServerManager.loadConfig(workdir);
|
|
5296
|
+
res.json({ config: config4 });
|
|
5369
5297
|
});
|
|
5370
5298
|
router.post("/config", async (req, res) => {
|
|
5371
5299
|
const workdir = req.query["workdir"];
|
|
@@ -5375,9 +5303,9 @@ function createDevServerRoutes() {
|
|
|
5375
5303
|
return res.status(400).json({ error: "command and url are required" });
|
|
5376
5304
|
}
|
|
5377
5305
|
try {
|
|
5378
|
-
const
|
|
5379
|
-
await devServerManager.saveConfig(workdir,
|
|
5380
|
-
res.json({ config });
|
|
5306
|
+
const config4 = { command, url, hotReload: hotReload ?? false, disableInspect: disableInspect ?? false };
|
|
5307
|
+
await devServerManager.saveConfig(workdir, config4);
|
|
5308
|
+
res.json({ config: config4 });
|
|
5381
5309
|
} catch (err) {
|
|
5382
5310
|
res.status(500).json({ error: err instanceof Error ? err.message : "Failed to save config" });
|
|
5383
5311
|
}
|
|
@@ -5386,9 +5314,9 @@ function createDevServerRoutes() {
|
|
|
5386
5314
|
}
|
|
5387
5315
|
|
|
5388
5316
|
// src/server/routes/terminals.ts
|
|
5389
|
-
import { Router as
|
|
5317
|
+
import { Router as Router4 } from "express";
|
|
5390
5318
|
function createTerminalRoutes() {
|
|
5391
|
-
const router =
|
|
5319
|
+
const router = Router4();
|
|
5392
5320
|
router.get("/", (req, res) => {
|
|
5393
5321
|
const projectId = req.query["projectId"];
|
|
5394
5322
|
const sessions = projectId ? terminalManager.getByProject(projectId) : [];
|
|
@@ -5426,19 +5354,105 @@ function createTerminalRoutes() {
|
|
|
5426
5354
|
return router;
|
|
5427
5355
|
}
|
|
5428
5356
|
|
|
5357
|
+
// src/server/routes/auto-update.ts
|
|
5358
|
+
import { Router as Router5 } from "express";
|
|
5359
|
+
import { spawn as spawn4 } from "child_process";
|
|
5360
|
+
|
|
5429
5361
|
// src/constants.ts
|
|
5430
|
-
var VERSION = "1.6.
|
|
5362
|
+
var VERSION = "1.6.92";
|
|
5363
|
+
|
|
5364
|
+
// src/server/routes/auto-update.ts
|
|
5365
|
+
var updateInProgress = false;
|
|
5366
|
+
function createAutoUpdateRoutes(options = {}) {
|
|
5367
|
+
const router = Router5();
|
|
5368
|
+
router.get("/check", async (req, res) => {
|
|
5369
|
+
const isTest = req.query["test"] === "1";
|
|
5370
|
+
const current = VERSION;
|
|
5371
|
+
if (isTest) {
|
|
5372
|
+
res.json({ current: "1.0.0", latest: "1.1.0", isUpdateAvailable: true });
|
|
5373
|
+
return;
|
|
5374
|
+
}
|
|
5375
|
+
try {
|
|
5376
|
+
const latest = await new Promise((resolve2, reject) => {
|
|
5377
|
+
const child = spawn4("npm", ["view", "openfox", "version"], {
|
|
5378
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
5379
|
+
});
|
|
5380
|
+
let stdout = "";
|
|
5381
|
+
child.stdout?.on("data", (data) => {
|
|
5382
|
+
stdout += data.toString();
|
|
5383
|
+
});
|
|
5384
|
+
child.on("close", (code) => {
|
|
5385
|
+
if (code === 0) {
|
|
5386
|
+
resolve2(stdout.trim());
|
|
5387
|
+
} else {
|
|
5388
|
+
reject(new Error(`npm view exited with code ${code}`));
|
|
5389
|
+
}
|
|
5390
|
+
});
|
|
5391
|
+
child.on("error", reject);
|
|
5392
|
+
setTimeout(() => {
|
|
5393
|
+
child.kill();
|
|
5394
|
+
reject(new Error("npm view timed out"));
|
|
5395
|
+
}, 1e4);
|
|
5396
|
+
});
|
|
5397
|
+
const isUpdateAvailable = current !== latest;
|
|
5398
|
+
res.json({ current, latest, isUpdateAvailable });
|
|
5399
|
+
} catch {
|
|
5400
|
+
res.json({ current, latest: current, isUpdateAvailable: false });
|
|
5401
|
+
}
|
|
5402
|
+
});
|
|
5403
|
+
router.post("/", async (req, res) => {
|
|
5404
|
+
if (options.requireAuth) {
|
|
5405
|
+
const authorized = await options.requireAuth(req);
|
|
5406
|
+
if (!authorized) {
|
|
5407
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
5408
|
+
return;
|
|
5409
|
+
}
|
|
5410
|
+
}
|
|
5411
|
+
if (updateInProgress) {
|
|
5412
|
+
res.status(409).json({ error: "Update already in progress" });
|
|
5413
|
+
return;
|
|
5414
|
+
}
|
|
5415
|
+
try {
|
|
5416
|
+
let stderr = "";
|
|
5417
|
+
const child = spawn4("bash", ["-c", "openfox update"], {
|
|
5418
|
+
detached: true,
|
|
5419
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
5420
|
+
});
|
|
5421
|
+
if (child.stderr) {
|
|
5422
|
+
child.stderr.on("data", (data) => {
|
|
5423
|
+
stderr += data.toString();
|
|
5424
|
+
});
|
|
5425
|
+
}
|
|
5426
|
+
child.unref();
|
|
5427
|
+
updateInProgress = true;
|
|
5428
|
+
child.on("close", () => {
|
|
5429
|
+
updateInProgress = false;
|
|
5430
|
+
});
|
|
5431
|
+
setTimeout(() => {
|
|
5432
|
+
if (stderr) {
|
|
5433
|
+
console.error("[auto-update] subprocess error:", stderr);
|
|
5434
|
+
}
|
|
5435
|
+
updateInProgress = false;
|
|
5436
|
+
}, 3e4);
|
|
5437
|
+
res.json({ success: true });
|
|
5438
|
+
} catch (err) {
|
|
5439
|
+
updateInProgress = false;
|
|
5440
|
+
res.status(500).json({ error: err instanceof Error ? err.message : "Update failed to start" });
|
|
5441
|
+
}
|
|
5442
|
+
});
|
|
5443
|
+
return router;
|
|
5444
|
+
}
|
|
5431
5445
|
|
|
5432
5446
|
// src/server/index.ts
|
|
5433
5447
|
var __dirname2 = dirname5(fileURLToPath4(import.meta.url));
|
|
5434
|
-
async function createServerHandle(
|
|
5435
|
-
setRuntimeConfig(
|
|
5436
|
-
setLogLevel(
|
|
5448
|
+
async function createServerHandle(config4) {
|
|
5449
|
+
setRuntimeConfig(config4);
|
|
5450
|
+
setLogLevel(config4.logging?.level ?? void 0, config4.mode);
|
|
5437
5451
|
await loadServerAuthConfig();
|
|
5438
|
-
const db = initDatabase(
|
|
5452
|
+
const db = initDatabase(config4);
|
|
5439
5453
|
initEventStore(db);
|
|
5440
|
-
const configDir = getGlobalConfigDir(
|
|
5441
|
-
const providerManager = createProviderManager(
|
|
5454
|
+
const configDir = getGlobalConfigDir(config4.mode ?? "production");
|
|
5455
|
+
const providerManager = createProviderManager(config4);
|
|
5442
5456
|
const sessionManager = new SessionManager(providerManager);
|
|
5443
5457
|
devServerManager.setSessionManager(sessionManager);
|
|
5444
5458
|
const useMock = process.env["OPENFOX_MOCK_LLM"] === "true";
|
|
@@ -5451,20 +5465,20 @@ async function createServerHandle(config) {
|
|
|
5451
5465
|
const llmClient = getLLMClient();
|
|
5452
5466
|
let backend;
|
|
5453
5467
|
const useMock2 = process.env["OPENFOX_MOCK_LLM"] === "true";
|
|
5454
|
-
if (
|
|
5455
|
-
backend = await detectBackend(
|
|
5468
|
+
if (config4.llm.backend === "auto") {
|
|
5469
|
+
backend = await detectBackend(config4.llm.baseUrl, void 0, useMock2);
|
|
5456
5470
|
llmClient.setBackend(backend);
|
|
5457
5471
|
if (!useMock2) {
|
|
5458
5472
|
logger.info("Auto-detected LLM backend", { backend: getBackendDisplayName(backend) });
|
|
5459
5473
|
}
|
|
5460
5474
|
} else {
|
|
5461
|
-
backend =
|
|
5475
|
+
backend = config4.llm.backend;
|
|
5462
5476
|
llmClient.setBackend(backend);
|
|
5463
5477
|
if (!useMock2) {
|
|
5464
5478
|
logger.info("Using configured LLM backend", { backend: getBackendDisplayName(backend) });
|
|
5465
5479
|
}
|
|
5466
5480
|
}
|
|
5467
|
-
const detected = await detectModel(
|
|
5481
|
+
const detected = await detectModel(config4.llm.baseUrl);
|
|
5468
5482
|
if (detected) {
|
|
5469
5483
|
llmClient.setModel(detected);
|
|
5470
5484
|
if (!useMock2) {
|
|
@@ -5472,7 +5486,7 @@ async function createServerHandle(config) {
|
|
|
5472
5486
|
}
|
|
5473
5487
|
} else {
|
|
5474
5488
|
if (!useMock2) {
|
|
5475
|
-
logger.warn("Could not auto-detect model, using config", { model:
|
|
5489
|
+
logger.warn("Could not auto-detect model, using config", { model: config4.llm.model });
|
|
5476
5490
|
}
|
|
5477
5491
|
}
|
|
5478
5492
|
const activeProvider = providerManager.getActiveProvider();
|
|
@@ -5494,7 +5508,7 @@ async function createServerHandle(config) {
|
|
|
5494
5508
|
app.use(express.json({ limit: "10mb" }));
|
|
5495
5509
|
const authMiddleware = async (req, res, next) => {
|
|
5496
5510
|
const path = req.path;
|
|
5497
|
-
const publicPaths = ["/health", "/auth", "/auth/login"];
|
|
5511
|
+
const publicPaths = ["/health", "/auth", "/auth/login", "/auto-update/check"];
|
|
5498
5512
|
if (publicPaths.includes(path)) {
|
|
5499
5513
|
return next();
|
|
5500
5514
|
}
|
|
@@ -5642,7 +5656,7 @@ async function createServerHandle(config) {
|
|
|
5642
5656
|
res.json({ project });
|
|
5643
5657
|
});
|
|
5644
5658
|
app.get("/api/sessions", async (req, res) => {
|
|
5645
|
-
const { getRecentUserPromptsForSession } = await import("./events-
|
|
5659
|
+
const { getRecentUserPromptsForSession } = await import("./events-K6AYMXFT.js");
|
|
5646
5660
|
const projectId = req.query["projectId"];
|
|
5647
5661
|
const limit = Math.min(parseInt(req.query["limit"]) || 20, 100);
|
|
5648
5662
|
const offset = parseInt(req.query["offset"]) || 0;
|
|
@@ -5670,12 +5684,12 @@ async function createServerHandle(config) {
|
|
|
5670
5684
|
if (!project) {
|
|
5671
5685
|
return res.status(404).json({ error: "Project not found" });
|
|
5672
5686
|
}
|
|
5673
|
-
const { providerId, model } = parseDefaultModelSelection(
|
|
5687
|
+
const { providerId, model } = parseDefaultModelSelection(config4.defaultModelSelection);
|
|
5674
5688
|
const session = sessionManager.createSession(projectId, title, providerId ?? null, model ?? null);
|
|
5675
5689
|
res.status(201).json({ session });
|
|
5676
5690
|
});
|
|
5677
5691
|
app.get("/api/sessions/:id", async (req, res) => {
|
|
5678
|
-
const { getEventStore: getEventStore2 } = await import("./events-
|
|
5692
|
+
const { getEventStore: getEventStore2 } = await import("./events-K6AYMXFT.js");
|
|
5679
5693
|
const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-4VHGQE6Y.js");
|
|
5680
5694
|
const session = sessionManager.getSession(req.params.id);
|
|
5681
5695
|
if (!session) {
|
|
@@ -5706,7 +5720,7 @@ async function createServerHandle(config) {
|
|
|
5706
5720
|
res.json({ success: true });
|
|
5707
5721
|
});
|
|
5708
5722
|
app.post("/api/sessions/:id/provider", async (req, res) => {
|
|
5709
|
-
const { getEventStore: getEventStore2 } = await import("./events-
|
|
5723
|
+
const { getEventStore: getEventStore2 } = await import("./events-K6AYMXFT.js");
|
|
5710
5724
|
const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-4VHGQE6Y.js");
|
|
5711
5725
|
const sessionId = req.params.id;
|
|
5712
5726
|
const session = sessionManager.getSession(sessionId);
|
|
@@ -5718,11 +5732,11 @@ async function createServerHandle(config) {
|
|
|
5718
5732
|
return res.status(400).json({ error: "providerId is required" });
|
|
5719
5733
|
}
|
|
5720
5734
|
sessionManager.setSessionProvider(sessionId, providerId, model ?? "auto");
|
|
5721
|
-
const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-
|
|
5722
|
-
const globalConfig = await loadGlobalConfig(
|
|
5735
|
+
const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-7XJQNOKX.js");
|
|
5736
|
+
const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
|
|
5723
5737
|
const updatedConfig = setDefaultModelSelection(globalConfig, providerId, model ?? "auto");
|
|
5724
|
-
await saveGlobalConfig(
|
|
5725
|
-
|
|
5738
|
+
await saveGlobalConfig(config4.mode ?? "production", updatedConfig);
|
|
5739
|
+
config4.defaultModelSelection = updatedConfig.defaultModelSelection;
|
|
5726
5740
|
const contextState = sessionManager.getContextState(sessionId);
|
|
5727
5741
|
const eventStore = getEventStore2();
|
|
5728
5742
|
const events = eventStore.getEvents(sessionId);
|
|
@@ -5744,7 +5758,7 @@ async function createServerHandle(config) {
|
|
|
5744
5758
|
res.json({ success: true });
|
|
5745
5759
|
});
|
|
5746
5760
|
app.put("/api/sessions/:id/mode", async (req, res) => {
|
|
5747
|
-
const { getEventStore: getEventStore2 } = await import("./events-
|
|
5761
|
+
const { getEventStore: getEventStore2 } = await import("./events-K6AYMXFT.js");
|
|
5748
5762
|
const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2 } = await import("./folding-4VHGQE6Y.js");
|
|
5749
5763
|
const sessionId = req.params.id;
|
|
5750
5764
|
const session = sessionManager.getSession(sessionId);
|
|
@@ -5752,12 +5766,16 @@ async function createServerHandle(config) {
|
|
|
5752
5766
|
return res.status(404).json({ error: "Session not found" });
|
|
5753
5767
|
}
|
|
5754
5768
|
const { mode } = req.body;
|
|
5755
|
-
if (!mode
|
|
5756
|
-
return res.status(400).json({ error:
|
|
5769
|
+
if (!mode) {
|
|
5770
|
+
return res.status(400).json({ error: "mode is required" });
|
|
5771
|
+
}
|
|
5772
|
+
const allAgents = await loadAllAgentsDefault();
|
|
5773
|
+
const topLevelIds = getTopLevelAgents(allAgents).map((a) => a.metadata.id);
|
|
5774
|
+
if (!topLevelIds.includes(mode)) {
|
|
5775
|
+
return res.status(400).json({ error: `Invalid mode. Must be one of: ${topLevelIds.join(", ")}` });
|
|
5757
5776
|
}
|
|
5758
5777
|
sessionManager.setMode(sessionId, mode);
|
|
5759
5778
|
const eventStore = getEventStore2();
|
|
5760
|
-
eventStore.append(sessionId, { type: "mode.changed", data: { mode, auto: false } });
|
|
5761
5779
|
const events = eventStore.getEvents(sessionId);
|
|
5762
5780
|
const messages = buildMessagesFromStoredEvents2(events);
|
|
5763
5781
|
const updatedSession = sessionManager.getSession(sessionId);
|
|
@@ -5797,12 +5815,12 @@ async function createServerHandle(config) {
|
|
|
5797
5815
|
if (!callId || approved === void 0) {
|
|
5798
5816
|
return res.status(400).json({ error: "callId and approved are required" });
|
|
5799
5817
|
}
|
|
5800
|
-
const { providePathConfirmation } = await import("./tools-
|
|
5818
|
+
const { providePathConfirmation } = await import("./tools-NFFQWH6M.js");
|
|
5801
5819
|
const result = providePathConfirmation(callId, approved, alwaysAllow);
|
|
5802
5820
|
if (!result.found) {
|
|
5803
5821
|
return res.status(404).json({ error: "No pending path confirmation with that ID" });
|
|
5804
5822
|
}
|
|
5805
|
-
const { getEventStore: getEventStore2 } = await import("./events-
|
|
5823
|
+
const { getEventStore: getEventStore2 } = await import("./events-K6AYMXFT.js");
|
|
5806
5824
|
const { buildMessagesFromStoredEvents: buildMessagesFromStoredEvents2, foldPendingConfirmations: foldPendingConfirmations2 } = await import("./folding-4VHGQE6Y.js");
|
|
5807
5825
|
const { createSessionStateMessage: createSessionStateMessage2 } = await import("./protocol-QDSVJTRN.js");
|
|
5808
5826
|
const eventStore = getEventStore2();
|
|
@@ -5821,7 +5839,7 @@ async function createServerHandle(config) {
|
|
|
5821
5839
|
if (!callId || !answer) {
|
|
5822
5840
|
return res.status(400).json({ error: "callId and answer are required" });
|
|
5823
5841
|
}
|
|
5824
|
-
const { provideAnswer: provideAnswer2 } = await import("./tools-
|
|
5842
|
+
const { provideAnswer: provideAnswer2 } = await import("./tools-NFFQWH6M.js");
|
|
5825
5843
|
const found = provideAnswer2(callId, answer);
|
|
5826
5844
|
if (!found) {
|
|
5827
5845
|
return res.status(404).json({ error: "No pending question with that ID" });
|
|
@@ -5857,14 +5875,14 @@ async function createServerHandle(config) {
|
|
|
5857
5875
|
if (!session) {
|
|
5858
5876
|
return res.status(404).json({ error: "Session not found" });
|
|
5859
5877
|
}
|
|
5860
|
-
const { stopSessionExecution } = await import("./chat-handler-
|
|
5861
|
-
const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-
|
|
5878
|
+
const { stopSessionExecution } = await import("./chat-handler-UPAEF6HR.js");
|
|
5879
|
+
const { cancelQuestionsForSession, cancelPathConfirmationsForSession } = await import("./tools-NFFQWH6M.js");
|
|
5862
5880
|
stopSessionExecution(sessionId, sessionManager);
|
|
5863
5881
|
abortSession(sessionId);
|
|
5864
5882
|
cancelQuestionsForSession(sessionId, "Session stopped by user");
|
|
5865
5883
|
cancelPathConfirmationsForSession(sessionId, "Session stopped by user");
|
|
5866
5884
|
sessionManager.clearMessageQueue(sessionId);
|
|
5867
|
-
const eventStore = (await import("./events-
|
|
5885
|
+
const eventStore = (await import("./events-K6AYMXFT.js")).getEventStore();
|
|
5868
5886
|
eventStore.append(sessionId, { type: "running.changed", data: { isRunning: false } });
|
|
5869
5887
|
res.json({ success: true });
|
|
5870
5888
|
});
|
|
@@ -5878,7 +5896,7 @@ async function createServerHandle(config) {
|
|
|
5878
5896
|
if (typeof messageIndex !== "number" || messageIndex < 0) {
|
|
5879
5897
|
return res.status(400).json({ error: "messageIndex must be a non-negative number" });
|
|
5880
5898
|
}
|
|
5881
|
-
const { truncateSessionMessages } = await import("./events-
|
|
5899
|
+
const { truncateSessionMessages } = await import("./events-K6AYMXFT.js");
|
|
5882
5900
|
truncateSessionMessages(sessionId, messageIndex);
|
|
5883
5901
|
res.json({ success: true });
|
|
5884
5902
|
});
|
|
@@ -5909,13 +5927,13 @@ async function createServerHandle(config) {
|
|
|
5909
5927
|
res.json({ accepted: true });
|
|
5910
5928
|
});
|
|
5911
5929
|
app.get("/api/settings/:key", async (req, res) => {
|
|
5912
|
-
const { getSetting, SETTINGS_DEFAULTS } = await import("./settings-
|
|
5930
|
+
const { getSetting, SETTINGS_DEFAULTS } = await import("./settings-AYSWDZUI.js");
|
|
5913
5931
|
const key = req.params.key;
|
|
5914
5932
|
const value = getSetting(key) ?? SETTINGS_DEFAULTS[key] ?? null;
|
|
5915
5933
|
res.json({ key, value });
|
|
5916
5934
|
});
|
|
5917
5935
|
app.put("/api/settings/:key", async (req, res) => {
|
|
5918
|
-
const { setSetting } = await import("./settings-
|
|
5936
|
+
const { setSetting } = await import("./settings-AYSWDZUI.js");
|
|
5919
5937
|
const key = req.params.key;
|
|
5920
5938
|
const { value } = req.body;
|
|
5921
5939
|
if (value === void 0) {
|
|
@@ -5930,8 +5948,8 @@ async function createServerHandle(config) {
|
|
|
5930
5948
|
let visionFallback;
|
|
5931
5949
|
let globalWorkdir;
|
|
5932
5950
|
try {
|
|
5933
|
-
const { loadGlobalConfig, getVisionFallback } = await import("./config-
|
|
5934
|
-
const globalConfig = await loadGlobalConfig(
|
|
5951
|
+
const { loadGlobalConfig, getVisionFallback } = await import("./config-7XJQNOKX.js");
|
|
5952
|
+
const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
|
|
5935
5953
|
const fallback = getVisionFallback(globalConfig);
|
|
5936
5954
|
if (fallback) {
|
|
5937
5955
|
visionFallback = {
|
|
@@ -5948,13 +5966,13 @@ async function createServerHandle(config) {
|
|
|
5948
5966
|
version: VERSION,
|
|
5949
5967
|
model: llmClient.getModel(),
|
|
5950
5968
|
maxContext: providerManager.getCurrentModelContext(),
|
|
5951
|
-
llmUrl: activeProvider?.url ??
|
|
5969
|
+
llmUrl: activeProvider?.url ?? config4.llm.baseUrl,
|
|
5952
5970
|
llmStatus: getLlmStatus(),
|
|
5953
5971
|
backend: llmClient.getBackend(),
|
|
5954
|
-
workdir: globalWorkdir ??
|
|
5972
|
+
workdir: globalWorkdir ?? config4.workdir,
|
|
5955
5973
|
providers: providerManager.getProviders(),
|
|
5956
5974
|
activeProviderId: providerManager.getActiveProviderId(),
|
|
5957
|
-
defaultModelSelection:
|
|
5975
|
+
defaultModelSelection: config4.defaultModelSelection,
|
|
5958
5976
|
visionFallback
|
|
5959
5977
|
});
|
|
5960
5978
|
});
|
|
@@ -5963,7 +5981,7 @@ async function createServerHandle(config) {
|
|
|
5963
5981
|
const currentModel = providerManager.getCurrentModel();
|
|
5964
5982
|
if (currentModel === "auto") {
|
|
5965
5983
|
const activeProvider = providerManager.getActiveProvider();
|
|
5966
|
-
const baseUrl = activeProvider?.url ??
|
|
5984
|
+
const baseUrl = activeProvider?.url ?? config4.llm.baseUrl;
|
|
5967
5985
|
const detected = await detectModel(baseUrl);
|
|
5968
5986
|
if (detected) {
|
|
5969
5987
|
llmClient.setModel(detected);
|
|
@@ -6009,8 +6027,8 @@ async function createServerHandle(config) {
|
|
|
6009
6027
|
return res.status(400).json({ error: "name, url, and backend are required" });
|
|
6010
6028
|
}
|
|
6011
6029
|
try {
|
|
6012
|
-
const { loadGlobalConfig, saveGlobalConfig, addProvider, setDefaultModelSelection } = await import("./config-
|
|
6013
|
-
const globalConfig = await loadGlobalConfig(
|
|
6030
|
+
const { loadGlobalConfig, saveGlobalConfig, addProvider, setDefaultModelSelection } = await import("./config-7XJQNOKX.js");
|
|
6031
|
+
const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
|
|
6014
6032
|
const providerBackend = backend;
|
|
6015
6033
|
const configWithProvider = addProvider(globalConfig, {
|
|
6016
6034
|
name,
|
|
@@ -6025,7 +6043,7 @@ async function createServerHandle(config) {
|
|
|
6025
6043
|
configWithProvider.providers[configWithProvider.providers.length - 1].id,
|
|
6026
6044
|
model ?? "auto"
|
|
6027
6045
|
);
|
|
6028
|
-
await saveGlobalConfig(
|
|
6046
|
+
await saveGlobalConfig(config4.mode ?? "production", finalConfig);
|
|
6029
6047
|
providerManager.setProviders(finalConfig.providers, finalConfig.defaultModelSelection ?? void 0);
|
|
6030
6048
|
const newProvider = finalConfig.providers[finalConfig.providers.length - 1];
|
|
6031
6049
|
res.status(201).json({
|
|
@@ -6042,14 +6060,14 @@ async function createServerHandle(config) {
|
|
|
6042
6060
|
app.post("/api/init/config", async (req, res) => {
|
|
6043
6061
|
const { workdir, visionFallback } = req.body;
|
|
6044
6062
|
try {
|
|
6045
|
-
const { loadGlobalConfig, saveGlobalConfig } = await import("./config-
|
|
6046
|
-
const globalConfig = await loadGlobalConfig(
|
|
6063
|
+
const { loadGlobalConfig, saveGlobalConfig } = await import("./config-7XJQNOKX.js");
|
|
6064
|
+
const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
|
|
6047
6065
|
const updatedConfig = {
|
|
6048
6066
|
...globalConfig,
|
|
6049
6067
|
workspace: workdir ? { workdir } : globalConfig.workspace,
|
|
6050
6068
|
visionFallback: visionFallback ?? globalConfig.visionFallback
|
|
6051
6069
|
};
|
|
6052
|
-
await saveGlobalConfig(
|
|
6070
|
+
await saveGlobalConfig(config4.mode ?? "production", updatedConfig);
|
|
6053
6071
|
res.json({ success: true });
|
|
6054
6072
|
} catch (error) {
|
|
6055
6073
|
res.status(500).json({
|
|
@@ -6070,10 +6088,10 @@ async function createServerHandle(config) {
|
|
|
6070
6088
|
});
|
|
6071
6089
|
app.delete("/api/providers/:id", async (req, res) => {
|
|
6072
6090
|
const { id } = req.params;
|
|
6073
|
-
const { loadGlobalConfig, saveGlobalConfig, removeProvider } = await import("./config-
|
|
6074
|
-
const globalConfig = await loadGlobalConfig(
|
|
6091
|
+
const { loadGlobalConfig, saveGlobalConfig, removeProvider } = await import("./config-7XJQNOKX.js");
|
|
6092
|
+
const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
|
|
6075
6093
|
const updatedConfig = removeProvider(globalConfig, id);
|
|
6076
|
-
await saveGlobalConfig(
|
|
6094
|
+
await saveGlobalConfig(config4.mode ?? "production", updatedConfig);
|
|
6077
6095
|
providerManager.setProviders(updatedConfig.providers, updatedConfig.defaultModelSelection ?? void 0);
|
|
6078
6096
|
res.json({ success: true });
|
|
6079
6097
|
});
|
|
@@ -6090,10 +6108,10 @@ async function createServerHandle(config) {
|
|
|
6090
6108
|
return res.status(400).json({ error: result.error });
|
|
6091
6109
|
}
|
|
6092
6110
|
const llmClient = getLLMClient();
|
|
6093
|
-
const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-
|
|
6094
|
-
const globalConfig = await loadGlobalConfig(
|
|
6111
|
+
const { loadGlobalConfig, saveGlobalConfig, setDefaultModelSelection } = await import("./config-7XJQNOKX.js");
|
|
6112
|
+
const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
|
|
6095
6113
|
const updatedConfig = setDefaultModelSelection(globalConfig, id, llmClient.getModel());
|
|
6096
|
-
await saveGlobalConfig(
|
|
6114
|
+
await saveGlobalConfig(config4.mode ?? "production", updatedConfig);
|
|
6097
6115
|
res.json({
|
|
6098
6116
|
success: true,
|
|
6099
6117
|
activeProviderId: id,
|
|
@@ -6121,8 +6139,8 @@ async function createServerHandle(config) {
|
|
|
6121
6139
|
if (!result.success) {
|
|
6122
6140
|
return res.status(400).json({ error: result.error });
|
|
6123
6141
|
}
|
|
6124
|
-
const { loadGlobalConfig, saveGlobalConfig } = await import("./config-
|
|
6125
|
-
const globalConfig = await loadGlobalConfig(
|
|
6142
|
+
const { loadGlobalConfig, saveGlobalConfig } = await import("./config-7XJQNOKX.js");
|
|
6143
|
+
const globalConfig = await loadGlobalConfig(config4.mode ?? "production");
|
|
6126
6144
|
const updatedProviders = providerManager.getProviders();
|
|
6127
6145
|
const updatedConfig = {
|
|
6128
6146
|
...globalConfig,
|
|
@@ -6130,7 +6148,7 @@ async function createServerHandle(config) {
|
|
|
6130
6148
|
activeProviderId: providerManager.getActiveProviderId(),
|
|
6131
6149
|
defaultModelSelection: providerManager.getActiveProviderId() ? `${providerManager.getActiveProviderId()}/${providerManager.getCurrentModel()}` : void 0
|
|
6132
6150
|
};
|
|
6133
|
-
await saveGlobalConfig(
|
|
6151
|
+
await saveGlobalConfig(config4.mode ?? "production", updatedConfig);
|
|
6134
6152
|
let contextState = null;
|
|
6135
6153
|
const sessions = sessionManager.listSessions();
|
|
6136
6154
|
if (sessions.length > 0) {
|
|
@@ -6165,12 +6183,27 @@ async function createServerHandle(config) {
|
|
|
6165
6183
|
status: updatedProvider?.status ?? "unknown"
|
|
6166
6184
|
});
|
|
6167
6185
|
});
|
|
6168
|
-
|
|
6169
|
-
app.use("/api/
|
|
6170
|
-
app.use("/api/
|
|
6171
|
-
app.use("/api/
|
|
6186
|
+
const projectDir = config4.workdir;
|
|
6187
|
+
app.use("/api/skills", createSkillRoutes(configDir, projectDir));
|
|
6188
|
+
app.use("/api/commands", createCommandRoutes(configDir, projectDir));
|
|
6189
|
+
app.use("/api/agents", createAgentRoutes(configDir, projectDir));
|
|
6190
|
+
app.use("/api/workflows", createWorkflowRoutes(configDir, config4, projectDir));
|
|
6172
6191
|
app.use("/api/dev-server", createDevServerRoutes());
|
|
6173
6192
|
app.use("/api/terminals", createTerminalRoutes());
|
|
6193
|
+
app.use(
|
|
6194
|
+
"/api/auto-update",
|
|
6195
|
+
createAutoUpdateRoutes({
|
|
6196
|
+
requireAuth: async (req) => {
|
|
6197
|
+
const authConfig = getAuthConfig();
|
|
6198
|
+
if (authConfig?.strategy !== "network" || !authConfig?.encryptedPassword) {
|
|
6199
|
+
return true;
|
|
6200
|
+
}
|
|
6201
|
+
const token = req.headers["x-session-token"];
|
|
6202
|
+
if (!token) return false;
|
|
6203
|
+
return Boolean(await isValidToken(token));
|
|
6204
|
+
}
|
|
6205
|
+
})
|
|
6206
|
+
);
|
|
6174
6207
|
app.get("/api/sessions/:id/background-processes", async (req, res) => {
|
|
6175
6208
|
const { getSessionProcesses } = await import("./manager-W7N3XQ4Q.js");
|
|
6176
6209
|
const sessionId = req.params.id;
|
|
@@ -6204,7 +6237,7 @@ async function createServerHandle(config) {
|
|
|
6204
6237
|
const entries = await import("fs/promises").then((m) => m.readdir(resolvedPath, { withFileTypes: true }));
|
|
6205
6238
|
const directories = entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map((entry) => ({
|
|
6206
6239
|
name: entry.name,
|
|
6207
|
-
path:
|
|
6240
|
+
path: join6(resolvedPath, entry.name)
|
|
6208
6241
|
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
6209
6242
|
const parent = dirname5(resolvedPath);
|
|
6210
6243
|
const hasParent = parent !== resolvedPath;
|
|
@@ -6225,7 +6258,7 @@ async function createServerHandle(config) {
|
|
|
6225
6258
|
}
|
|
6226
6259
|
});
|
|
6227
6260
|
const webDir = resolve(__dirname2, "../../web");
|
|
6228
|
-
const isDev =
|
|
6261
|
+
const isDev = config4.mode === "development";
|
|
6229
6262
|
let viteServer;
|
|
6230
6263
|
if (isDev) {
|
|
6231
6264
|
logger.info("Dev mode: using Vite middleware");
|
|
@@ -6251,7 +6284,7 @@ async function createServerHandle(config) {
|
|
|
6251
6284
|
}
|
|
6252
6285
|
});
|
|
6253
6286
|
app.get("/fox.svg", (_req, res) => {
|
|
6254
|
-
readFile3(
|
|
6287
|
+
readFile3(join6(webDir, "fox.svg")).then((content) => {
|
|
6255
6288
|
res.set("Content-Type", "image/svg+xml");
|
|
6256
6289
|
res.send(content);
|
|
6257
6290
|
}).catch(() => {
|
|
@@ -6260,7 +6293,7 @@ async function createServerHandle(config) {
|
|
|
6260
6293
|
});
|
|
6261
6294
|
app.use(
|
|
6262
6295
|
"/sounds",
|
|
6263
|
-
express.static(
|
|
6296
|
+
express.static(join6(webDir, "public", "sounds"), {
|
|
6264
6297
|
setHeaders: (res) => {
|
|
6265
6298
|
res.set("Content-Type", "audio/mpeg");
|
|
6266
6299
|
}
|
|
@@ -6269,24 +6302,24 @@ async function createServerHandle(config) {
|
|
|
6269
6302
|
app.use("/__inspect__.js", (_req, res) => {
|
|
6270
6303
|
res.set("Access-Control-Allow-Origin", "*");
|
|
6271
6304
|
res.set("Content-Type", "application/javascript");
|
|
6272
|
-
readFile3(
|
|
6305
|
+
readFile3(join6(webDir, "public", "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
|
|
6273
6306
|
});
|
|
6274
6307
|
app.get("/*path", (req, res) => {
|
|
6275
6308
|
if (req.path.startsWith("/api/")) {
|
|
6276
6309
|
return;
|
|
6277
6310
|
}
|
|
6278
|
-
readFile3(
|
|
6311
|
+
readFile3(join6(webDir, "index.html"), "utf-8").then((indexHtml) => viteServer.transformIndexHtml(req.originalUrl, indexHtml)).then((transformed) => res.send(transformed)).catch((err) => {
|
|
6279
6312
|
logger.error("Error serving index.html", { error: err });
|
|
6280
6313
|
res.status(500).send("Server error");
|
|
6281
6314
|
});
|
|
6282
6315
|
});
|
|
6283
|
-
logger.info("Vite middleware ready", { port:
|
|
6316
|
+
logger.info("Vite middleware ready", { port: config4.server.port });
|
|
6284
6317
|
}
|
|
6285
6318
|
if (!isDev) {
|
|
6286
6319
|
const distWebDir = resolve(__dirname2, "web");
|
|
6287
6320
|
app.use(
|
|
6288
6321
|
"/assets",
|
|
6289
|
-
express.static(
|
|
6322
|
+
express.static(join6(distWebDir, "assets"), {
|
|
6290
6323
|
setHeaders: (res, filepath) => {
|
|
6291
6324
|
if (filepath.endsWith(".css")) {
|
|
6292
6325
|
res.set("Content-Type", "text/css");
|
|
@@ -6294,11 +6327,11 @@ async function createServerHandle(config) {
|
|
|
6294
6327
|
}
|
|
6295
6328
|
})
|
|
6296
6329
|
);
|
|
6297
|
-
app.use("/manifest.webmanifest", express.static(
|
|
6298
|
-
app.use("/registerSW.js", express.static(
|
|
6299
|
-
app.use("/sw.js", express.static(
|
|
6330
|
+
app.use("/manifest.webmanifest", express.static(join6(distWebDir, "manifest.webmanifest")));
|
|
6331
|
+
app.use("/registerSW.js", express.static(join6(distWebDir, "registerSW.js")));
|
|
6332
|
+
app.use("/sw.js", express.static(join6(distWebDir, "sw.js")));
|
|
6300
6333
|
app.get("/fox.svg", (_req, res) => {
|
|
6301
|
-
readFile3(
|
|
6334
|
+
readFile3(join6(distWebDir, "fox.svg")).then((content) => {
|
|
6302
6335
|
res.set("Content-Type", "image/svg+xml");
|
|
6303
6336
|
res.send(content);
|
|
6304
6337
|
}).catch(() => {
|
|
@@ -6307,7 +6340,7 @@ async function createServerHandle(config) {
|
|
|
6307
6340
|
});
|
|
6308
6341
|
app.use(
|
|
6309
6342
|
"/sounds",
|
|
6310
|
-
express.static(
|
|
6343
|
+
express.static(join6(distWebDir, "sounds"), {
|
|
6311
6344
|
setHeaders: (res) => {
|
|
6312
6345
|
res.set("Content-Type", "audio/mpeg");
|
|
6313
6346
|
}
|
|
@@ -6316,15 +6349,15 @@ async function createServerHandle(config) {
|
|
|
6316
6349
|
app.use("/__inspect__.js", (_req, res) => {
|
|
6317
6350
|
res.set("Access-Control-Allow-Origin", "*");
|
|
6318
6351
|
res.set("Content-Type", "application/javascript");
|
|
6319
|
-
readFile3(
|
|
6352
|
+
readFile3(join6(distWebDir, "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
|
|
6320
6353
|
});
|
|
6321
6354
|
app.use("/__inspect__.js", (_req, res) => {
|
|
6322
6355
|
res.set("Access-Control-Allow-Origin", "*");
|
|
6323
6356
|
res.set("Content-Type", "application/javascript");
|
|
6324
|
-
readFile3(
|
|
6357
|
+
readFile3(join6(distWebDir, "__inspect__.js")).then((content) => res.send(content)).catch(() => res.status(404).send("Not found"));
|
|
6325
6358
|
});
|
|
6326
6359
|
app.get("/", (_req, res) => {
|
|
6327
|
-
readFile3(
|
|
6360
|
+
readFile3(join6(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
|
|
6328
6361
|
res.status(404).send("Web UI not built. Run `npm run build:web`");
|
|
6329
6362
|
});
|
|
6330
6363
|
});
|
|
@@ -6332,7 +6365,7 @@ async function createServerHandle(config) {
|
|
|
6332
6365
|
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") {
|
|
6333
6366
|
return;
|
|
6334
6367
|
}
|
|
6335
|
-
readFile3(
|
|
6368
|
+
readFile3(join6(distWebDir, "index.html"), "utf-8").then((content) => res.send(content)).catch(() => {
|
|
6336
6369
|
res.status(404).send("Web UI not built");
|
|
6337
6370
|
});
|
|
6338
6371
|
});
|
|
@@ -6340,14 +6373,14 @@ async function createServerHandle(config) {
|
|
|
6340
6373
|
const httpServer = createHttpServer(app);
|
|
6341
6374
|
const wssExports = createWebSocketServer(
|
|
6342
6375
|
httpServer,
|
|
6343
|
-
|
|
6376
|
+
config4,
|
|
6344
6377
|
getLLMClient,
|
|
6345
6378
|
() => providerManager.getActiveProvider(),
|
|
6346
6379
|
sessionManager,
|
|
6347
6380
|
providerManager
|
|
6348
6381
|
);
|
|
6349
6382
|
const wss = wssExports.wss;
|
|
6350
|
-
const { QueueProcessor } = await import("./processor-
|
|
6383
|
+
const { QueueProcessor } = await import("./processor-D4XQ5QMB.js");
|
|
6351
6384
|
const queueProcessor = new QueueProcessor({
|
|
6352
6385
|
sessionManager,
|
|
6353
6386
|
providerManager,
|
|
@@ -6366,17 +6399,17 @@ async function createServerHandle(config) {
|
|
|
6366
6399
|
};
|
|
6367
6400
|
return {
|
|
6368
6401
|
httpServer,
|
|
6369
|
-
ctx: { config, sessionManager, llmClient: getLLMClient(), toolRegistry, providerManager },
|
|
6402
|
+
ctx: { config: config4, sessionManager, llmClient: getLLMClient(), toolRegistry, providerManager },
|
|
6370
6403
|
start: (port) => new Promise((resolve2, reject) => {
|
|
6371
|
-
const listenPort = port ??
|
|
6372
|
-
const host =
|
|
6404
|
+
const listenPort = port ?? config4.server.port;
|
|
6405
|
+
const host = config4.server.host;
|
|
6373
6406
|
httpServer.listen(listenPort, host, () => {
|
|
6374
6407
|
const addr = httpServer.address();
|
|
6375
6408
|
const actualPort = typeof addr === "object" && addr ? addr.port : listenPort;
|
|
6376
6409
|
const client = getLLMClient();
|
|
6377
6410
|
logger.info(`OpenFox server running at http://${host}:${actualPort}`);
|
|
6378
6411
|
logger.info(`WebSocket available at ws://${host}:${actualPort}/ws`);
|
|
6379
|
-
logger.info(`LLM backend: ${client.getBackend()}, model: ${client.getModel()}, url: ${
|
|
6412
|
+
logger.info(`LLM backend: ${client.getBackend()}, model: ${client.getModel()}, url: ${config4.llm.baseUrl}`);
|
|
6380
6413
|
resolve2({ port: actualPort });
|
|
6381
6414
|
});
|
|
6382
6415
|
httpServer.on("error", reject);
|
|
@@ -6399,8 +6432,8 @@ async function createServerHandle(config) {
|
|
|
6399
6432
|
})
|
|
6400
6433
|
};
|
|
6401
6434
|
}
|
|
6402
|
-
async function createServer(
|
|
6403
|
-
const handle = await createServerHandle(
|
|
6435
|
+
async function createServer(config4) {
|
|
6436
|
+
const handle = await createServerHandle(config4);
|
|
6404
6437
|
await handle.start();
|
|
6405
6438
|
const shutdown = () => {
|
|
6406
6439
|
const forceExitTimer = setTimeout(() => {
|
|
@@ -6422,4 +6455,4 @@ export {
|
|
|
6422
6455
|
createServerHandle,
|
|
6423
6456
|
createServer
|
|
6424
6457
|
};
|
|
6425
|
-
//# sourceMappingURL=chunk-
|
|
6458
|
+
//# sourceMappingURL=chunk-2BS6LMIU.js.map
|