teleton 0.7.5 → 0.8.1
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/README.md +35 -15
- package/dist/chunk-3RG5ZIWI.js +10 -0
- package/dist/{chunk-LCCVZ4D2.js → chunk-3S4GGLLR.js} +28 -26
- package/dist/{chunk-NUGDTPE4.js → chunk-4L66JHQE.js} +2 -1
- package/dist/{chunk-OGMVWDVU.js → chunk-5FNWBZ5K.js} +1826 -4992
- package/dist/{chunk-U7FQYCBQ.js → chunk-7TECSLJ4.js} +2 -2
- package/dist/{chunk-2GLHOJ5C.js → chunk-7U7BOHCL.js} +103 -36
- package/dist/{chunk-DMXTIRUW.js → chunk-AYWEJCDB.js} +20 -39
- package/dist/chunk-CGOXE4WP.js +11315 -0
- package/dist/{chunk-5UVXJMOX.js → chunk-KVXV7EF7.js} +4 -4
- package/dist/{chunk-QOQWUUA4.js → chunk-OJCLKU5Z.js} +68 -2
- package/dist/{chunk-CB2Y45HA.js → chunk-PHSAHTK4.js} +51 -3
- package/dist/{chunk-WIKM24GZ.js → chunk-QBHRXLZS.js} +5 -0
- package/dist/{chunk-OCLG5GKI.js → chunk-QV2GLOTK.js} +14 -3
- package/dist/{chunk-AVDWXYQ7.js → chunk-S6PHGKOC.js} +12 -1
- package/dist/{chunk-YP25WTQK.js → chunk-UP55PXFH.js} +6 -0
- package/dist/cli/index.js +21 -21
- package/dist/{client-O37XDCJB.js → client-MPHPIZB6.js} +4 -4
- package/dist/{get-my-gifts-TPVUGUWT.js → get-my-gifts-CC6HAVWB.js} +2 -2
- package/dist/index.js +14 -15
- package/dist/{memory-KQALFUV3.js → memory-UBHM7ILG.js} +5 -5
- package/dist/{migrate-UV3WEL5D.js → migrate-UBBEJ5BL.js} +5 -5
- package/dist/{multipart-parser-S3YC6NRJ.js → multipart-parser-UFQLJOV2.js} +2 -2
- package/dist/{paths-TMNTEDDD.js → paths-XA2RJH4S.js} +1 -1
- package/dist/{server-BHHJGUDF.js → server-3FHI2SEB.js} +398 -56
- package/dist/{setup-server-G7UG2DI3.js → setup-server-32XGDPE6.js} +161 -11
- package/dist/{store-H4XPNGC2.js → store-M5IMUQCL.js} +6 -6
- package/dist/{task-dependency-resolver-VMEVJRPO.js → task-dependency-resolver-RR2O5S7B.js} +3 -3
- package/dist/{task-executor-WWSPBJ4V.js → task-executor-6W5HRX5C.js} +3 -3
- package/dist/{tasks-QSCWSMPS.js → tasks-WQIKXDX5.js} +2 -2
- package/dist/{tool-adapter-Y3TCEQOC.js → tool-adapter-IH5VGBOO.js} +1 -1
- package/dist/{tool-index-2KH3OB6X.js → tool-index-PMAOXWUA.js} +9 -6
- package/dist/{transcript-UDJZP6NK.js → transcript-NGDPSNIH.js} +2 -2
- package/dist/web/assets/index-BfYCdwLI.js +80 -0
- package/dist/web/assets/{index-BrVqauzj.css → index-DmlyQVhR.css} +1 -1
- package/dist/web/assets/{index.es-Pet5-M13.js → index.es-DitvF-9H.js} +1 -1
- package/dist/web/index.html +2 -2
- package/package.json +12 -5
- package/dist/BigInteger-DQ33LTTE.js +0 -5
- package/dist/chunk-G2LLMJXJ.js +0 -5048
- package/dist/chunk-QGM4M3NI.js +0 -37
- package/dist/chunk-TSKJCWQQ.js +0 -1263
- package/dist/web/assets/index-Bx8JW3gV.js +0 -72
|
@@ -1,48 +1,58 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getModelsForProvider
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-OJCLKU5Z.js";
|
|
4
4
|
import {
|
|
5
5
|
CONFIGURABLE_KEYS,
|
|
6
|
+
TonProxyManager,
|
|
6
7
|
WorkspaceSecurityError,
|
|
7
8
|
adaptPlugin,
|
|
8
9
|
clearPromptCache,
|
|
9
10
|
deleteNestedValue,
|
|
10
11
|
deletePluginSecret,
|
|
11
12
|
ensurePluginDeps,
|
|
13
|
+
getBlocklistConfig,
|
|
12
14
|
getNestedValue,
|
|
15
|
+
getPluginPriorities,
|
|
13
16
|
getTokenUsage,
|
|
17
|
+
getTonProxyManager,
|
|
18
|
+
getTriggersConfig,
|
|
14
19
|
listPluginSecretKeys,
|
|
15
20
|
readRawConfig,
|
|
21
|
+
resetPluginPriority,
|
|
22
|
+
setBlocklistConfig,
|
|
16
23
|
setNestedValue,
|
|
24
|
+
setPluginPriority,
|
|
25
|
+
setTonProxyManager,
|
|
26
|
+
setTriggersConfig,
|
|
17
27
|
validateDirectory,
|
|
18
28
|
validatePath,
|
|
19
29
|
validateReadPath,
|
|
20
30
|
validateWritePath,
|
|
21
31
|
writePluginSecret,
|
|
22
32
|
writeRawConfig
|
|
23
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-CGOXE4WP.js";
|
|
24
34
|
import {
|
|
25
35
|
invalidateEndpointCache,
|
|
26
36
|
invalidateTonClientCache,
|
|
27
37
|
setToncenterApiKey
|
|
28
|
-
} from "./chunk-
|
|
29
|
-
import "./chunk-
|
|
30
|
-
import "./chunk-
|
|
38
|
+
} from "./chunk-S6PHGKOC.js";
|
|
39
|
+
import "./chunk-KVXV7EF7.js";
|
|
40
|
+
import "./chunk-7TECSLJ4.js";
|
|
31
41
|
import {
|
|
32
42
|
getErrorMessage
|
|
33
43
|
} from "./chunk-XBE4JB7C.js";
|
|
34
|
-
import "./chunk-
|
|
44
|
+
import "./chunk-AYWEJCDB.js";
|
|
35
45
|
import {
|
|
36
46
|
getProviderMetadata,
|
|
37
47
|
validateApiKeyFormat
|
|
38
|
-
} from "./chunk-
|
|
39
|
-
import "./chunk-
|
|
40
|
-
import "./chunk-
|
|
41
|
-
import "./chunk-
|
|
48
|
+
} from "./chunk-PHSAHTK4.js";
|
|
49
|
+
import "./chunk-QV2GLOTK.js";
|
|
50
|
+
import "./chunk-7U7BOHCL.js";
|
|
51
|
+
import "./chunk-3S4GGLLR.js";
|
|
42
52
|
import {
|
|
43
53
|
setTonapiKey
|
|
44
54
|
} from "./chunk-VFA7QMCZ.js";
|
|
45
|
-
import "./chunk-
|
|
55
|
+
import "./chunk-UP55PXFH.js";
|
|
46
56
|
import "./chunk-XQUHC3JZ.js";
|
|
47
57
|
import "./chunk-R4YSJ4EY.js";
|
|
48
58
|
import {
|
|
@@ -56,11 +66,11 @@ import {
|
|
|
56
66
|
} from "./chunk-RCMD3U65.js";
|
|
57
67
|
import {
|
|
58
68
|
getTaskStore
|
|
59
|
-
} from "./chunk-
|
|
60
|
-
import "./chunk-
|
|
69
|
+
} from "./chunk-4L66JHQE.js";
|
|
70
|
+
import "./chunk-3RG5ZIWI.js";
|
|
61
71
|
|
|
62
72
|
// src/webui/server.ts
|
|
63
|
-
import { Hono as
|
|
73
|
+
import { Hono as Hono14 } from "hono";
|
|
64
74
|
import { serve } from "@hono/node-server";
|
|
65
75
|
import { cors } from "hono/cors";
|
|
66
76
|
import { streamSSE as streamSSE2 } from "hono/streaming";
|
|
@@ -146,7 +156,8 @@ function createStatusRoutes(deps) {
|
|
|
146
156
|
provider: config.agent.provider,
|
|
147
157
|
sessionCount: sessionCountRow?.count ?? 0,
|
|
148
158
|
toolCount: deps.toolRegistry.getAll().length,
|
|
149
|
-
tokenUsage: getTokenUsage()
|
|
159
|
+
tokenUsage: getTokenUsage(),
|
|
160
|
+
platform: process.platform
|
|
150
161
|
};
|
|
151
162
|
const response = {
|
|
152
163
|
success: true,
|
|
@@ -412,15 +423,14 @@ function createLogsRoutes(_deps) {
|
|
|
412
423
|
const app = new Hono3();
|
|
413
424
|
app.get("/stream", (c) => {
|
|
414
425
|
return streamSSE(c, async (stream) => {
|
|
415
|
-
let cleanup;
|
|
416
426
|
let aborted = false;
|
|
417
427
|
stream.onAbort(() => {
|
|
418
428
|
aborted = true;
|
|
419
429
|
if (cleanup) cleanup();
|
|
420
430
|
});
|
|
421
|
-
cleanup = logInterceptor.addListener((entry) => {
|
|
431
|
+
const cleanup = logInterceptor.addListener((entry) => {
|
|
422
432
|
if (!aborted) {
|
|
423
|
-
stream.writeSSE({
|
|
433
|
+
void stream.writeSSE({
|
|
424
434
|
data: JSON.stringify(entry),
|
|
425
435
|
event: "log"
|
|
426
436
|
});
|
|
@@ -716,6 +726,52 @@ function createPluginsRoutes(deps) {
|
|
|
716
726
|
const data = deps.marketplace ? deps.marketplace.modules.filter((m) => deps.toolRegistry.isPluginModule(m.name)).map((m) => ({ name: m.name, version: m.version ?? "0.0.0" })) : deps.plugins;
|
|
717
727
|
return c.json({ success: true, data });
|
|
718
728
|
});
|
|
729
|
+
app.get("/priorities", (c) => {
|
|
730
|
+
try {
|
|
731
|
+
const priorities = getPluginPriorities(deps.memory.db);
|
|
732
|
+
const data = {};
|
|
733
|
+
for (const [name, priority] of priorities) {
|
|
734
|
+
data[name] = priority;
|
|
735
|
+
}
|
|
736
|
+
return c.json({ success: true, data });
|
|
737
|
+
} catch (err) {
|
|
738
|
+
return c.json({ success: false, error: getErrorMessage(err) }, 500);
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
app.post("/priorities", async (c) => {
|
|
742
|
+
try {
|
|
743
|
+
const body = await c.req.json();
|
|
744
|
+
const { pluginName, priority } = body;
|
|
745
|
+
if (!pluginName || typeof pluginName !== "string") {
|
|
746
|
+
return c.json({ success: false, error: "pluginName is required" }, 400);
|
|
747
|
+
}
|
|
748
|
+
if (typeof priority !== "number" || !Number.isInteger(priority)) {
|
|
749
|
+
return c.json({ success: false, error: "priority must be an integer" }, 400);
|
|
750
|
+
}
|
|
751
|
+
if (priority < -1e3 || priority > 1e3) {
|
|
752
|
+
return c.json(
|
|
753
|
+
{ success: false, error: "priority must be between -1000 and 1000" },
|
|
754
|
+
400
|
|
755
|
+
);
|
|
756
|
+
}
|
|
757
|
+
setPluginPriority(deps.memory.db, pluginName, priority);
|
|
758
|
+
return c.json({
|
|
759
|
+
success: true,
|
|
760
|
+
data: { pluginName, priority }
|
|
761
|
+
});
|
|
762
|
+
} catch (err) {
|
|
763
|
+
return c.json({ success: false, error: getErrorMessage(err) }, 500);
|
|
764
|
+
}
|
|
765
|
+
});
|
|
766
|
+
app.delete("/priorities/:name", (c) => {
|
|
767
|
+
try {
|
|
768
|
+
const name = c.req.param("name");
|
|
769
|
+
resetPluginPriority(deps.memory.db, name);
|
|
770
|
+
return c.json({ success: true, data: null });
|
|
771
|
+
} catch (err) {
|
|
772
|
+
return c.json({ success: false, error: getErrorMessage(err) }, 500);
|
|
773
|
+
}
|
|
774
|
+
});
|
|
719
775
|
return app;
|
|
720
776
|
}
|
|
721
777
|
|
|
@@ -781,7 +837,7 @@ function createMcpRoutes(deps) {
|
|
|
781
837
|
entry.url = body.url;
|
|
782
838
|
} else {
|
|
783
839
|
entry.command = "npx";
|
|
784
|
-
entry.args = ["-y", body.package, ...body.args || []];
|
|
840
|
+
entry.args = ["-y", body.package ?? "", ...body.args || []];
|
|
785
841
|
}
|
|
786
842
|
if (body.scope && body.scope !== "always") entry.scope = body.scope;
|
|
787
843
|
if (body.env && Object.keys(body.env).length > 0) entry.env = body.env;
|
|
@@ -832,7 +888,7 @@ function createMcpRoutes(deps) {
|
|
|
832
888
|
return app;
|
|
833
889
|
}
|
|
834
890
|
function deriveServerName(pkg) {
|
|
835
|
-
const unscoped = pkg.includes("/") ? pkg.split("/").pop() : pkg;
|
|
891
|
+
const unscoped = pkg.includes("/") ? pkg.split("/").pop() ?? pkg : pkg;
|
|
836
892
|
return unscoped.replace(/^server-/, "").replace(/^mcp-server-/, "").replace(/^mcp-/, "");
|
|
837
893
|
}
|
|
838
894
|
|
|
@@ -849,6 +905,8 @@ import {
|
|
|
849
905
|
existsSync
|
|
850
906
|
} from "fs";
|
|
851
907
|
import { join as join2, relative } from "path";
|
|
908
|
+
var MAX_SCAN_DEPTH = 10;
|
|
909
|
+
var MAX_SCAN_ENTRIES = 5e3;
|
|
852
910
|
function errorResponse(c, error, status = 500) {
|
|
853
911
|
const message = getErrorMessage(error);
|
|
854
912
|
const code = error instanceof WorkspaceSecurityError ? 403 : status;
|
|
@@ -865,35 +923,46 @@ var IMAGE_MIME_TYPES = {
|
|
|
865
923
|
".bmp": "image/bmp",
|
|
866
924
|
".ico": "image/x-icon"
|
|
867
925
|
};
|
|
868
|
-
function getWorkspaceStats(dir) {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
926
|
+
function getWorkspaceStats(dir, depth = 0, state = { files: 0, size: 0, truncated: false }) {
|
|
927
|
+
if (!existsSync(dir)) return state;
|
|
928
|
+
if (depth >= MAX_SCAN_DEPTH || state.files >= MAX_SCAN_ENTRIES) {
|
|
929
|
+
state.truncated = true;
|
|
930
|
+
return state;
|
|
931
|
+
}
|
|
872
932
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
933
|
+
if (state.files >= MAX_SCAN_ENTRIES) {
|
|
934
|
+
state.truncated = true;
|
|
935
|
+
return state;
|
|
936
|
+
}
|
|
873
937
|
const fullPath = join2(dir, entry.name);
|
|
874
938
|
if (entry.isDirectory()) {
|
|
875
|
-
|
|
876
|
-
files += sub.files;
|
|
877
|
-
size += sub.size;
|
|
939
|
+
getWorkspaceStats(fullPath, depth + 1, state);
|
|
878
940
|
} else if (entry.isFile()) {
|
|
879
|
-
files++;
|
|
941
|
+
state.files++;
|
|
880
942
|
try {
|
|
881
|
-
size += statSync(fullPath).size;
|
|
943
|
+
state.size += statSync(fullPath).size;
|
|
882
944
|
} catch {
|
|
883
945
|
}
|
|
884
946
|
}
|
|
885
947
|
}
|
|
886
|
-
return
|
|
948
|
+
return state;
|
|
887
949
|
}
|
|
888
|
-
function listDir(absPath, recursive) {
|
|
889
|
-
if (!existsSync(absPath)) return
|
|
890
|
-
|
|
950
|
+
function listDir(absPath, recursive, depth = 0, state = { entries: [], truncated: false }) {
|
|
951
|
+
if (!existsSync(absPath)) return state;
|
|
952
|
+
if (depth >= MAX_SCAN_DEPTH || state.entries.length >= MAX_SCAN_ENTRIES) {
|
|
953
|
+
state.truncated = true;
|
|
954
|
+
return state;
|
|
955
|
+
}
|
|
891
956
|
for (const entry of readdirSync(absPath, { withFileTypes: true })) {
|
|
957
|
+
if (state.entries.length >= MAX_SCAN_ENTRIES) {
|
|
958
|
+
state.truncated = true;
|
|
959
|
+
return state;
|
|
960
|
+
}
|
|
892
961
|
const fullPath = join2(absPath, entry.name);
|
|
893
962
|
const relPath = relative(WORKSPACE_ROOT, fullPath);
|
|
894
963
|
try {
|
|
895
964
|
const stats = statSync(fullPath);
|
|
896
|
-
entries.push({
|
|
965
|
+
state.entries.push({
|
|
897
966
|
name: entry.name,
|
|
898
967
|
path: relPath,
|
|
899
968
|
isDirectory: entry.isDirectory(),
|
|
@@ -901,12 +970,12 @@ function listDir(absPath, recursive) {
|
|
|
901
970
|
mtime: stats.mtime.toISOString()
|
|
902
971
|
});
|
|
903
972
|
if (recursive && entry.isDirectory()) {
|
|
904
|
-
|
|
973
|
+
listDir(fullPath, true, depth + 1, state);
|
|
905
974
|
}
|
|
906
975
|
} catch {
|
|
907
976
|
}
|
|
908
977
|
}
|
|
909
|
-
return
|
|
978
|
+
return state;
|
|
910
979
|
}
|
|
911
980
|
function createWorkspaceRoutes(_deps) {
|
|
912
981
|
const app = new Hono8();
|
|
@@ -926,12 +995,18 @@ function createWorkspaceRoutes(_deps) {
|
|
|
926
995
|
const response2 = { success: true, data: [] };
|
|
927
996
|
return c.json(response2);
|
|
928
997
|
}
|
|
929
|
-
const
|
|
930
|
-
entries.sort((a, b) => {
|
|
998
|
+
const result = listDir(validated.absolutePath, recursive);
|
|
999
|
+
result.entries.sort((a, b) => {
|
|
931
1000
|
if (a.isDirectory !== b.isDirectory) return a.isDirectory ? -1 : 1;
|
|
932
1001
|
return a.name.localeCompare(b.name);
|
|
933
1002
|
});
|
|
934
|
-
const response = {
|
|
1003
|
+
const response = {
|
|
1004
|
+
success: true,
|
|
1005
|
+
data: {
|
|
1006
|
+
entries: result.entries,
|
|
1007
|
+
...result.truncated && { truncated: true }
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
935
1010
|
return c.json(response);
|
|
936
1011
|
} catch (error) {
|
|
937
1012
|
return errorResponse(c, error);
|
|
@@ -1100,7 +1175,8 @@ function createWorkspaceRoutes(_deps) {
|
|
|
1100
1175
|
data: {
|
|
1101
1176
|
root: WORKSPACE_ROOT,
|
|
1102
1177
|
totalFiles: stats.files,
|
|
1103
|
-
totalSize: stats.size
|
|
1178
|
+
totalSize: stats.size,
|
|
1179
|
+
...stats.truncated && { truncated: true }
|
|
1104
1180
|
}
|
|
1105
1181
|
};
|
|
1106
1182
|
return c.json(response);
|
|
@@ -1657,7 +1733,7 @@ var MarketplaceService = class {
|
|
|
1657
1733
|
const registry = await this.getRegistry();
|
|
1658
1734
|
const entry = registry.find((e) => e.id === pluginId);
|
|
1659
1735
|
if (!entry) throw new Error(`Plugin "${pluginId}" not found in registry`);
|
|
1660
|
-
const
|
|
1736
|
+
const _manifest = await this.fetchRemoteManifest(entry);
|
|
1661
1737
|
mkdirSync2(pluginDir, { recursive: true });
|
|
1662
1738
|
await this.downloadDir(entry.path, pluginDir);
|
|
1663
1739
|
await ensurePluginDeps(pluginDir, pluginId);
|
|
@@ -1833,7 +1909,7 @@ function createMarketplaceRoutes(deps) {
|
|
|
1833
1909
|
const result = await svc.installPlugin(body.id);
|
|
1834
1910
|
deps.plugins.length = 0;
|
|
1835
1911
|
deps.plugins.push(
|
|
1836
|
-
...deps.marketplace
|
|
1912
|
+
...(deps.marketplace?.modules ?? []).filter((m) => deps.toolRegistry.isPluginModule(m.name)).map((m) => ({ name: m.name, version: m.version ?? "0.0.0" }))
|
|
1837
1913
|
);
|
|
1838
1914
|
return c.json({ success: true, data: result });
|
|
1839
1915
|
} catch (err) {
|
|
@@ -1857,7 +1933,7 @@ function createMarketplaceRoutes(deps) {
|
|
|
1857
1933
|
const result = await svc.uninstallPlugin(body.id);
|
|
1858
1934
|
deps.plugins.length = 0;
|
|
1859
1935
|
deps.plugins.push(
|
|
1860
|
-
...deps.marketplace
|
|
1936
|
+
...(deps.marketplace?.modules ?? []).filter((m) => deps.toolRegistry.isPluginModule(m.name)).map((m) => ({ name: m.name, version: m.version ?? "0.0.0" }))
|
|
1861
1937
|
);
|
|
1862
1938
|
return c.json({ success: true, data: result });
|
|
1863
1939
|
} catch (err) {
|
|
@@ -1881,7 +1957,7 @@ function createMarketplaceRoutes(deps) {
|
|
|
1881
1957
|
const result = await svc.updatePlugin(body.id);
|
|
1882
1958
|
deps.plugins.length = 0;
|
|
1883
1959
|
deps.plugins.push(
|
|
1884
|
-
...deps.marketplace
|
|
1960
|
+
...(deps.marketplace?.modules ?? []).filter((m) => deps.toolRegistry.isPluginModule(m.name)).map((m) => ({ name: m.name, version: m.version ?? "0.0.0" }))
|
|
1885
1961
|
);
|
|
1886
1962
|
return c.json({ success: true, data: result });
|
|
1887
1963
|
} catch (err) {
|
|
@@ -1971,8 +2047,271 @@ function createMarketplaceRoutes(deps) {
|
|
|
1971
2047
|
return app;
|
|
1972
2048
|
}
|
|
1973
2049
|
|
|
2050
|
+
// src/webui/routes/hooks.ts
|
|
2051
|
+
import { Hono as Hono12 } from "hono";
|
|
2052
|
+
import { randomUUID } from "crypto";
|
|
2053
|
+
function createHooksRoutes(deps) {
|
|
2054
|
+
const app = new Hono12();
|
|
2055
|
+
app.get("/blocklist", (c) => {
|
|
2056
|
+
try {
|
|
2057
|
+
const data = getBlocklistConfig(deps.memory.db);
|
|
2058
|
+
return c.json({ success: true, data });
|
|
2059
|
+
} catch (err) {
|
|
2060
|
+
return c.json({ success: false, error: getErrorMessage(err) }, 500);
|
|
2061
|
+
}
|
|
2062
|
+
});
|
|
2063
|
+
app.put("/blocklist", async (c) => {
|
|
2064
|
+
try {
|
|
2065
|
+
const body = await c.req.json();
|
|
2066
|
+
if (typeof body.enabled !== "boolean") {
|
|
2067
|
+
return c.json({ success: false, error: "enabled must be a boolean" }, 400);
|
|
2068
|
+
}
|
|
2069
|
+
if (!Array.isArray(body.keywords)) {
|
|
2070
|
+
return c.json({ success: false, error: "keywords must be an array" }, 400);
|
|
2071
|
+
}
|
|
2072
|
+
if (body.keywords.length > 200) {
|
|
2073
|
+
return c.json({ success: false, error: "Maximum 200 keywords" }, 400);
|
|
2074
|
+
}
|
|
2075
|
+
const keywords = body.keywords.map((k) => typeof k === "string" ? k.trim() : "").filter((k) => k.length >= 2);
|
|
2076
|
+
const message = typeof body.message === "string" ? body.message.slice(0, 500) : "";
|
|
2077
|
+
const config = {
|
|
2078
|
+
enabled: body.enabled,
|
|
2079
|
+
keywords,
|
|
2080
|
+
message
|
|
2081
|
+
};
|
|
2082
|
+
setBlocklistConfig(deps.memory.db, config);
|
|
2083
|
+
deps.userHookEvaluator?.reload();
|
|
2084
|
+
return c.json({ success: true, data: config });
|
|
2085
|
+
} catch (err) {
|
|
2086
|
+
return c.json({ success: false, error: getErrorMessage(err) }, 500);
|
|
2087
|
+
}
|
|
2088
|
+
});
|
|
2089
|
+
app.get("/triggers", (c) => {
|
|
2090
|
+
try {
|
|
2091
|
+
const data = getTriggersConfig(deps.memory.db);
|
|
2092
|
+
return c.json({ success: true, data });
|
|
2093
|
+
} catch (err) {
|
|
2094
|
+
return c.json({ success: false, error: getErrorMessage(err) }, 500);
|
|
2095
|
+
}
|
|
2096
|
+
});
|
|
2097
|
+
app.post("/triggers", async (c) => {
|
|
2098
|
+
try {
|
|
2099
|
+
const body = await c.req.json();
|
|
2100
|
+
const keyword = typeof body.keyword === "string" ? body.keyword.trim() : "";
|
|
2101
|
+
const context = typeof body.context === "string" ? body.context.trim() : "";
|
|
2102
|
+
if (keyword.length < 2 || keyword.length > 100) {
|
|
2103
|
+
return c.json(
|
|
2104
|
+
{ success: false, error: "keyword must be 2-100 characters" },
|
|
2105
|
+
400
|
|
2106
|
+
);
|
|
2107
|
+
}
|
|
2108
|
+
if (context.length < 1 || context.length > 2e3) {
|
|
2109
|
+
return c.json(
|
|
2110
|
+
{ success: false, error: "context must be 1-2000 characters" },
|
|
2111
|
+
400
|
|
2112
|
+
);
|
|
2113
|
+
}
|
|
2114
|
+
const triggers = getTriggersConfig(deps.memory.db);
|
|
2115
|
+
if (triggers.length >= 50) {
|
|
2116
|
+
return c.json({ success: false, error: "Maximum 50 triggers" }, 400);
|
|
2117
|
+
}
|
|
2118
|
+
const entry = {
|
|
2119
|
+
id: randomUUID(),
|
|
2120
|
+
keyword,
|
|
2121
|
+
context,
|
|
2122
|
+
enabled: body.enabled !== false
|
|
2123
|
+
};
|
|
2124
|
+
triggers.push(entry);
|
|
2125
|
+
setTriggersConfig(deps.memory.db, triggers);
|
|
2126
|
+
deps.userHookEvaluator?.reload();
|
|
2127
|
+
return c.json({ success: true, data: entry });
|
|
2128
|
+
} catch (err) {
|
|
2129
|
+
return c.json({ success: false, error: getErrorMessage(err) }, 500);
|
|
2130
|
+
}
|
|
2131
|
+
});
|
|
2132
|
+
app.put("/triggers/:id", async (c) => {
|
|
2133
|
+
try {
|
|
2134
|
+
const id = c.req.param("id");
|
|
2135
|
+
const body = await c.req.json();
|
|
2136
|
+
const triggers = getTriggersConfig(deps.memory.db);
|
|
2137
|
+
const idx = triggers.findIndex((t) => t.id === id);
|
|
2138
|
+
if (idx === -1) {
|
|
2139
|
+
return c.json({ success: false, error: "Trigger not found" }, 404);
|
|
2140
|
+
}
|
|
2141
|
+
if (typeof body.keyword === "string") {
|
|
2142
|
+
const kw = body.keyword.trim();
|
|
2143
|
+
if (kw.length < 2 || kw.length > 100) {
|
|
2144
|
+
return c.json(
|
|
2145
|
+
{ success: false, error: "keyword must be 2-100 characters" },
|
|
2146
|
+
400
|
|
2147
|
+
);
|
|
2148
|
+
}
|
|
2149
|
+
triggers[idx].keyword = kw;
|
|
2150
|
+
}
|
|
2151
|
+
if (typeof body.context === "string") {
|
|
2152
|
+
const ctx = body.context.trim();
|
|
2153
|
+
if (ctx.length < 1 || ctx.length > 2e3) {
|
|
2154
|
+
return c.json(
|
|
2155
|
+
{ success: false, error: "context must be 1-2000 characters" },
|
|
2156
|
+
400
|
|
2157
|
+
);
|
|
2158
|
+
}
|
|
2159
|
+
triggers[idx].context = ctx;
|
|
2160
|
+
}
|
|
2161
|
+
if (typeof body.enabled === "boolean") {
|
|
2162
|
+
triggers[idx].enabled = body.enabled;
|
|
2163
|
+
}
|
|
2164
|
+
setTriggersConfig(deps.memory.db, triggers);
|
|
2165
|
+
deps.userHookEvaluator?.reload();
|
|
2166
|
+
return c.json({ success: true, data: triggers[idx] });
|
|
2167
|
+
} catch (err) {
|
|
2168
|
+
return c.json({ success: false, error: getErrorMessage(err) }, 500);
|
|
2169
|
+
}
|
|
2170
|
+
});
|
|
2171
|
+
app.delete("/triggers/:id", (c) => {
|
|
2172
|
+
try {
|
|
2173
|
+
const id = c.req.param("id");
|
|
2174
|
+
const triggers = getTriggersConfig(deps.memory.db);
|
|
2175
|
+
const filtered = triggers.filter((t) => t.id !== id);
|
|
2176
|
+
setTriggersConfig(deps.memory.db, filtered);
|
|
2177
|
+
deps.userHookEvaluator?.reload();
|
|
2178
|
+
return c.json({ success: true, data: null });
|
|
2179
|
+
} catch (err) {
|
|
2180
|
+
return c.json({ success: false, error: getErrorMessage(err) }, 500);
|
|
2181
|
+
}
|
|
2182
|
+
});
|
|
2183
|
+
app.patch("/triggers/:id/toggle", async (c) => {
|
|
2184
|
+
try {
|
|
2185
|
+
const id = c.req.param("id");
|
|
2186
|
+
const body = await c.req.json();
|
|
2187
|
+
if (typeof body.enabled !== "boolean") {
|
|
2188
|
+
return c.json({ success: false, error: "enabled must be a boolean" }, 400);
|
|
2189
|
+
}
|
|
2190
|
+
const triggers = getTriggersConfig(deps.memory.db);
|
|
2191
|
+
const trigger = triggers.find((t) => t.id === id);
|
|
2192
|
+
if (!trigger) {
|
|
2193
|
+
return c.json({ success: false, error: "Trigger not found" }, 404);
|
|
2194
|
+
}
|
|
2195
|
+
trigger.enabled = body.enabled;
|
|
2196
|
+
setTriggersConfig(deps.memory.db, triggers);
|
|
2197
|
+
deps.userHookEvaluator?.reload();
|
|
2198
|
+
return c.json({
|
|
2199
|
+
success: true,
|
|
2200
|
+
data: { id, enabled: body.enabled }
|
|
2201
|
+
});
|
|
2202
|
+
} catch (err) {
|
|
2203
|
+
return c.json({ success: false, error: getErrorMessage(err) }, 500);
|
|
2204
|
+
}
|
|
2205
|
+
});
|
|
2206
|
+
return app;
|
|
2207
|
+
}
|
|
2208
|
+
|
|
2209
|
+
// src/webui/routes/ton-proxy.ts
|
|
2210
|
+
import { Hono as Hono13 } from "hono";
|
|
2211
|
+
var log2 = createLogger("TonProxyRoute");
|
|
2212
|
+
function createTonProxyRoutes(deps) {
|
|
2213
|
+
const app = new Hono13();
|
|
2214
|
+
app.get("/", (c) => {
|
|
2215
|
+
const mgr = getTonProxyManager();
|
|
2216
|
+
if (!mgr) {
|
|
2217
|
+
return c.json({
|
|
2218
|
+
success: true,
|
|
2219
|
+
data: { running: false, installed: false, port: 8080, enabled: false }
|
|
2220
|
+
});
|
|
2221
|
+
}
|
|
2222
|
+
return c.json({
|
|
2223
|
+
success: true,
|
|
2224
|
+
data: { ...mgr.getStatus(), enabled: true }
|
|
2225
|
+
});
|
|
2226
|
+
});
|
|
2227
|
+
app.post("/start", async (c) => {
|
|
2228
|
+
try {
|
|
2229
|
+
const runtimeConfig = deps.agent.getConfig();
|
|
2230
|
+
const port = runtimeConfig.ton_proxy?.port ?? 8080;
|
|
2231
|
+
const binaryPath = runtimeConfig.ton_proxy?.binary_path;
|
|
2232
|
+
const existing = getTonProxyManager();
|
|
2233
|
+
if (existing?.isRunning()) await existing.stop();
|
|
2234
|
+
const mgr = new TonProxyManager({ enabled: true, port, binary_path: binaryPath });
|
|
2235
|
+
setTonProxyManager(mgr);
|
|
2236
|
+
await mgr.start();
|
|
2237
|
+
const raw = readRawConfig(deps.configPath);
|
|
2238
|
+
setNestedValue(raw, "ton_proxy.enabled", true);
|
|
2239
|
+
writeRawConfig(raw, deps.configPath);
|
|
2240
|
+
setNestedValue(runtimeConfig, "ton_proxy.enabled", true);
|
|
2241
|
+
log2.info(`TON Proxy started on port ${port} (WebUI)`);
|
|
2242
|
+
return c.json({
|
|
2243
|
+
success: true,
|
|
2244
|
+
data: { ...mgr.getStatus(), enabled: true }
|
|
2245
|
+
});
|
|
2246
|
+
} catch (err) {
|
|
2247
|
+
log2.error({ err }, "Failed to start TON Proxy");
|
|
2248
|
+
return c.json(
|
|
2249
|
+
{ success: false, error: err instanceof Error ? err.message : String(err) },
|
|
2250
|
+
500
|
|
2251
|
+
);
|
|
2252
|
+
}
|
|
2253
|
+
});
|
|
2254
|
+
app.post("/stop", async (c) => {
|
|
2255
|
+
try {
|
|
2256
|
+
const mgr = getTonProxyManager();
|
|
2257
|
+
if (mgr) {
|
|
2258
|
+
await mgr.stop();
|
|
2259
|
+
setTonProxyManager(null);
|
|
2260
|
+
}
|
|
2261
|
+
const runtimeConfig = deps.agent.getConfig();
|
|
2262
|
+
const raw = readRawConfig(deps.configPath);
|
|
2263
|
+
setNestedValue(raw, "ton_proxy.enabled", false);
|
|
2264
|
+
writeRawConfig(raw, deps.configPath);
|
|
2265
|
+
setNestedValue(runtimeConfig, "ton_proxy.enabled", false);
|
|
2266
|
+
log2.info("TON Proxy stopped (WebUI)");
|
|
2267
|
+
return c.json({
|
|
2268
|
+
success: true,
|
|
2269
|
+
data: { running: false, installed: true, port: 8080, enabled: false }
|
|
2270
|
+
});
|
|
2271
|
+
} catch (err) {
|
|
2272
|
+
log2.error({ err }, "Failed to stop TON Proxy");
|
|
2273
|
+
return c.json(
|
|
2274
|
+
{ success: false, error: err instanceof Error ? err.message : String(err) },
|
|
2275
|
+
500
|
|
2276
|
+
);
|
|
2277
|
+
}
|
|
2278
|
+
});
|
|
2279
|
+
app.post("/uninstall", async (c) => {
|
|
2280
|
+
try {
|
|
2281
|
+
const mgr = getTonProxyManager();
|
|
2282
|
+
if (mgr) {
|
|
2283
|
+
await mgr.uninstall();
|
|
2284
|
+
setTonProxyManager(null);
|
|
2285
|
+
} else {
|
|
2286
|
+
const runtimeConfig2 = deps.agent.getConfig();
|
|
2287
|
+
const port = runtimeConfig2.ton_proxy?.port ?? 8080;
|
|
2288
|
+
const binaryPath = runtimeConfig2.ton_proxy?.binary_path;
|
|
2289
|
+
const tmp = new TonProxyManager({ enabled: false, port, binary_path: binaryPath });
|
|
2290
|
+
await tmp.uninstall();
|
|
2291
|
+
}
|
|
2292
|
+
const runtimeConfig = deps.agent.getConfig();
|
|
2293
|
+
const raw = readRawConfig(deps.configPath);
|
|
2294
|
+
setNestedValue(raw, "ton_proxy.enabled", false);
|
|
2295
|
+
writeRawConfig(raw, deps.configPath);
|
|
2296
|
+
setNestedValue(runtimeConfig, "ton_proxy.enabled", false);
|
|
2297
|
+
log2.info("TON Proxy uninstalled (WebUI)");
|
|
2298
|
+
return c.json({
|
|
2299
|
+
success: true,
|
|
2300
|
+
data: { running: false, installed: false, port: 8080, enabled: false }
|
|
2301
|
+
});
|
|
2302
|
+
} catch (err) {
|
|
2303
|
+
log2.error({ err }, "Failed to uninstall TON Proxy");
|
|
2304
|
+
return c.json(
|
|
2305
|
+
{ success: false, error: err instanceof Error ? err.message : String(err) },
|
|
2306
|
+
500
|
|
2307
|
+
);
|
|
2308
|
+
}
|
|
2309
|
+
});
|
|
2310
|
+
return app;
|
|
2311
|
+
}
|
|
2312
|
+
|
|
1974
2313
|
// src/webui/server.ts
|
|
1975
|
-
var
|
|
2314
|
+
var log3 = createLogger("WebUI");
|
|
1976
2315
|
function findWebDist() {
|
|
1977
2316
|
const candidates = [
|
|
1978
2317
|
resolve2("dist/web"),
|
|
@@ -2001,12 +2340,13 @@ var WebUIServer = class {
|
|
|
2001
2340
|
authToken;
|
|
2002
2341
|
constructor(deps) {
|
|
2003
2342
|
this.deps = deps;
|
|
2004
|
-
this.app = new
|
|
2343
|
+
this.app = new Hono14();
|
|
2005
2344
|
this.authToken = deps.config.auth_token || generateToken();
|
|
2006
2345
|
this.setupMiddleware();
|
|
2007
2346
|
this.setupRoutes();
|
|
2008
2347
|
}
|
|
2009
2348
|
/** Set an HttpOnly session cookie */
|
|
2349
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Hono context type
|
|
2010
2350
|
setSessionCookie(c) {
|
|
2011
2351
|
setCookie(c, COOKIE_NAME, this.authToken, {
|
|
2012
2352
|
path: "/",
|
|
@@ -2033,7 +2373,7 @@ var WebUIServer = class {
|
|
|
2033
2373
|
const start = Date.now();
|
|
2034
2374
|
await next();
|
|
2035
2375
|
const duration = Date.now() - start;
|
|
2036
|
-
|
|
2376
|
+
log3.info(`${c.req.method} ${c.req.path} \u2192 ${c.res.status} (${duration}ms)`);
|
|
2037
2377
|
});
|
|
2038
2378
|
}
|
|
2039
2379
|
this.app.use(
|
|
@@ -2111,6 +2451,8 @@ var WebUIServer = class {
|
|
|
2111
2451
|
this.app.route("/api/tasks", createTasksRoutes(this.deps));
|
|
2112
2452
|
this.app.route("/api/config", createConfigRoutes(this.deps));
|
|
2113
2453
|
this.app.route("/api/marketplace", createMarketplaceRoutes(this.deps));
|
|
2454
|
+
this.app.route("/api/hooks", createHooksRoutes(this.deps));
|
|
2455
|
+
this.app.route("/api/ton-proxy", createTonProxyRoutes(this.deps));
|
|
2114
2456
|
this.app.post("/api/agent/start", async (c) => {
|
|
2115
2457
|
const lifecycle = this.deps.lifecycle;
|
|
2116
2458
|
if (!lifecycle) {
|
|
@@ -2124,7 +2466,7 @@ var WebUIServer = class {
|
|
|
2124
2466
|
return c.json({ error: "Agent is currently stopping, please wait" }, 409);
|
|
2125
2467
|
}
|
|
2126
2468
|
lifecycle.start().catch((err) => {
|
|
2127
|
-
|
|
2469
|
+
log3.error({ err }, "Agent start failed");
|
|
2128
2470
|
});
|
|
2129
2471
|
return c.json({ state: "starting" });
|
|
2130
2472
|
});
|
|
@@ -2141,7 +2483,7 @@ var WebUIServer = class {
|
|
|
2141
2483
|
return c.json({ error: "Agent is currently starting, please wait" }, 409);
|
|
2142
2484
|
}
|
|
2143
2485
|
lifecycle.stop().catch((err) => {
|
|
2144
|
-
|
|
2486
|
+
log3.error({ err }, "Agent stop failed");
|
|
2145
2487
|
});
|
|
2146
2488
|
return c.json({ state: "stopping" });
|
|
2147
2489
|
});
|
|
@@ -2179,7 +2521,7 @@ var WebUIServer = class {
|
|
|
2179
2521
|
});
|
|
2180
2522
|
const onStateChange = (event) => {
|
|
2181
2523
|
if (aborted) return;
|
|
2182
|
-
stream.writeSSE({
|
|
2524
|
+
void stream.writeSSE({
|
|
2183
2525
|
event: "status",
|
|
2184
2526
|
id: String(event.timestamp),
|
|
2185
2527
|
data: JSON.stringify({
|
|
@@ -2238,7 +2580,7 @@ var WebUIServer = class {
|
|
|
2238
2580
|
});
|
|
2239
2581
|
}
|
|
2240
2582
|
this.app.onError((err, c) => {
|
|
2241
|
-
|
|
2583
|
+
log3.error({ err }, "WebUI error");
|
|
2242
2584
|
return c.json(
|
|
2243
2585
|
{
|
|
2244
2586
|
success: false,
|
|
@@ -2260,9 +2602,9 @@ var WebUIServer = class {
|
|
|
2260
2602
|
},
|
|
2261
2603
|
(info) => {
|
|
2262
2604
|
const url = `http://${info.address}:${info.port}`;
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2605
|
+
log3.info(`WebUI server running`);
|
|
2606
|
+
log3.info(`URL: ${url}/auth/exchange?token=${this.authToken}`);
|
|
2607
|
+
log3.info(`Token: ${maskToken(this.authToken)} (use Bearer header for API access)`);
|
|
2266
2608
|
resolve3();
|
|
2267
2609
|
}
|
|
2268
2610
|
);
|
|
@@ -2275,9 +2617,9 @@ var WebUIServer = class {
|
|
|
2275
2617
|
async stop() {
|
|
2276
2618
|
if (this.server) {
|
|
2277
2619
|
return new Promise((resolve3) => {
|
|
2278
|
-
this.server
|
|
2620
|
+
this.server?.close(() => {
|
|
2279
2621
|
logInterceptor.uninstall();
|
|
2280
|
-
|
|
2622
|
+
log3.info("WebUI server stopped");
|
|
2281
2623
|
resolve3();
|
|
2282
2624
|
});
|
|
2283
2625
|
});
|