teleton 0.8.0 → 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 (32) hide show
  1. package/README.md +28 -11
  2. package/dist/{chunk-U56QTM46.js → chunk-3S4GGLLR.js} +28 -26
  3. package/dist/{chunk-NUGDTPE4.js → chunk-4L66JHQE.js} +2 -1
  4. package/dist/{chunk-H36RFKRI.js → chunk-5FNWBZ5K.js} +476 -143
  5. package/dist/{chunk-SD4NLLYG.js → chunk-7U7BOHCL.js} +80 -33
  6. package/dist/{chunk-QVBSUYVX.js → chunk-AYWEJCDB.js} +11 -3
  7. package/dist/{chunk-RQBAMUCV.js → chunk-CGOXE4WP.js} +1235 -201
  8. package/dist/{chunk-TVRZJIZX.js → chunk-KVXV7EF7.js} +3 -3
  9. package/dist/{chunk-WIKM24GZ.js → chunk-QBHRXLZS.js} +5 -0
  10. package/dist/{chunk-P36I6OIV.js → chunk-QV2GLOTK.js} +12 -1
  11. package/dist/{chunk-JHYZYFZJ.js → chunk-S6PHGKOC.js} +8 -1
  12. package/dist/{chunk-IJBWWQE4.js → chunk-UP55PXFH.js} +4 -0
  13. package/dist/cli/index.js +17 -16
  14. package/dist/{client-LNZTDQSA.js → client-MPHPIZB6.js} +2 -2
  15. package/dist/{get-my-gifts-OMGKOEPM.js → get-my-gifts-CC6HAVWB.js} +1 -1
  16. package/dist/index.js +11 -11
  17. package/dist/{memory-AS7WKGTW.js → memory-UBHM7ILG.js} +4 -4
  18. package/dist/{migrate-POHWYEIW.js → migrate-UBBEJ5BL.js} +4 -4
  19. package/dist/{server-H3QA252W.js → server-3FHI2SEB.js} +392 -51
  20. package/dist/{setup-server-QXED3D2L.js → setup-server-32XGDPE6.js} +157 -7
  21. package/dist/{store-GAFULOOX.js → store-M5IMUQCL.js} +5 -5
  22. package/dist/{task-dependency-resolver-3FIKQ7Z6.js → task-dependency-resolver-RR2O5S7B.js} +2 -2
  23. package/dist/{task-executor-RUTFG6VG.js → task-executor-6W5HRX5C.js} +2 -2
  24. package/dist/{tasks-BEZ4QRI2.js → tasks-WQIKXDX5.js} +1 -1
  25. package/dist/{tool-index-H3SHOJC3.js → tool-index-PMAOXWUA.js} +8 -5
  26. package/dist/{transcript-IMNE6KU3.js → transcript-NGDPSNIH.js} +1 -1
  27. package/dist/web/assets/index-BfYCdwLI.js +80 -0
  28. package/dist/web/assets/{index-BrVqauzj.css → index-DmlyQVhR.css} +1 -1
  29. package/dist/web/assets/{index.es-DkU1GvWU.js → index.es-DitvF-9H.js} +1 -1
  30. package/dist/web/index.html +2 -2
  31. package/package.json +11 -4
  32. package/dist/web/assets/index-DYeEkvJ6.js +0 -72
@@ -3,46 +3,56 @@ import {
3
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-RQBAMUCV.js";
33
+ } from "./chunk-CGOXE4WP.js";
24
34
  import {
25
35
  invalidateEndpointCache,
26
36
  invalidateTonClientCache,
27
37
  setToncenterApiKey
28
- } from "./chunk-JHYZYFZJ.js";
29
- import "./chunk-TVRZJIZX.js";
38
+ } from "./chunk-S6PHGKOC.js";
39
+ import "./chunk-KVXV7EF7.js";
30
40
  import "./chunk-7TECSLJ4.js";
31
41
  import {
32
42
  getErrorMessage
33
43
  } from "./chunk-XBE4JB7C.js";
34
- import "./chunk-QVBSUYVX.js";
44
+ import "./chunk-AYWEJCDB.js";
35
45
  import {
36
46
  getProviderMetadata,
37
47
  validateApiKeyFormat
38
48
  } from "./chunk-PHSAHTK4.js";
