openfox 1.6.15 → 1.6.17
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-JZIM73ZY.js → auto-compaction-VOWM5ZHF.js} +2 -2
- package/dist/{chat-handler-F2A2IMQB.js → chat-handler-7HWNXQ4G.js} +4 -4
- package/dist/{chunk-JFKYCGZ5.js → chunk-EAQNNNUR.js} +2 -2
- package/dist/{chunk-3WHZ47PY.js → chunk-R7U3CD2U.js} +147 -230
- package/dist/{chunk-YM6VHAPM.js → chunk-RPPEIB3F.js} +2 -2
- package/dist/{chunk-G4E72ST3.js → chunk-UJANEDP5.js} +311 -262
- package/dist/cli/dev.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/{orchestrator-SRSG2SIZ.js → orchestrator-DJZZPPE7.js} +3 -3
- package/dist/package.json +2 -2
- package/dist/{processor-H5BQ5HQM.js → processor-PVYCX5GK.js} +2 -2
- package/dist/{serve-5AY7GMN7.js → serve-FEG4BUYZ.js} +4 -4
- package/dist/server/index.js +3 -3
- package/dist/{tools-VOWNOP6V.js → tools-YRDPOS6P.js} +2 -2
- package/dist/web/assets/index-CZBXRYpK.js +150 -0
- package/dist/web/assets/{index-CNeIjdxm.css → index-D4V7Gtvt.css} +1 -1
- package/dist/web/index.html +2 -2
- package/dist/web/sw.js +1 -1
- package/package.json +2 -2
- package/dist/web/assets/index-mBLhctLW.js +0 -150
- /package/dist/{server/commands/defaults → command-defaults}/commit-push.command.md +0 -0
- /package/dist/{server/commands/defaults → command-defaults}/init.command.md +0 -0
- /package/dist/{server/commands/defaults → command-defaults}/test-ui.command.md +0 -0
- /package/dist/{server/skills/defaults → skill-defaults}/browser.skill.md +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
createVerifierNudgeConfig,
|
|
7
7
|
runBuilderTurn,
|
|
8
8
|
runChatTurn
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-RPPEIB3F.js";
|
|
10
10
|
import {
|
|
11
11
|
TurnMetrics,
|
|
12
12
|
agentExists,
|
|
@@ -17,46 +17,37 @@ import {
|
|
|
17
17
|
createMessageStartEvent,
|
|
18
18
|
createToolRegistry,
|
|
19
19
|
deleteAgent,
|
|
20
|
-
deleteItem,
|
|
21
20
|
deleteSkill,
|
|
22
21
|
devServerManager,
|
|
23
|
-
dirExists,
|
|
24
|
-
ensureDefaultAgents,
|
|
25
|
-
ensureDefaultSkills,
|
|
26
|
-
ensureDir,
|
|
27
22
|
executeSubAgent,
|
|
28
23
|
findAgentById,
|
|
29
|
-
findById,
|
|
30
|
-
findModifiedDefaultFiles,
|
|
31
24
|
findSkillById,
|
|
32
25
|
getAllInstructions,
|
|
33
|
-
|
|
26
|
+
getDefaultAgentContent,
|
|
34
27
|
getDefaultAgentIds,
|
|
35
28
|
getDefaultIds,
|
|
29
|
+
getDefaultSkillContent,
|
|
36
30
|
getDefaultSkillIds,
|
|
37
31
|
getEnabledSkillMetadata,
|
|
38
|
-
getModifiedDefaultAgentIds,
|
|
39
|
-
getModifiedDefaultSkillIds,
|
|
40
32
|
getToolRegistryForAgent,
|
|
41
33
|
isSkillEnabled,
|
|
42
34
|
loadAllAgents,
|
|
43
35
|
loadAllAgentsDefault,
|
|
44
36
|
loadAllSkills,
|
|
45
|
-
|
|
37
|
+
loadDefaultAgents,
|
|
38
|
+
loadDefaultSkills,
|
|
39
|
+
loadItemsFromDir,
|
|
40
|
+
loadUserAgents,
|
|
41
|
+
loadUserSkills,
|
|
46
42
|
maybeAutoCompactContext,
|
|
43
|
+
pathExists,
|
|
47
44
|
performManualContextCompaction,
|
|
48
|
-
restoreAllDefaultAgents,
|
|
49
|
-
restoreAllDefaultSkills,
|
|
50
|
-
restoreDefault,
|
|
51
|
-
restoreDefaultAgent,
|
|
52
|
-
restoreDefaultSkill,
|
|
53
45
|
saveAgent,
|
|
54
|
-
saveItem,
|
|
55
46
|
saveSkill,
|
|
56
47
|
setSkillEnabled,
|
|
57
48
|
skillExists,
|
|
58
49
|
spawnShellProcess
|
|
59
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-R7U3CD2U.js";
|
|
60
51
|
import {
|
|
61
52
|
getPathSeparator,
|
|
62
53
|
getPlatformShell,
|
|
@@ -156,8 +147,8 @@ import {
|
|
|
156
147
|
import express from "express";
|
|
157
148
|
import cors from "cors";
|
|
158
149
|
import { createServer as createHttpServer } from "http";
|
|
159
|
-
import { fileURLToPath as
|
|
160
|
-
import { dirname as
|
|
150
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
151
|
+
import { dirname as dirname5, resolve, join as join5 } from "path";
|
|
161
152
|
import { readFile as readFile3 } from "fs/promises";
|
|
162
153
|
import { createServer as createViteServer } from "vite";
|
|
163
154
|
|
|
@@ -1426,7 +1417,7 @@ function unsubscribeAllFromTerminal(ws) {
|
|
|
1426
1417
|
}
|
|
1427
1418
|
|
|
1428
1419
|
// src/server/workflows/registry.ts
|
|
1429
|
-
import { readdir, readFile, writeFile,
|
|
1420
|
+
import { readdir, readFile, writeFile, mkdir, access, unlink } from "fs/promises";
|
|
1430
1421
|
import { join, dirname } from "path";
|
|
1431
1422
|
import { constants } from "fs";
|
|
1432
1423
|
import { fileURLToPath } from "url";
|
|
@@ -1437,7 +1428,7 @@ var WORKFLOW_EXTENSION = ".workflow.json";
|
|
|
1437
1428
|
function getWorkflowsDir(configDir) {
|
|
1438
1429
|
return join(configDir, "workflows");
|
|
1439
1430
|
}
|
|
1440
|
-
async function
|
|
1431
|
+
async function pathExists2(path) {
|
|
1441
1432
|
try {
|
|
1442
1433
|
await access(path, constants.R_OK);
|
|
1443
1434
|
return true;
|
|
@@ -1445,49 +1436,20 @@ async function pathExists(path) {
|
|
|
1445
1436
|
return false;
|
|
1446
1437
|
}
|
|
1447
1438
|
}
|
|
1448
|
-
async function
|
|
1449
|
-
|
|
1450
|
-
if (!await pathExists(workflowsDir)) {
|
|
1451
|
-
await mkdir(workflowsDir, { recursive: true });
|
|
1452
|
-
}
|
|
1453
|
-
let defaultFiles;
|
|
1454
|
-
let sourceDir;
|
|
1455
|
-
try {
|
|
1456
|
-
defaultFiles = (await readdir(DEFAULTS_DIR)).filter((f) => f.endsWith(WORKFLOW_EXTENSION));
|
|
1457
|
-
sourceDir = DEFAULTS_DIR;
|
|
1458
|
-
} catch {
|
|
1459
|
-
try {
|
|
1460
|
-
defaultFiles = (await readdir(DEFAULTS_DIR_ALT)).filter((f) => f.endsWith(WORKFLOW_EXTENSION));
|
|
1461
|
-
sourceDir = DEFAULTS_DIR_ALT;
|
|
1462
|
-
} catch {
|
|
1463
|
-
logger.warn("No bundled workflow defaults found", { dir: DEFAULTS_DIR });
|
|
1464
|
-
return;
|
|
1465
|
-
}
|
|
1466
|
-
}
|
|
1467
|
-
for (const file of defaultFiles) {
|
|
1468
|
-
const targetPath = join(workflowsDir, file);
|
|
1469
|
-
try {
|
|
1470
|
-
await copyFile(join(sourceDir, file), targetPath);
|
|
1471
|
-
} catch (err) {
|
|
1472
|
-
logger.error("Failed to copy default workflow", { file, error: err instanceof Error ? err.message : String(err) });
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
async function loadAllWorkflows(configDir) {
|
|
1477
|
-
const workflowsDir = getWorkflowsDir(configDir);
|
|
1478
|
-
if (!await pathExists(workflowsDir)) {
|
|
1439
|
+
async function loadWorkflowsFromDir(dir) {
|
|
1440
|
+
if (!await pathExists2(dir)) {
|
|
1479
1441
|
return [];
|
|
1480
1442
|
}
|
|
1481
1443
|
let files;
|
|
1482
1444
|
try {
|
|
1483
|
-
files = (await readdir(
|
|
1445
|
+
files = (await readdir(dir)).filter((f) => f.endsWith(WORKFLOW_EXTENSION));
|
|
1484
1446
|
} catch {
|
|
1485
1447
|
return [];
|
|
1486
1448
|
}
|
|
1487
1449
|
const workflows = [];
|
|
1488
1450
|
for (const file of files) {
|
|
1489
1451
|
try {
|
|
1490
|
-
const raw = await readFile(join(
|
|
1452
|
+
const raw = await readFile(join(dir, file), "utf-8");
|
|
1491
1453
|
const parsed = JSON.parse(raw);
|
|
1492
1454
|
if (parsed.metadata?.id && parsed.steps?.length > 0) {
|
|
1493
1455
|
workflows.push(parsed);
|
|
@@ -1500,6 +1462,30 @@ async function loadAllWorkflows(configDir) {
|
|
|
1500
1462
|
}
|
|
1501
1463
|
return workflows;
|
|
1502
1464
|
}
|
|
1465
|
+
async function loadDefaultWorkflows() {
|
|
1466
|
+
let defaults = await loadWorkflowsFromDir(DEFAULTS_DIR);
|
|
1467
|
+
if (!defaults.length) {
|
|
1468
|
+
defaults = await loadWorkflowsFromDir(DEFAULTS_DIR_ALT);
|
|
1469
|
+
}
|
|
1470
|
+
return defaults;
|
|
1471
|
+
}
|
|
1472
|
+
async function loadUserWorkflows(configDir) {
|
|
1473
|
+
return loadWorkflowsFromDir(getWorkflowsDir(configDir));
|
|
1474
|
+
}
|
|
1475
|
+
async function loadAllWorkflows(configDir) {
|
|
1476
|
+
const [defaultWorkflows, userWorkflows] = await Promise.all([
|
|
1477
|
+
loadDefaultWorkflows(),
|
|
1478
|
+
loadUserWorkflows(configDir)
|
|
1479
|
+
]);
|
|
1480
|
+
const workflowMap = /* @__PURE__ */ new Map();
|
|
1481
|
+
for (const workflow of defaultWorkflows) {
|
|
1482
|
+
workflowMap.set(workflow.metadata.id, workflow);
|
|
1483
|
+
}
|
|
1484
|
+
for (const workflow of userWorkflows) {
|
|
1485
|
+
workflowMap.set(workflow.metadata.id, workflow);
|
|
1486
|
+
}
|
|
1487
|
+
return Array.from(workflowMap.values());
|
|
1488
|
+
}
|
|
1503
1489
|
async function getDefaultWorkflowIds() {
|
|
1504
1490
|
for (const dir of [DEFAULTS_DIR, DEFAULTS_DIR_ALT]) {
|
|
1505
1491
|
try {
|
|
@@ -1510,56 +1496,40 @@ async function getDefaultWorkflowIds() {
|
|
|
1510
1496
|
}
|
|
1511
1497
|
return [];
|
|
1512
1498
|
}
|
|
1513
|
-
async function
|
|
1514
|
-
const
|
|
1515
|
-
|
|
1516
|
-
const sourcePath = join(dir, filename);
|
|
1517
|
-
if (await pathExists(sourcePath)) {
|
|
1518
|
-
const targetPath = join(getWorkflowsDir(configDir), filename);
|
|
1519
|
-
await copyFile(sourcePath, targetPath);
|
|
1520
|
-
return true;
|
|
1521
|
-
}
|
|
1522
|
-
}
|
|
1523
|
-
return false;
|
|
1499
|
+
async function getDefaultWorkflowContent(workflowId) {
|
|
1500
|
+
const defaults = await loadDefaultWorkflows();
|
|
1501
|
+
return defaults.find((w) => w.metadata.id === workflowId) ?? null;
|
|
1524
1502
|
}
|
|
1525
|
-
async function
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
WORKFLOW_EXTENSION,
|
|
1529
|
-
[DEFAULTS_DIR, DEFAULTS_DIR_ALT],
|
|
1530
|
-
getWorkflowsDir(configDir)
|
|
1531
|
-
);
|
|
1532
|
-
}
|
|
1533
|
-
async function restoreAllDefaultWorkflows(configDir) {
|
|
1534
|
-
const ids = await getDefaultWorkflowIds();
|
|
1535
|
-
let count = 0;
|
|
1536
|
-
for (const id of ids) {
|
|
1537
|
-
if (await restoreDefaultWorkflow(configDir, id)) count++;
|
|
1538
|
-
}
|
|
1539
|
-
return count;
|
|
1503
|
+
async function isDefaultWorkflow(workflowId) {
|
|
1504
|
+
const defaultIds = await getDefaultWorkflowIds();
|
|
1505
|
+
return defaultIds.includes(workflowId);
|
|
1540
1506
|
}
|
|
1541
1507
|
function findWorkflowById(workflowId, workflows) {
|
|
1542
1508
|
return workflows.find((p) => p.metadata.id === workflowId);
|
|
1543
1509
|
}
|
|
1544
1510
|
async function workflowExists(configDir, workflowId) {
|
|
1545
1511
|
const filePath = join(getWorkflowsDir(configDir), `${workflowId}${WORKFLOW_EXTENSION}`);
|
|
1546
|
-
return
|
|
1512
|
+
return pathExists2(filePath);
|
|
1547
1513
|
}
|
|
1548
1514
|
async function saveWorkflow(configDir, workflow) {
|
|
1549
1515
|
const workflowsDir = getWorkflowsDir(configDir);
|
|
1550
|
-
if (!await
|
|
1516
|
+
if (!await pathExists2(workflowsDir)) {
|
|
1551
1517
|
await mkdir(workflowsDir, { recursive: true });
|
|
1552
1518
|
}
|
|
1553
1519
|
const filePath = join(workflowsDir, `${workflow.metadata.id}${WORKFLOW_EXTENSION}`);
|
|
1554
1520
|
await writeFile(filePath, JSON.stringify(workflow, null, 2) + "\n", "utf-8");
|
|
1555
1521
|
}
|
|
1556
1522
|
async function deleteWorkflow(configDir, workflowId) {
|
|
1523
|
+
const isDefault = await isDefaultWorkflow(workflowId);
|
|
1524
|
+
if (isDefault) {
|
|
1525
|
+
return { success: false, reason: "Cannot delete built-in defaults" };
|
|
1526
|
+
}
|
|
1557
1527
|
const filePath = join(getWorkflowsDir(configDir), `${workflowId}${WORKFLOW_EXTENSION}`);
|
|
1558
1528
|
try {
|
|
1559
1529
|
await unlink(filePath);
|
|
1560
|
-
return true;
|
|
1530
|
+
return { success: true };
|
|
1561
1531
|
} catch {
|
|
1562
|
-
return false;
|
|
1532
|
+
return { success: false };
|
|
1563
1533
|
}
|
|
1564
1534
|
}
|
|
1565
1535
|
|
|
@@ -4898,102 +4868,47 @@ ${summary}`,
|
|
|
4898
4868
|
}
|
|
4899
4869
|
};
|
|
4900
4870
|
|
|
4901
|
-
// src/server/
|
|
4902
|
-
import {
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
function getCommandsDir(configDir) {
|
|
4908
|
-
return join4(configDir, "commands");
|
|
4909
|
-
}
|
|
4910
|
-
async function ensureDefaultCommands(configDir) {
|
|
4911
|
-
const bundleDir = getBundleDir();
|
|
4912
|
-
const commandsDir = getCommandsDir(configDir);
|
|
4913
|
-
await ensureDir(commandsDir);
|
|
4914
|
-
const ids = await getDefaultIds(bundleDir, DEFAULTS_DIR2, COMMAND_EXTENSION);
|
|
4915
|
-
for (const id of ids) {
|
|
4916
|
-
if (!await restoreDefault(commandsDir, bundleDir, DEFAULTS_DIR2, id, COMMAND_EXTENSION)) {
|
|
4917
|
-
await restoreDefault(commandsDir, bundleDir, DEFAULTS_DIR_ALT2, id, COMMAND_EXTENSION);
|
|
4918
|
-
}
|
|
4919
|
-
}
|
|
4920
|
-
}
|
|
4921
|
-
async function loadAllCommands(configDir) {
|
|
4922
|
-
return loadItems(getCommandsDir(configDir), COMMAND_EXTENSION);
|
|
4923
|
-
}
|
|
4924
|
-
async function getDefaultCommandIds() {
|
|
4925
|
-
const bundleDir = getBundleDir();
|
|
4926
|
-
const ids = await getDefaultIds(bundleDir, DEFAULTS_DIR2, COMMAND_EXTENSION);
|
|
4927
|
-
if (ids.length) return ids;
|
|
4928
|
-
return getDefaultIds(bundleDir, DEFAULTS_DIR_ALT2, COMMAND_EXTENSION);
|
|
4929
|
-
}
|
|
4930
|
-
async function restoreDefaultCommand(configDir, commandId) {
|
|
4931
|
-
const bundleDir = getBundleDir();
|
|
4932
|
-
const commandsDir = getCommandsDir(configDir);
|
|
4933
|
-
return restoreDefault(commandsDir, bundleDir, DEFAULTS_DIR2, commandId, COMMAND_EXTENSION) || restoreDefault(commandsDir, bundleDir, DEFAULTS_DIR_ALT2, commandId, COMMAND_EXTENSION);
|
|
4934
|
-
}
|
|
4935
|
-
async function getModifiedDefaultCommandIds(configDir) {
|
|
4936
|
-
const bundleDir = getBundleDir();
|
|
4937
|
-
const ids = await getDefaultCommandIds();
|
|
4938
|
-
const files = (await readdir2(join4(bundleDir, DEFAULTS_DIR2))).filter((f) => f.endsWith(COMMAND_EXTENSION));
|
|
4939
|
-
return files.map((f) => f.replace(COMMAND_EXTENSION, "")).filter((id) => ids.includes(id));
|
|
4940
|
-
}
|
|
4941
|
-
async function restoreAllDefaultCommands(configDir) {
|
|
4942
|
-
const ids = await getDefaultCommandIds();
|
|
4943
|
-
let count = 0;
|
|
4944
|
-
for (const id of ids) {
|
|
4945
|
-
if (await restoreDefaultCommand(configDir, id)) count++;
|
|
4946
|
-
}
|
|
4947
|
-
return count;
|
|
4948
|
-
}
|
|
4949
|
-
function findCommandById(commandId, commands) {
|
|
4950
|
-
return findById(commandId, commands);
|
|
4951
|
-
}
|
|
4952
|
-
async function commandExists(configDir, commandId) {
|
|
4953
|
-
return dirExists(join4(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`));
|
|
4954
|
-
}
|
|
4955
|
-
async function saveCommand(configDir, command) {
|
|
4956
|
-
return saveItem(getCommandsDir(configDir), command.metadata.id, COMMAND_EXTENSION, command);
|
|
4957
|
-
}
|
|
4958
|
-
async function deleteCommand(configDir, commandId) {
|
|
4959
|
-
return deleteItem(getCommandsDir(configDir), commandId, COMMAND_EXTENSION);
|
|
4871
|
+
// src/server/routes/skills.ts
|
|
4872
|
+
import { Router } from "express";
|
|
4873
|
+
|
|
4874
|
+
// src/server/routes/crud-helpers.ts
|
|
4875
|
+
function computeOverrideIds(defaults, userItems) {
|
|
4876
|
+
return userItems.filter((u) => defaults.some((d) => d.metadata.id === u.metadata.id)).map((u) => u.metadata.id);
|
|
4960
4877
|
}
|
|
4961
4878
|
|
|
4962
4879
|
// src/server/routes/skills.ts
|
|
4963
|
-
import { Router } from "express";
|
|
4964
4880
|
function createSkillRoutes(configDir) {
|
|
4965
4881
|
const router = Router();
|
|
4966
4882
|
router.get("/", async (_req, res) => {
|
|
4967
|
-
const [
|
|
4968
|
-
|
|
4969
|
-
|
|
4970
|
-
getModifiedDefaultSkillIds(configDir)
|
|
4883
|
+
const [defaults, userItems] = await Promise.all([
|
|
4884
|
+
loadDefaultSkills(),
|
|
4885
|
+
loadUserSkills(configDir)
|
|
4971
4886
|
]);
|
|
4887
|
+
const overrideIds = computeOverrideIds(defaults, userItems);
|
|
4972
4888
|
res.json({
|
|
4973
|
-
|
|
4889
|
+
defaults: defaults.map((s) => ({
|
|
4974
4890
|
...s.metadata,
|
|
4975
4891
|
enabled: isSkillEnabled(s.metadata.id)
|
|
4976
4892
|
})),
|
|
4977
|
-
|
|
4978
|
-
|
|
4893
|
+
userItems: userItems.map((s) => ({
|
|
4894
|
+
...s.metadata,
|
|
4895
|
+
enabled: isSkillEnabled(s.metadata.id)
|
|
4896
|
+
})),
|
|
4897
|
+
overrideIds
|
|
4979
4898
|
});
|
|
4980
4899
|
});
|
|
4900
|
+
router.get("/defaults/:id", async (req, res) => {
|
|
4901
|
+
const { id } = req.params;
|
|
4902
|
+
const content = await getDefaultSkillContent(id);
|
|
4903
|
+
if (!content) {
|
|
4904
|
+
return res.status(404).json({ error: "Default skill not found" });
|
|
4905
|
+
}
|
|
4906
|
+
res.json(content);
|
|
4907
|
+
});
|
|
4981
4908
|
router.get("/default-ids", async (_req, res) => {
|
|
4982
4909
|
const ids = await getDefaultSkillIds();
|
|
4983
4910
|
res.json({ ids });
|
|
4984
4911
|
});
|
|
4985
|
-
router.post("/restore-all-defaults", async (_req, res) => {
|
|
4986
|
-
const count = await restoreAllDefaultSkills(configDir);
|
|
4987
|
-
res.json({ success: true, count });
|
|
4988
|
-
});
|
|
4989
|
-
router.post("/:id/restore-default", async (req, res) => {
|
|
4990
|
-
const { id } = req.params;
|
|
4991
|
-
const restored = await restoreDefaultSkill(configDir, id);
|
|
4992
|
-
if (!restored) {
|
|
4993
|
-
return res.status(404).json({ error: "No bundled default found for this skill" });
|
|
4994
|
-
}
|
|
4995
|
-
res.json({ success: true });
|
|
4996
|
-
});
|
|
4997
4912
|
router.post("/:id/toggle", (req, res) => {
|
|
4998
4913
|
const { id } = req.params;
|
|
4999
4914
|
const currentlyEnabled = isSkillEnabled(id);
|
|
@@ -5017,7 +4932,8 @@ function createSkillRoutes(configDir) {
|
|
|
5017
4932
|
if (!/^[a-z0-9-]+$/.test(body.metadata.id)) {
|
|
5018
4933
|
return res.status(400).json({ error: "Skill ID must be lowercase alphanumeric with hyphens only" });
|
|
5019
4934
|
}
|
|
5020
|
-
|
|
4935
|
+
const exists = await skillExists(configDir, body.metadata.id);
|
|
4936
|
+
if (exists) {
|
|
5021
4937
|
return res.status(409).json({ error: "A skill with this ID already exists" });
|
|
5022
4938
|
}
|
|
5023
4939
|
await saveSkill(configDir, body);
|
|
@@ -5025,15 +4941,12 @@ function createSkillRoutes(configDir) {
|
|
|
5025
4941
|
});
|
|
5026
4942
|
router.put("/:id", async (req, res) => {
|
|
5027
4943
|
const { id } = req.params;
|
|
5028
|
-
if (!await skillExists(configDir, id)) {
|
|
5029
|
-
return res.status(404).json({ error: "Skill not found" });
|
|
5030
|
-
}
|
|
5031
|
-
const body = req.body;
|
|
5032
4944
|
const skills = await loadAllSkills(configDir);
|
|
5033
4945
|
const existing = findSkillById(id, skills);
|
|
5034
4946
|
if (!existing) {
|
|
5035
4947
|
return res.status(404).json({ error: "Skill not found" });
|
|
5036
4948
|
}
|
|
4949
|
+
const body = req.body;
|
|
5037
4950
|
const updated = {
|
|
5038
4951
|
metadata: { ...existing.metadata, ...body.metadata, id },
|
|
5039
4952
|
prompt: body.prompt ?? existing.prompt
|
|
@@ -5043,47 +4956,148 @@ function createSkillRoutes(configDir) {
|
|
|
5043
4956
|
});
|
|
5044
4957
|
router.delete("/:id", async (req, res) => {
|
|
5045
4958
|
const { id } = req.params;
|
|
5046
|
-
const
|
|
5047
|
-
if (!
|
|
5048
|
-
return res.status(
|
|
4959
|
+
const result = await deleteSkill(configDir, id);
|
|
4960
|
+
if (!result.success) {
|
|
4961
|
+
return res.status(403).json({ error: result.reason ?? "Cannot delete this skill" });
|
|
5049
4962
|
}
|
|
5050
4963
|
res.json({ success: true });
|
|
5051
4964
|
});
|
|
4965
|
+
router.post("/:id/duplicate", async (req, res) => {
|
|
4966
|
+
const { id } = req.params;
|
|
4967
|
+
const defaults = await loadDefaultSkills();
|
|
4968
|
+
const userItems = await loadUserSkills(configDir);
|
|
4969
|
+
const source = defaults.find((s) => s.metadata.id === id) ?? userItems.find((s) => s.metadata.id === id);
|
|
4970
|
+
if (!source) {
|
|
4971
|
+
return res.status(404).json({ error: "Skill not found" });
|
|
4972
|
+
}
|
|
4973
|
+
const newId = `${id}-copy-${Date.now()}`;
|
|
4974
|
+
const duplicated = {
|
|
4975
|
+
metadata: { ...source.metadata, id: newId, name: `${source.metadata.name} (copy)` },
|
|
4976
|
+
prompt: source.prompt
|
|
4977
|
+
};
|
|
4978
|
+
await saveSkill(configDir, duplicated);
|
|
4979
|
+
res.status(201).json(duplicated);
|
|
4980
|
+
});
|
|
5052
4981
|
return router;
|
|
5053
4982
|
}
|
|
5054
4983
|
|
|
5055
4984
|
// src/server/routes/commands.ts
|
|
5056
4985
|
import { Router as Router2 } from "express";
|
|
4986
|
+
|
|
4987
|
+
// src/server/commands/registry.ts
|
|
4988
|
+
import { writeFile as writeFile3, mkdir as mkdir3, unlink as unlink2 } from "fs/promises";
|
|
4989
|
+
import { join as join4, dirname as dirname4 } from "path";
|
|
4990
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
4991
|
+
import matter from "gray-matter";
|
|
4992
|
+
var __bundleDir2 = dirname4(fileURLToPath3(import.meta.url));
|
|
4993
|
+
var DEFAULTS_DIR2 = join4(__bundleDir2, "defaults");
|
|
4994
|
+
var DEFAULTS_DIR_ALT2 = join4(__bundleDir2, "command-defaults");
|
|
4995
|
+
var COMMAND_EXTENSION = ".command.md";
|
|
4996
|
+
function getCommandsDir(configDir) {
|
|
4997
|
+
return join4(configDir, "commands");
|
|
4998
|
+
}
|
|
4999
|
+
async function loadDefaultCommands() {
|
|
5000
|
+
let defaults = await loadItemsFromDir(DEFAULTS_DIR2, {
|
|
5001
|
+
extension: COMMAND_EXTENSION,
|
|
5002
|
+
logName: "command"
|
|
5003
|
+
});
|
|
5004
|
+
if (!defaults.length) {
|
|
5005
|
+
defaults = await loadItemsFromDir(DEFAULTS_DIR_ALT2, {
|
|
5006
|
+
extension: COMMAND_EXTENSION,
|
|
5007
|
+
logName: "command"
|
|
5008
|
+
});
|
|
5009
|
+
}
|
|
5010
|
+
return defaults;
|
|
5011
|
+
}
|
|
5012
|
+
async function loadUserCommands(configDir) {
|
|
5013
|
+
return loadItemsFromDir(getCommandsDir(configDir), {
|
|
5014
|
+
extension: COMMAND_EXTENSION,
|
|
5015
|
+
logName: "command"
|
|
5016
|
+
});
|
|
5017
|
+
}
|
|
5018
|
+
async function loadAllCommands(configDir) {
|
|
5019
|
+
const [defaultCommands, userCommands] = await Promise.all([
|
|
5020
|
+
loadDefaultCommands(),
|
|
5021
|
+
loadUserCommands(configDir)
|
|
5022
|
+
]);
|
|
5023
|
+
const commandMap = /* @__PURE__ */ new Map();
|
|
5024
|
+
for (const cmd of defaultCommands) {
|
|
5025
|
+
commandMap.set(cmd.metadata.id, cmd);
|
|
5026
|
+
}
|
|
5027
|
+
for (const cmd of userCommands) {
|
|
5028
|
+
commandMap.set(cmd.metadata.id, cmd);
|
|
5029
|
+
}
|
|
5030
|
+
return Array.from(commandMap.values());
|
|
5031
|
+
}
|
|
5032
|
+
async function getDefaultCommandIds() {
|
|
5033
|
+
const ids = await getDefaultIds(DEFAULTS_DIR2, COMMAND_EXTENSION);
|
|
5034
|
+
if (ids.length) return ids;
|
|
5035
|
+
return getDefaultIds(DEFAULTS_DIR_ALT2, COMMAND_EXTENSION);
|
|
5036
|
+
}
|
|
5037
|
+
async function getDefaultCommandContent(commandId) {
|
|
5038
|
+
const defaults = await loadDefaultCommands();
|
|
5039
|
+
return defaults.find((c) => c.metadata.id === commandId) ?? null;
|
|
5040
|
+
}
|
|
5041
|
+
async function isDefaultCommand(commandId) {
|
|
5042
|
+
const defaultIds = await getDefaultCommandIds();
|
|
5043
|
+
return defaultIds.includes(commandId);
|
|
5044
|
+
}
|
|
5045
|
+
function findCommandById(commandId, commands) {
|
|
5046
|
+
return commands.find((c) => c.metadata.id === commandId);
|
|
5047
|
+
}
|
|
5048
|
+
async function commandExists(configDir, commandId) {
|
|
5049
|
+
return pathExists(join4(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`));
|
|
5050
|
+
}
|
|
5051
|
+
async function saveCommand(configDir, command) {
|
|
5052
|
+
const commandsDir = getCommandsDir(configDir);
|
|
5053
|
+
if (!await pathExists(commandsDir)) {
|
|
5054
|
+
await mkdir3(commandsDir, { recursive: true });
|
|
5055
|
+
}
|
|
5056
|
+
const filePath = join4(commandsDir, `${command.metadata.id}${COMMAND_EXTENSION}`);
|
|
5057
|
+
const content = matter.stringify(command.prompt, command.metadata);
|
|
5058
|
+
await writeFile3(filePath, content, "utf-8");
|
|
5059
|
+
}
|
|
5060
|
+
async function deleteCommand(configDir, commandId) {
|
|
5061
|
+
const isDefault = await isDefaultCommand(commandId);
|
|
5062
|
+
if (isDefault) {
|
|
5063
|
+
return { success: false, reason: "Cannot delete built-in defaults" };
|
|
5064
|
+
}
|
|
5065
|
+
const filePath = join4(getCommandsDir(configDir), `${commandId}${COMMAND_EXTENSION}`);
|
|
5066
|
+
try {
|
|
5067
|
+
await unlink2(filePath);
|
|
5068
|
+
return { success: true };
|
|
5069
|
+
} catch {
|
|
5070
|
+
return { success: false };
|
|
5071
|
+
}
|
|
5072
|
+
}
|
|
5073
|
+
|
|
5074
|
+
// src/server/routes/commands.ts
|
|
5057
5075
|
function createCommandRoutes(configDir) {
|
|
5058
5076
|
const router = Router2();
|
|
5059
5077
|
router.get("/", async (_req, res) => {
|
|
5060
|
-
const [
|
|
5061
|
-
|
|
5062
|
-
|
|
5063
|
-
getModifiedDefaultCommandIds(configDir)
|
|
5078
|
+
const [defaults, userItems] = await Promise.all([
|
|
5079
|
+
loadDefaultCommands(),
|
|
5080
|
+
loadUserCommands(configDir)
|
|
5064
5081
|
]);
|
|
5082
|
+
const overrideIds = computeOverrideIds(defaults, userItems);
|
|
5065
5083
|
res.json({
|
|
5066
|
-
|
|
5067
|
-
|
|
5068
|
-
|
|
5084
|
+
defaults: defaults.map((c) => c.metadata),
|
|
5085
|
+
userItems: userItems.map((c) => c.metadata),
|
|
5086
|
+
overrideIds
|
|
5069
5087
|
});
|
|
5070
5088
|
});
|
|
5089
|
+
router.get("/defaults/:id", async (req, res) => {
|
|
5090
|
+
const { id } = req.params;
|
|
5091
|
+
const content = await getDefaultCommandContent(id);
|
|
5092
|
+
if (!content) {
|
|
5093
|
+
return res.status(404).json({ error: "Default command not found" });
|
|
5094
|
+
}
|
|
5095
|
+
res.json(content);
|
|
5096
|
+
});
|
|
5071
5097
|
router.get("/default-ids", async (_req, res) => {
|
|
5072
5098
|
const ids = await getDefaultCommandIds();
|
|
5073
5099
|
res.json({ ids });
|
|
5074
5100
|
});
|
|
5075
|
-
router.post("/restore-all-defaults", async (_req, res) => {
|
|
5076
|
-
const count = await restoreAllDefaultCommands(configDir);
|
|
5077
|
-
res.json({ success: true, count });
|
|
5078
|
-
});
|
|
5079
|
-
router.post("/:id/restore-default", async (req, res) => {
|
|
5080
|
-
const { id } = req.params;
|
|
5081
|
-
const restored = await restoreDefaultCommand(configDir, id);
|
|
5082
|
-
if (!restored) {
|
|
5083
|
-
return res.status(404).json({ error: "No bundled default found for this command" });
|
|
5084
|
-
}
|
|
5085
|
-
res.json({ success: true });
|
|
5086
|
-
});
|
|
5087
5101
|
router.get("/:id", async (req, res) => {
|
|
5088
5102
|
const { id } = req.params;
|
|
5089
5103
|
const commands = await loadAllCommands(configDir);
|
|
@@ -5101,7 +5115,8 @@ function createCommandRoutes(configDir) {
|
|
|
5101
5115
|
if (!/^[a-z0-9-]+$/.test(body.metadata.id)) {
|
|
5102
5116
|
return res.status(400).json({ error: "Command ID must be lowercase alphanumeric with hyphens only" });
|
|
5103
5117
|
}
|
|
5104
|
-
|
|
5118
|
+
const exists = await commandExists(configDir, body.metadata.id);
|
|
5119
|
+
if (exists) {
|
|
5105
5120
|
return res.status(409).json({ error: "A command with this ID already exists" });
|
|
5106
5121
|
}
|
|
5107
5122
|
await saveCommand(configDir, body);
|
|
@@ -5109,15 +5124,12 @@ function createCommandRoutes(configDir) {
|
|
|
5109
5124
|
});
|
|
5110
5125
|
router.put("/:id", async (req, res) => {
|
|
5111
5126
|
const { id } = req.params;
|
|
5112
|
-
if (!await commandExists(configDir, id)) {
|
|
5113
|
-
return res.status(404).json({ error: "Command not found" });
|
|
5114
|
-
}
|
|
5115
|
-
const body = req.body;
|
|
5116
5127
|
const commands = await loadAllCommands(configDir);
|
|
5117
5128
|
const existing = findCommandById(id, commands);
|
|
5118
5129
|
if (!existing) {
|
|
5119
5130
|
return res.status(404).json({ error: "Command not found" });
|
|
5120
5131
|
}
|
|
5132
|
+
const body = req.body;
|
|
5121
5133
|
const updated = {
|
|
5122
5134
|
metadata: { ...existing.metadata, ...body.metadata, id },
|
|
5123
5135
|
prompt: body.prompt ?? existing.prompt
|
|
@@ -5127,12 +5139,28 @@ function createCommandRoutes(configDir) {
|
|
|
5127
5139
|
});
|
|
5128
5140
|
router.delete("/:id", async (req, res) => {
|
|
5129
5141
|
const { id } = req.params;
|
|
5130
|
-
const
|
|
5131
|
-
if (!
|
|
5132
|
-
return res.status(
|
|
5142
|
+
const result = await deleteCommand(configDir, id);
|
|
5143
|
+
if (!result.success) {
|
|
5144
|
+
return res.status(403).json({ error: result.reason ?? "Cannot delete this command" });
|
|
5133
5145
|
}
|
|
5134
5146
|
res.json({ success: true });
|
|
5135
5147
|
});
|
|
5148
|
+
router.post("/:id/duplicate", async (req, res) => {
|
|
5149
|
+
const { id } = req.params;
|
|
5150
|
+
const defaults = await loadDefaultCommands();
|
|
5151
|
+
const userItems = await loadUserCommands(configDir);
|
|
5152
|
+
const source = defaults.find((c) => c.metadata.id === id) ?? userItems.find((c) => c.metadata.id === id);
|
|
5153
|
+
if (!source) {
|
|
5154
|
+
return res.status(404).json({ error: "Command not found" });
|
|
5155
|
+
}
|
|
5156
|
+
const newId = `${id}-copy-${Date.now()}`;
|
|
5157
|
+
const duplicated = {
|
|
5158
|
+
metadata: { ...source.metadata, id: newId, name: `${source.metadata.name} (copy)` },
|
|
5159
|
+
prompt: source.prompt
|
|
5160
|
+
};
|
|
5161
|
+
await saveCommand(configDir, duplicated);
|
|
5162
|
+
res.status(201).json(duplicated);
|
|
5163
|
+
});
|
|
5136
5164
|
return router;
|
|
5137
5165
|
}
|
|
5138
5166
|
|
|
@@ -5141,33 +5169,29 @@ import { Router as Router3 } from "express";
|
|
|
5141
5169
|
function createAgentRoutes(configDir) {
|
|
5142
5170
|
const router = Router3();
|
|
5143
5171
|
router.get("/", async (_req, res) => {
|
|
5144
|
-
const [
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
getModifiedDefaultAgentIds(configDir)
|
|
5172
|
+
const [defaults, userItems] = await Promise.all([
|
|
5173
|
+
loadDefaultAgents(),
|
|
5174
|
+
loadUserAgents(configDir)
|
|
5148
5175
|
]);
|
|
5176
|
+
const overrideIds = computeOverrideIds(defaults, userItems);
|
|
5149
5177
|
res.json({
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5178
|
+
defaults: defaults.map((a) => a.metadata),
|
|
5179
|
+
userItems: userItems.map((a) => a.metadata),
|
|
5180
|
+
overrideIds
|
|
5153
5181
|
});
|
|
5154
5182
|
});
|
|
5183
|
+
router.get("/defaults/:id", async (req, res) => {
|
|
5184
|
+
const { id } = req.params;
|
|
5185
|
+
const content = await getDefaultAgentContent(id);
|
|
5186
|
+
if (!content) {
|
|
5187
|
+
return res.status(404).json({ error: "Default agent not found" });
|
|
5188
|
+
}
|
|
5189
|
+
res.json(content);
|
|
5190
|
+
});
|
|
5155
5191
|
router.get("/default-ids", async (_req, res) => {
|
|
5156
5192
|
const ids = await getDefaultAgentIds();
|
|
5157
5193
|
res.json({ ids });
|
|
5158
5194
|
});
|
|
5159
|
-
router.post("/restore-all-defaults", async (_req, res) => {
|
|
5160
|
-
const count = await restoreAllDefaultAgents(configDir);
|
|
5161
|
-
res.json({ success: true, count });
|
|
5162
|
-
});
|
|
5163
|
-
router.post("/:id/restore-default", async (req, res) => {
|
|
5164
|
-
const { id } = req.params;
|
|
5165
|
-
const restored = await restoreDefaultAgent(configDir, id);
|
|
5166
|
-
if (!restored) {
|
|
5167
|
-
return res.status(404).json({ error: "No bundled default found for this agent" });
|
|
5168
|
-
}
|
|
5169
|
-
res.json({ success: true });
|
|
5170
|
-
});
|
|
5171
5195
|
router.get("/:id", async (req, res) => {
|
|
5172
5196
|
const { id } = req.params;
|
|
5173
5197
|
const agents = await loadAllAgents(configDir);
|
|
@@ -5182,7 +5206,8 @@ function createAgentRoutes(configDir) {
|
|
|
5182
5206
|
if (!body?.metadata?.id || !body?.prompt) {
|
|
5183
5207
|
return res.status(400).json({ error: "Missing required fields: metadata.id, prompt" });
|
|
5184
5208
|
}
|
|
5185
|
-
|
|
5209
|
+
const exists = await agentExists(configDir, body.metadata.id);
|
|
5210
|
+
if (exists) {
|
|
5186
5211
|
return res.status(409).json({ error: "An agent with this ID already exists" });
|
|
5187
5212
|
}
|
|
5188
5213
|
await saveAgent(configDir, body);
|
|
@@ -5208,12 +5233,28 @@ function createAgentRoutes(configDir) {
|
|
|
5208
5233
|
});
|
|
5209
5234
|
router.delete("/:id", async (req, res) => {
|
|
5210
5235
|
const { id } = req.params;
|
|
5211
|
-
const
|
|
5212
|
-
if (!
|
|
5213
|
-
return res.status(
|
|
5236
|
+
const result = await deleteAgent(configDir, id);
|
|
5237
|
+
if (!result.success) {
|
|
5238
|
+
return res.status(403).json({ error: result.reason ?? "Cannot delete this agent" });
|
|
5214
5239
|
}
|
|
5215
5240
|
res.json({ success: true });
|
|
5216
5241
|
});
|
|
5242
|
+
router.post("/:id/duplicate", async (req, res) => {
|
|
5243
|
+
const { id } = req.params;
|
|
5244
|
+
const defaults = await loadDefaultAgents();
|
|
5245
|
+
const userItems = await loadUserAgents(configDir);
|
|
5246
|
+
const source = defaults.find((a) => a.metadata.id === id) ?? userItems.find((a) => a.metadata.id === id);
|
|
5247
|
+
if (!source) {
|
|
5248
|
+
return res.status(404).json({ error: "Agent not found" });
|
|
5249
|
+
}
|
|
5250
|
+
const newId = `${id}-copy-${Date.now()}`;
|
|
5251
|
+
const duplicated = {
|
|
5252
|
+
metadata: { ...source.metadata, id: newId, name: `${source.metadata.name} (copy)` },
|
|
5253
|
+
prompt: source.prompt
|
|
5254
|
+
};
|
|
5255
|
+
await saveAgent(configDir, duplicated);
|
|
5256
|
+
res.status(201).json(duplicated);
|
|
5257
|
+
});
|
|
5217
5258
|
return router;
|
|
5218
5259
|
}
|
|
5219
5260
|
|
|
@@ -5222,37 +5263,33 @@ import { Router as Router4 } from "express";
|
|
|
5222
5263
|
function createWorkflowRoutes(configDir, config) {
|
|
5223
5264
|
const router = Router4();
|
|
5224
5265
|
router.get("/", async (_req, res) => {
|
|
5225
|
-
const [
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
getModifiedDefaultWorkflowIds(configDir)
|
|
5266
|
+
const [defaults, userItems] = await Promise.all([
|
|
5267
|
+
loadDefaultWorkflows(),
|
|
5268
|
+
loadUserWorkflows(configDir)
|
|
5229
5269
|
]);
|
|
5270
|
+
const overrideIds = computeOverrideIds(defaults, userItems);
|
|
5230
5271
|
res.json({
|
|
5231
|
-
|
|
5272
|
+
defaults: defaults.map((p) => ({ ...p.metadata, startCondition: p.startCondition })),
|
|
5273
|
+
userItems: userItems.map((p) => ({ ...p.metadata, startCondition: p.startCondition })),
|
|
5232
5274
|
activeWorkflowId: config.activeWorkflowId ?? "default",
|
|
5233
|
-
|
|
5234
|
-
modifiedIds
|
|
5275
|
+
overrideIds
|
|
5235
5276
|
});
|
|
5236
5277
|
});
|
|
5237
5278
|
router.get("/template-variables", (_req, res) => {
|
|
5238
5279
|
res.json({ variables: TEMPLATE_VARIABLES });
|
|
5239
5280
|
});
|
|
5281
|
+
router.get("/defaults/:id", async (req, res) => {
|
|
5282
|
+
const { id } = req.params;
|
|
5283
|
+
const content = await getDefaultWorkflowContent(id);
|
|
5284
|
+
if (!content) {
|
|
5285
|
+
return res.status(404).json({ error: "Default workflow not found" });
|
|
5286
|
+
}
|
|
5287
|
+
res.json(content);
|
|
5288
|
+
});
|
|
5240
5289
|
router.get("/default-ids", async (_req, res) => {
|
|
5241
5290
|
const ids = await getDefaultWorkflowIds();
|
|
5242
5291
|
res.json({ ids });
|
|
5243
5292
|
});
|
|
5244
|
-
router.post("/restore-all-defaults", async (_req, res) => {
|
|
5245
|
-
const count = await restoreAllDefaultWorkflows(configDir);
|
|
5246
|
-
res.json({ success: true, count });
|
|
5247
|
-
});
|
|
5248
|
-
router.post("/:id/restore-default", async (req, res) => {
|
|
5249
|
-
const { id } = req.params;
|
|
5250
|
-
const restored = await restoreDefaultWorkflow(configDir, id);
|
|
5251
|
-
if (!restored) {
|
|
5252
|
-
return res.status(404).json({ error: "No bundled default found for this workflow" });
|
|
5253
|
-
}
|
|
5254
|
-
res.json({ success: true });
|
|
5255
|
-
});
|
|
5256
5293
|
router.get("/:id", async (req, res) => {
|
|
5257
5294
|
const { id } = req.params;
|
|
5258
5295
|
const workflows = await loadAllWorkflows(configDir);
|
|
@@ -5267,7 +5304,8 @@ function createWorkflowRoutes(configDir, config) {
|
|
|
5267
5304
|
if (!body?.metadata?.id || !body?.steps?.length) {
|
|
5268
5305
|
return res.status(400).json({ error: "Missing required fields: metadata.id, steps" });
|
|
5269
5306
|
}
|
|
5270
|
-
|
|
5307
|
+
const exists = await workflowExists(configDir, body.metadata.id);
|
|
5308
|
+
if (exists) {
|
|
5271
5309
|
return res.status(409).json({ error: "A workflow with this ID already exists" });
|
|
5272
5310
|
}
|
|
5273
5311
|
await saveWorkflow(configDir, body);
|
|
@@ -5275,7 +5313,9 @@ function createWorkflowRoutes(configDir, config) {
|
|
|
5275
5313
|
});
|
|
5276
5314
|
router.put("/:id", async (req, res) => {
|
|
5277
5315
|
const { id } = req.params;
|
|
5278
|
-
|
|
5316
|
+
const workflows = await loadAllWorkflows(configDir);
|
|
5317
|
+
const existing = findWorkflowById(id, workflows);
|
|
5318
|
+
if (!existing) {
|
|
5279
5319
|
return res.status(404).json({ error: "Workflow not found" });
|
|
5280
5320
|
}
|
|
5281
5321
|
const body = req.body;
|
|
@@ -5288,14 +5328,27 @@ function createWorkflowRoutes(configDir, config) {
|
|
|
5288
5328
|
});
|
|
5289
5329
|
router.delete("/:id", async (req, res) => {
|
|
5290
5330
|
const { id } = req.params;
|
|
5291
|
-
|
|
5292
|
-
|
|
5331
|
+
const result = await deleteWorkflow(configDir, id);
|
|
5332
|
+
if (!result.success) {
|
|
5333
|
+
return res.status(403).json({ error: result.reason ?? "Cannot delete this workflow" });
|
|
5293
5334
|
}
|
|
5294
|
-
|
|
5295
|
-
|
|
5335
|
+
res.json({ success: true });
|
|
5336
|
+
});
|
|
5337
|
+
router.post("/:id/duplicate", async (req, res) => {
|
|
5338
|
+
const { id } = req.params;
|
|
5339
|
+
const defaults = await loadDefaultWorkflows();
|
|
5340
|
+
const userItems = await loadUserWorkflows(configDir);
|
|
5341
|
+
const source = defaults.find((w) => w.metadata.id === id) ?? userItems.find((w) => w.metadata.id === id);
|
|
5342
|
+
if (!source) {
|
|
5296
5343
|
return res.status(404).json({ error: "Workflow not found" });
|
|
5297
5344
|
}
|
|
5298
|
-
|
|
5345
|
+
const newId = `${id}-copy-${Date.now()}`;
|
|
5346
|
+
const duplicated = {
|
|
5347
|
+
...source,
|
|
5348
|
+
metadata: { ...source.metadata, id: newId, name: `${source.metadata.name} (copy)` }
|
|
5349
|
+
};
|
|
5350
|
+
await saveWorkflow(configDir, duplicated);
|
|
5351
|
+
res.status(201).json(duplicated);
|
|
5299
5352
|
});
|
|
5300
5353
|
return router;
|
|
5301
5354
|
}
|
|
@@ -5419,10 +5472,10 @@ function createTerminalRoutes() {
|
|
|
5419
5472
|
}
|
|
5420
5473
|
|
|
5421
5474
|
// src/constants.ts
|
|
5422
|
-
var VERSION = "1.6.
|
|
5475
|
+
var VERSION = "1.6.17";
|
|
5423
5476
|
|
|
5424
5477
|
// src/server/index.ts
|
|
5425
|
-
var __dirname2 =
|
|
5478
|
+
var __dirname2 = dirname5(fileURLToPath4(import.meta.url));
|
|
5426
5479
|
async function createServerHandle(config) {
|
|
5427
5480
|
setRuntimeConfig(config);
|
|
5428
5481
|
setLogLevel(config.logging?.level ?? void 0, config.mode);
|
|
@@ -5430,10 +5483,6 @@ async function createServerHandle(config) {
|
|
|
5430
5483
|
const db = initDatabase(config);
|
|
5431
5484
|
initEventStore(db);
|
|
5432
5485
|
const configDir = getGlobalConfigDir(config.mode ?? "production");
|
|
5433
|
-
await ensureDefaultSkills(configDir);
|
|
5434
|
-
await ensureDefaultCommands(configDir);
|
|
5435
|
-
await ensureDefaultAgents(configDir);
|
|
5436
|
-
await ensureDefaultWorkflows(configDir);
|
|
5437
5486
|
const providerManager = createProviderManager(config);
|
|
5438
5487
|
const sessionManager = new SessionManager(providerManager);
|
|
5439
5488
|
const useMock = process.env["OPENFOX_MOCK_LLM"] === "true";
|
|
@@ -5725,7 +5774,7 @@ async function createServerHandle(config) {
|
|
|
5725
5774
|
if (!callId || approved === void 0) {
|
|
5726
5775
|
return res.status(400).json({ error: "callId and approved are required" });
|
|
5727
5776
|
}
|
|
5728
|
-
const { providePathConfirmation: providePathConfirmation2 } = await import("./tools-
|
|
5777
|
+
const { providePathConfirmation: providePathConfirmation2 } = await import("./tools-YRDPOS6P.js");
|
|
5729
5778
|
const result = providePathConfirmation2(callId, approved, alwaysAllow);
|
|
5730
5779
|
if (!result.found) {
|
|
5731
5780
|
return res.status(404).json({ error: "No pending path confirmation with that ID" });
|
|
@@ -5750,7 +5799,7 @@ async function createServerHandle(config) {
|
|
|
5750
5799
|
if (!callId || !answer) {
|
|
5751
5800
|
return res.status(400).json({ error: "callId and answer are required" });
|
|
5752
5801
|
}
|
|
5753
|
-
const { provideAnswer: provideAnswer2 } = await import("./tools-
|
|
5802
|
+
const { provideAnswer: provideAnswer2 } = await import("./tools-YRDPOS6P.js");
|
|
5754
5803
|
const found = provideAnswer2(callId, answer);
|
|
5755
5804
|
if (!found) {
|
|
5756
5805
|
return res.status(404).json({ error: "No pending question with that ID" });
|
|
@@ -5786,8 +5835,8 @@ async function createServerHandle(config) {
|
|
|
5786
5835
|
if (!session) {
|
|
5787
5836
|
return res.status(404).json({ error: "Session not found" });
|
|
5788
5837
|
}
|
|
5789
|
-
const { stopSessionExecution } = await import("./chat-handler-
|
|
5790
|
-
const { cancelQuestionsForSession: cancelQuestionsForSession2, cancelPathConfirmationsForSession: cancelPathConfirmationsForSession2 } = await import("./tools-
|
|
5838
|
+
const { stopSessionExecution } = await import("./chat-handler-7HWNXQ4G.js");
|
|
5839
|
+
const { cancelQuestionsForSession: cancelQuestionsForSession2, cancelPathConfirmationsForSession: cancelPathConfirmationsForSession2 } = await import("./tools-YRDPOS6P.js");
|
|
5791
5840
|
stopSessionExecution(sessionId, sessionManager);
|
|
5792
5841
|
abortSession(sessionId);
|
|
5793
5842
|
cancelQuestionsForSession2(sessionId, "Session stopped by user");
|
|
@@ -6109,7 +6158,7 @@ async function createServerHandle(config) {
|
|
|
6109
6158
|
name: entry.name,
|
|
6110
6159
|
path: join5(resolvedPath, entry.name)
|
|
6111
6160
|
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
6112
|
-
const parent =
|
|
6161
|
+
const parent = dirname5(resolvedPath);
|
|
6113
6162
|
const hasParent = parent !== resolvedPath;
|
|
6114
6163
|
res.json({
|
|
6115
6164
|
current: resolvedPath,
|
|
@@ -6235,7 +6284,7 @@ async function createServerHandle(config) {
|
|
|
6235
6284
|
providerManager
|
|
6236
6285
|
);
|
|
6237
6286
|
const wss = wssExports.wss;
|
|
6238
|
-
const { QueueProcessor } = await import("./processor-
|
|
6287
|
+
const { QueueProcessor } = await import("./processor-PVYCX5GK.js");
|
|
6239
6288
|
const queueProcessor = new QueueProcessor({
|
|
6240
6289
|
sessionManager,
|
|
6241
6290
|
providerManager,
|
|
@@ -6308,4 +6357,4 @@ export {
|
|
|
6308
6357
|
createServerHandle,
|
|
6309
6358
|
createServer
|
|
6310
6359
|
};
|
|
6311
|
-
//# sourceMappingURL=chunk-
|
|
6360
|
+
//# sourceMappingURL=chunk-UJANEDP5.js.map
|