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.
Files changed (43) hide show
  1. package/README.md +35 -15
  2. package/dist/chunk-3RG5ZIWI.js +10 -0
  3. package/dist/{chunk-LCCVZ4D2.js → chunk-3S4GGLLR.js} +28 -26
  4. package/dist/{chunk-NUGDTPE4.js → chunk-4L66JHQE.js} +2 -1
  5. package/dist/{chunk-OGMVWDVU.js → chunk-5FNWBZ5K.js} +1826 -4992
  6. package/dist/{chunk-U7FQYCBQ.js → chunk-7TECSLJ4.js} +2 -2
  7. package/dist/{chunk-2GLHOJ5C.js → chunk-7U7BOHCL.js} +103 -36
  8. package/dist/{chunk-DMXTIRUW.js → chunk-AYWEJCDB.js} +20 -39
  9. package/dist/chunk-CGOXE4WP.js +11315 -0
  10. package/dist/{chunk-5UVXJMOX.js → chunk-KVXV7EF7.js} +4 -4
  11. package/dist/{chunk-QOQWUUA4.js → chunk-OJCLKU5Z.js} +68 -2
  12. package/dist/{chunk-CB2Y45HA.js → chunk-PHSAHTK4.js} +51 -3
  13. package/dist/{chunk-WIKM24GZ.js → chunk-QBHRXLZS.js} +5 -0
  14. package/dist/{chunk-OCLG5GKI.js → chunk-QV2GLOTK.js} +14 -3
  15. package/dist/{chunk-AVDWXYQ7.js → chunk-S6PHGKOC.js} +12 -1
  16. package/dist/{chunk-YP25WTQK.js → chunk-UP55PXFH.js} +6 -0
  17. package/dist/cli/index.js +21 -21
  18. package/dist/{client-O37XDCJB.js → client-MPHPIZB6.js} +4 -4
  19. package/dist/{get-my-gifts-TPVUGUWT.js → get-my-gifts-CC6HAVWB.js} +2 -2
  20. package/dist/index.js +14 -15
  21. package/dist/{memory-KQALFUV3.js → memory-UBHM7ILG.js} +5 -5
  22. package/dist/{migrate-UV3WEL5D.js → migrate-UBBEJ5BL.js} +5 -5
  23. package/dist/{multipart-parser-S3YC6NRJ.js → multipart-parser-UFQLJOV2.js} +2 -2
  24. package/dist/{paths-TMNTEDDD.js → paths-XA2RJH4S.js} +1 -1
  25. package/dist/{server-BHHJGUDF.js → server-3FHI2SEB.js} +398 -56
  26. package/dist/{setup-server-G7UG2DI3.js → setup-server-32XGDPE6.js} +161 -11
  27. package/dist/{store-H4XPNGC2.js → store-M5IMUQCL.js} +6 -6
  28. package/dist/{task-dependency-resolver-VMEVJRPO.js → task-dependency-resolver-RR2O5S7B.js} +3 -3
  29. package/dist/{task-executor-WWSPBJ4V.js → task-executor-6W5HRX5C.js} +3 -3
  30. package/dist/{tasks-QSCWSMPS.js → tasks-WQIKXDX5.js} +2 -2
  31. package/dist/{tool-adapter-Y3TCEQOC.js → tool-adapter-IH5VGBOO.js} +1 -1
  32. package/dist/{tool-index-2KH3OB6X.js → tool-index-PMAOXWUA.js} +9 -6
  33. package/dist/{transcript-UDJZP6NK.js → transcript-NGDPSNIH.js} +2 -2
  34. package/dist/web/assets/index-BfYCdwLI.js +80 -0
  35. package/dist/web/assets/{index-BrVqauzj.css → index-DmlyQVhR.css} +1 -1
  36. package/dist/web/assets/{index.es-Pet5-M13.js → index.es-DitvF-9H.js} +1 -1
  37. package/dist/web/index.html +2 -2
  38. package/package.json +12 -5
  39. package/dist/BigInteger-DQ33LTTE.js +0 -5
  40. package/dist/chunk-G2LLMJXJ.js +0 -5048
  41. package/dist/chunk-QGM4M3NI.js +0 -37
  42. package/dist/chunk-TSKJCWQQ.js +0 -1263
  43. package/dist/web/assets/index-Bx8JW3gV.js +0 -72
@@ -1,48 +1,58 @@
1
1
  import {
2
2
  getModelsForProvider
3
- } from "./chunk-QOQWUUA4.js";
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-G2LLMJXJ.js";
33
+ } from "./chunk-CGOXE4WP.js";
24
34
  import {
25
35
  invalidateEndpointCache,
26
36
  invalidateTonClientCache,
27
37
  setToncenterApiKey
28
- } from "./chunk-AVDWXYQ7.js";
29
- import "./chunk-5UVXJMOX.js";
30
- import "./chunk-TSKJCWQQ.js";
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-DMXTIRUW.js";
44
+ import "./chunk-AYWEJCDB.js";
35
45
  import {
36
46
  getProviderMetadata,
37
47
  validateApiKeyFormat
38
- } from "./chunk-CB2Y45HA.js";
39
- import "./chunk-OCLG5GKI.js";
40
- import "./chunk-2GLHOJ5C.js";
41
- import "./chunk-LCCVZ4D2.js";
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-YP25WTQK.js";
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-NUGDTPE4.js";
60
- import "./chunk-QGM4M3NI.js";
69
+ } from "./chunk-4L66JHQE.js";
70
+ import "./chunk-3RG5ZIWI.js";
61
71
 
62
72
  // src/webui/server.ts
63
- import { Hono as Hono12 } from "hono";
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
- let files = 0;
870
- let size = 0;
871
- if (!existsSync(dir)) return { files, size };
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
- const sub = getWorkspaceStats(fullPath);
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 { files, size };
948
+ return state;
887
949
  }
888
- function listDir(absPath, recursive) {
889
- if (!existsSync(absPath)) return [];
890
- const entries = [];
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
- entries.push(...listDir(fullPath, true));
973
+ listDir(fullPath, true, depth + 1, state);
905
974
  }
906
975
  } catch {
907
976
  }
908
977
  }
909
- return entries;
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 entries = listDir(validated.absolutePath, recursive);
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 = { success: true, data: entries };
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 manifest = await this.fetchRemoteManifest(entry);
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.modules.filter((m) => deps.toolRegistry.isPluginModule(m.name)).map((m) => ({ name: m.name, version: m.version ?? "0.0.0" }))
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.modules.filter((m) => deps.toolRegistry.isPluginModule(m.name)).map((m) => ({ name: m.name, version: m.version ?? "0.0.0" }))
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.modules.filter((m) => deps.toolRegistry.isPluginModule(m.name)).map((m) => ({ name: m.name, version: m.version ?? "0.0.0" }))
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 log2 = createLogger("WebUI");
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 Hono12();
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
- log2.info(`${c.req.method} ${c.req.path} \u2192 ${c.res.status} (${duration}ms)`);
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
- log2.error({ err }, "Agent start failed");
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
- log2.error({ err }, "Agent stop failed");
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
- log2.error({ err }, "WebUI error");
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
- log2.info(`WebUI server running`);
2264
- log2.info(`URL: ${url}/auth/exchange?token=${this.authToken}`);
2265
- log2.info(`Token: ${maskToken(this.authToken)} (use Bearer header for API access)`);
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.close(() => {
2620
+ this.server?.close(() => {
2279
2621
  logInterceptor.uninstall();
2280
- log2.info("WebUI server stopped");
2622
+ log3.info("WebUI server stopped");
2281
2623
  resolve3();
2282
2624
  });
2283
2625
  });