39
- import "./chunk-P36I6OIV.js";
40
- import "./chunk-SD4NLLYG.js";
41
- import "./chunk-U56QTM46.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-IJBWWQE4.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";
69
+ } from "./chunk-4L66JHQE.js";
60
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";
@@ -413,15 +423,14 @@ function createLogsRoutes(_deps) {
413
423
  const app = new Hono3();
414
424
  app.get("/stream", (c) => {
415
425
  return streamSSE(c, async (stream) => {
416
- let cleanup;
417
426
  let aborted = false;
418
427
  stream.onAbort(() => {
419
428
  aborted = true;
420
429
  if (cleanup) cleanup();
421
430
  });
422
- cleanup = logInterceptor.addListener((entry) => {
431
+ const cleanup = logInterceptor.addListener((entry) => {
423
432
  if (!aborted) {
424
- stream.writeSSE({
433
+ void stream.writeSSE({
425
434
  data: JSON.stringify(entry),
426
435
  event: "log"
427
436
  });
@@ -717,6 +726,52 @@ function createPluginsRoutes(deps) {
717
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;
718
727
  return c.json({ success: true, data });
719
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
+ });
720
775
  return app;
721
776
  }
722
777
 
@@ -782,7 +837,7 @@ function createMcpRoutes(deps) {
782
837
  entry.url = body.url;
783
838
  } else {
784
839
  entry.command = "npx";
785
- entry.args = ["-y", body.package, ...body.args || []];
840
+ entry.args = ["-y", body.package ?? "", ...body.args || []];
786
841
  }
787
842
  if (body.scope && body.scope !== "always") entry.scope = body.scope;
788
843
  if (body.env && Object.keys(body.env).length > 0) entry.env = body.env;
@@ -833,7 +888,7 @@ function createMcpRoutes(deps) {
833
888
  return app;
834
889
  }
835
890
  function deriveServerName(pkg) {
836
- const unscoped = pkg.includes("/") ? pkg.split("/").pop() : pkg;
891
+ const unscoped = pkg.includes("/") ? pkg.split("/").pop() ?? pkg : pkg;
837
892
  return unscoped.replace(/^server-/, "").replace(/^mcp-server-/, "").replace(/^mcp-/, "");
838
893
  }
839
894
 
@@ -850,6 +905,8 @@ import {
850
905
  existsSync
851
906
  } from "fs";
852
907
  import { join as join2, relative } from "path";
908
+ var MAX_SCAN_DEPTH = 10;
909
+ var MAX_SCAN_ENTRIES = 5e3;
853
910
  function errorResponse(c, error, status = 500) {
854
911
  const message = getErrorMessage(error);
855
912
  const code = error instanceof WorkspaceSecurityError ? 403 : status;
@@ -866,35 +923,46 @@ var IMAGE_MIME_TYPES = {
866
923
  ".bmp": "image/bmp",
867
924
  ".ico": "image/x-icon"
868
925
  };
869
- function getWorkspaceStats(dir) {
870
- let files = 0;
871
- let size = 0;
872
- 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
+ }
873
932
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
933
+ if (state.files >= MAX_SCAN_ENTRIES) {
934
+ state.truncated = true;
935
+ return state;
936
+ }
874
937
  const fullPath = join2(dir, entry.name);
875
938
  if (entry.isDirectory()) {
876
- const sub = getWorkspaceStats(fullPath);
877
- files += sub.files;
878
- size += sub.size;
939
+ getWorkspaceStats(fullPath, depth + 1, state);
879
940
  } else if (entry.isFile()) {
880
- files++;
941
+ state.files++;
881
942
  try {
882
- size += statSync(fullPath).size;
943
+ state.size += statSync(fullPath).size;
883
944
  } catch {
884
945
  }
885
946
  }
886
947
  }
887
- return { files, size };
948
+ return state;
888
949
  }
889
- function listDir(absPath, recursive) {
890
- if (!existsSync(absPath)) return [];
891
- 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
+ }
892
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
+ }
893
961
  const fullPath = join2(absPath, entry.name);
894
962
  const relPath = relative(WORKSPACE_ROOT, fullPath);
895
963
  try {
896
964
  const stats = statSync(fullPath);
897
- entries.push({
965
+ state.entries.push({
898
966
  name: entry.name,
899
967
  path: relPath,
900
968
  isDirectory: entry.isDirectory(),
@@ -902,12 +970,12 @@ function listDir(absPath, recursive) {
902
970
  mtime: stats.mtime.toISOString()
903
971
  });
904
972
  if (recursive && entry.isDirectory()) {
905
- entries.push(...listDir(fullPath, true));
973
+ listDir(fullPath, true, depth + 1, state);
906
974
  }
907
975
  } catch {
908
976
  }
909
977
  }
910
- return entries;
978
+ return state;
911
979
  }
912
980
  function createWorkspaceRoutes(_deps) {
913
981
  const app = new Hono8();
@@ -927,12 +995,18 @@ function createWorkspaceRoutes(_deps) {
927
995
  const response2 = { success: true, data: [] };
928
996
  return c.json(response2);
929
997
  }
930
- const entries = listDir(validated.absolutePath, recursive);
931
- entries.sort((a, b) => {
998
+ const result = listDir(validated.absolutePath, recursive);
999
+ result.entries.sort((a, b) => {
932
1000
  if (a.isDirectory !== b.isDirectory) return a.isDirectory ? -1 : 1;
933
1001
  return a.name.localeCompare(b.name);
934
1002
  });
935
- 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
+ };
936
1010
  return c.json(response);
937
1011
  } catch (error) {
938
1012
  return errorResponse(c, error);
@@ -1101,7 +1175,8 @@ function createWorkspaceRoutes(_deps) {
1101
1175
  data: {
1102
1176
  root: WORKSPACE_ROOT,
1103
1177
  totalFiles: stats.files,
1104
- totalSize: stats.size
1178
+ totalSize: stats.size,
1179
+ ...stats.truncated && { truncated: true }
1105
1180
  }
1106
1181
  };
1107
1182
  return c.json(response);
@@ -1658,7 +1733,7 @@ var MarketplaceService = class {
1658
1733
  const registry = await this.getRegistry();
1659
1734
  const entry = registry.find((e) => e.id === pluginId);
1660
1735
  if (!entry) throw new Error(`Plugin "${pluginId}" not found in registry`);
1661
- const manifest = await this.fetchRemoteManifest(entry);
1736
+ const _manifest = await this.fetchRemoteManifest(entry);
1662
1737
  mkdirSync2(pluginDir, { recursive: true });
1663
1738
  await this.downloadDir(entry.path, pluginDir);
1664
1739
  await ensurePluginDeps(pluginDir, pluginId);
@@ -1834,7 +1909,7 @@ function createMarketplaceRoutes(deps) {
1834
1909
  const result = await svc.installPlugin(body.id);
1835
1910
  deps.plugins.length = 0;
1836
1911
  deps.plugins.push(
1837
- ...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" }))
1838
1913
  );
1839
1914
  return c.json({ success: true, data: result });
1840
1915
  } catch (err) {
@@ -1858,7 +1933,7 @@ function createMarketplaceRoutes(deps) {
1858
1933
  const result = await svc.uninstallPlugin(body.id);
1859
1934
  deps.plugins.length = 0;
1860
1935
  deps.plugins.push(
1861
- ...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" }))
1862
1937
  );
1863
1938
  return c.json({ success: true, data: result });
1864
1939
  } catch (err) {
@@ -1882,7 +1957,7 @@ function createMarketplaceRoutes(deps) {
1882
1957
  const result = await svc.updatePlugin(body.id);
1883
1958
  deps.plugins.length = 0;
1884
1959
  deps.plugins.push(
1885
- ...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" }))
1886
1961
  );
1887
1962
  return c.json({ success: true, data: result });
1888
1963
  } catch (err) {
@@ -1972,8 +2047,271 @@ function createMarketplaceRoutes(deps) {
1972
2047
  return app;
1973
2048
  }
1974
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
+
1975
2313
  // src/webui/server.ts
1976
- var log2 = createLogger("WebUI");
2314
+ var log3 = createLogger("WebUI");
1977
2315
  function findWebDist() {
1978
2316
  const candidates = [
1979
2317
  resolve2("dist/web"),
@@ -2002,12 +2340,13 @@ var WebUIServer = class {
2002
2340
  authToken;
2003
2341
  constructor(deps) {
2004
2342
  this.deps = deps;
2005
- this.app = new Hono12();
2343
+ this.app = new Hono14();
2006
2344
  this.authToken = deps.config.auth_token || generateToken();
2007
2345
  this.setupMiddleware();
2008
2346
  this.setupRoutes();
2009
2347
  }
2010
2348
  /** Set an HttpOnly session cookie */
2349
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Hono context type
2011
2350
  setSessionCookie(c) {
2012
2351
  setCookie(c, COOKIE_NAME, this.authToken, {
2013
2352
  path: "/",
@@ -2034,7 +2373,7 @@ var WebUIServer = class {
2034
2373
  const start = Date.now();
2035
2374
  await next();
2036
2375
  const duration = Date.now() - start;
2037
- 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)`);
2038
2377
  });
2039
2378
  }
2040
2379
  this.app.use(
@@ -2112,6 +2451,8 @@ var WebUIServer = class {
2112
2451
  this.app.route("/api/tasks", createTasksRoutes(this.deps));
2113
2452
  this.app.route("/api/config", createConfigRoutes(this.deps));
2114
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));
2115
2456
  this.app.post("/api/agent/start", async (c) => {
2116
2457
  const lifecycle = this.deps.lifecycle;
2117
2458
  if (!lifecycle) {
@@ -2125,7 +2466,7 @@ var WebUIServer = class {
2125
2466
  return c.json({ error: "Agent is currently stopping, please wait" }, 409);
2126
2467
  }
2127
2468
  lifecycle.start().catch((err) => {
2128
- log2.error({ err }, "Agent start failed");
2469
+ log3.error({ err }, "Agent start failed");
2129
2470
  });
2130
2471
  return c.json({ state: "starting" });
2131
2472
  });
@@ -2142,7 +2483,7 @@ var WebUIServer = class {
2142
2483
  return c.json({ error: "Agent is currently starting, please wait" }, 409);
2143
2484
  }
2144
2485
  lifecycle.stop().catch((err) => {
2145
- log2.error({ err }, "Agent stop failed");
2486
+ log3.error({ err }, "Agent stop failed");
2146
2487
  });
2147
2488
  return c.json({ state: "stopping" });
2148
2489
  });
@@ -2180,7 +2521,7 @@ var WebUIServer = class {
2180
2521
  });
2181
2522
  const onStateChange = (event) => {
2182
2523
  if (aborted) return;
2183
- stream.writeSSE({
2524
+ void stream.writeSSE({
2184
2525
  event: "status",
2185
2526
  id: String(event.timestamp),
2186
2527
  data: JSON.stringify({
@@ -2239,7 +2580,7 @@ var WebUIServer = class {
2239
2580
  });
2240
2581
  }
2241
2582
  this.app.onError((err, c) => {
2242
- log2.error({ err }, "WebUI error");
2583
+ log3.error({ err }, "WebUI error");
2243
2584
  return c.json(
2244
2585
  {
2245
2586
  success: false,
@@ -2261,9 +2602,9 @@ var WebUIServer = class {
2261
2602
  },
2262
2603
  (info) => {
2263
2604
  const url = `http://${info.address}:${info.port}`;
2264
- log2.info(`WebUI server running`);
2265
- log2.info(`URL: ${url}/auth/exchange?token=${this.authToken}`);
2266
- 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)`);
2267
2608
  resolve3();
2268
2609
  }
2269
2610
  );
@@ -2276,9 +2617,9 @@ var WebUIServer = class {
2276
2617
  async stop() {
2277
2618
  if (this.server) {
2278
2619
  return new Promise((resolve3) => {
2279
- this.server.close(() => {
2620
+ this.server?.close(() => {
2280
2621
  logInterceptor.uninstall();
2281
- log2.info("WebUI server stopped");
2622
+ log3.info("WebUI server stopped");
2282
2623
  resolve3();
2283
2624
  });
2284
2625
  });