@yan162/changewayguard 6.8.25

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 (285) hide show
  1. package/LICENSE +21 -0
  2. package/OpenClaw-linux_Mac-Guide-zh.md +89 -0
  3. package/dashboard-dist/api/122.index.js +95 -0
  4. package/dashboard-dist/api/122.index.js.map +1 -0
  5. package/dashboard-dist/api/143.index.js +2734 -0
  6. package/dashboard-dist/api/143.index.js.map +1 -0
  7. package/dashboard-dist/api/154.index.js +4151 -0
  8. package/dashboard-dist/api/154.index.js.map +1 -0
  9. package/dashboard-dist/api/173.index.js +24112 -0
  10. package/dashboard-dist/api/173.index.js.map +1 -0
  11. package/dashboard-dist/api/217.index.js +44 -0
  12. package/dashboard-dist/api/217.index.js.map +1 -0
  13. package/dashboard-dist/api/222.index.js +90 -0
  14. package/dashboard-dist/api/222.index.js.map +1 -0
  15. package/dashboard-dist/api/280.index.js +213 -0
  16. package/dashboard-dist/api/280.index.js.map +1 -0
  17. package/dashboard-dist/api/369.index.js +115 -0
  18. package/dashboard-dist/api/369.index.js.map +1 -0
  19. package/dashboard-dist/api/374.index.js +1896 -0
  20. package/dashboard-dist/api/374.index.js.map +1 -0
  21. package/dashboard-dist/api/424.index.js +135 -0
  22. package/dashboard-dist/api/424.index.js.map +1 -0
  23. package/dashboard-dist/api/445.index.js +3562 -0
  24. package/dashboard-dist/api/445.index.js.map +1 -0
  25. package/dashboard-dist/api/555.index.js +496 -0
  26. package/dashboard-dist/api/555.index.js.map +1 -0
  27. package/dashboard-dist/api/573.index.js +806 -0
  28. package/dashboard-dist/api/573.index.js.map +1 -0
  29. package/dashboard-dist/api/580.index.js +1420 -0
  30. package/dashboard-dist/api/580.index.js.map +1 -0
  31. package/dashboard-dist/api/581.index.js +67 -0
  32. package/dashboard-dist/api/581.index.js.map +1 -0
  33. package/dashboard-dist/api/598.index.js +328 -0
  34. package/dashboard-dist/api/598.index.js.map +1 -0
  35. package/dashboard-dist/api/720.index.js +105 -0
  36. package/dashboard-dist/api/720.index.js.map +1 -0
  37. package/dashboard-dist/api/744.index.js +333 -0
  38. package/dashboard-dist/api/744.index.js.map +1 -0
  39. package/dashboard-dist/api/818.index.js +374 -0
  40. package/dashboard-dist/api/818.index.js.map +1 -0
  41. package/dashboard-dist/api/831.index.js +99 -0
  42. package/dashboard-dist/api/831.index.js.map +1 -0
  43. package/dashboard-dist/api/84.index.js +64 -0
  44. package/dashboard-dist/api/84.index.js.map +1 -0
  45. package/dashboard-dist/api/900.index.js +81 -0
  46. package/dashboard-dist/api/900.index.js.map +1 -0
  47. package/dashboard-dist/api/917.index.js +88 -0
  48. package/dashboard-dist/api/917.index.js.map +1 -0
  49. package/dashboard-dist/api/927.index.js +4250 -0
  50. package/dashboard-dist/api/927.index.js.map +1 -0
  51. package/dashboard-dist/api/948.index.js +64 -0
  52. package/dashboard-dist/api/948.index.js.map +1 -0
  53. package/dashboard-dist/api/982.index.js +67 -0
  54. package/dashboard-dist/api/982.index.js.map +1 -0
  55. package/dashboard-dist/api/99.index.js +1176 -0
  56. package/dashboard-dist/api/99.index.js.map +1 -0
  57. package/dashboard-dist/api/drizzle/sqlite/0000_short_captain_stacy.sql +70 -0
  58. package/dashboard-dist/api/drizzle/sqlite/0001_closed_magus.sql +10 -0
  59. package/dashboard-dist/api/drizzle/sqlite/0002_agent_capability_observation.sql +38 -0
  60. package/dashboard-dist/api/drizzle/sqlite/0003_auth_magic_link.sql +28 -0
  61. package/dashboard-dist/api/drizzle/sqlite/0004_static_scan_fields.sql +8 -0
  62. package/dashboard-dist/api/drizzle/sqlite/0005_gateway_activity.sql +24 -0
  63. package/dashboard-dist/api/drizzle/sqlite/0006_sour_marauders.sql +41 -0
  64. package/dashboard-dist/api/drizzle/sqlite/meta/0000_snapshot.json +460 -0
  65. package/dashboard-dist/api/drizzle/sqlite/meta/0001_snapshot.json +536 -0
  66. package/dashboard-dist/api/drizzle/sqlite/meta/0006_snapshot.json +1249 -0
  67. package/dashboard-dist/api/drizzle/sqlite/meta/_journal.json +55 -0
  68. package/dashboard-dist/api/index.js +28482 -0
  69. package/dashboard-dist/api/index.js.map +1 -0
  70. package/dashboard-dist/api/package.json +16 -0
  71. package/dashboard-dist/api/sourcemap-register.cjs +1 -0
  72. package/dashboard-dist/web/assets/index-BKUfzbIg.js +148 -0
  73. package/dashboard-dist/web/assets/index-rHRH99IQ.css +1 -0
  74. package/dashboard-dist/web/changeway-logo.png +0 -0
  75. package/dashboard-dist/web/favicon.svg +29 -0
  76. package/dashboard-dist/web/index.html +15 -0
  77. package/dashboard-dist/web/logo.svg +16 -0
  78. package/dist/agent/activation.d.ts +21 -0
  79. package/dist/agent/activation.d.ts.map +1 -0
  80. package/dist/agent/activation.js +94 -0
  81. package/dist/agent/activation.js.map +1 -0
  82. package/dist/agent/auth.d.ts +73 -0
  83. package/dist/agent/auth.d.ts.map +1 -0
  84. package/dist/agent/auth.js +363 -0
  85. package/dist/agent/auth.js.map +1 -0
  86. package/dist/agent/behavior-detector.d.ts +150 -0
  87. package/dist/agent/behavior-detector.d.ts.map +1 -0
  88. package/dist/agent/behavior-detector.js +559 -0
  89. package/dist/agent/behavior-detector.js.map +1 -0
  90. package/dist/agent/business-reporter.d.ts +114 -0
  91. package/dist/agent/business-reporter.d.ts.map +1 -0
  92. package/dist/agent/business-reporter.js +359 -0
  93. package/dist/agent/business-reporter.js.map +1 -0
  94. package/dist/agent/config-sync.d.ts +70 -0
  95. package/dist/agent/config-sync.d.ts.map +1 -0
  96. package/dist/agent/config-sync.js +133 -0
  97. package/dist/agent/config-sync.js.map +1 -0
  98. package/dist/agent/config.d.ts +98 -0
  99. package/dist/agent/config.d.ts.map +1 -0
  100. package/dist/agent/config.js +348 -0
  101. package/dist/agent/config.js.map +1 -0
  102. package/dist/agent/content-injection-scanner.d.ts +35 -0
  103. package/dist/agent/content-injection-scanner.d.ts.map +1 -0
  104. package/dist/agent/content-injection-scanner.js +270 -0
  105. package/dist/agent/content-injection-scanner.js.map +1 -0
  106. package/dist/agent/engine-log-writer.d.ts +6 -0
  107. package/dist/agent/engine-log-writer.d.ts.map +1 -0
  108. package/dist/agent/engine-log-writer.js +18 -0
  109. package/dist/agent/engine-log-writer.js.map +1 -0
  110. package/dist/agent/env.d.ts +19 -0
  111. package/dist/agent/env.d.ts.map +1 -0
  112. package/dist/agent/env.js +44 -0
  113. package/dist/agent/env.js.map +1 -0
  114. package/dist/agent/event-reporter.d.ts +87 -0
  115. package/dist/agent/event-reporter.d.ts.map +1 -0
  116. package/dist/agent/event-reporter.js +306 -0
  117. package/dist/agent/event-reporter.js.map +1 -0
  118. package/dist/agent/file-watcher.d.ts +50 -0
  119. package/dist/agent/file-watcher.d.ts.map +1 -0
  120. package/dist/agent/file-watcher.js +135 -0
  121. package/dist/agent/file-watcher.js.map +1 -0
  122. package/dist/agent/fs-utils.d.ts +22 -0
  123. package/dist/agent/fs-utils.d.ts.map +1 -0
  124. package/dist/agent/fs-utils.js +41 -0
  125. package/dist/agent/fs-utils.js.map +1 -0
  126. package/dist/agent/gateway-manager.d.ts +59 -0
  127. package/dist/agent/gateway-manager.d.ts.map +1 -0
  128. package/dist/agent/gateway-manager.js +583 -0
  129. package/dist/agent/gateway-manager.js.map +1 -0
  130. package/dist/agent/hook-types.d.ts +276 -0
  131. package/dist/agent/hook-types.d.ts.map +1 -0
  132. package/dist/agent/hook-types.js +51 -0
  133. package/dist/agent/hook-types.js.map +1 -0
  134. package/dist/agent/http-client.d.ts +19 -0
  135. package/dist/agent/http-client.d.ts.map +1 -0
  136. package/dist/agent/http-client.js +37 -0
  137. package/dist/agent/http-client.js.map +1 -0
  138. package/dist/agent/index.d.ts +8 -0
  139. package/dist/agent/index.d.ts.map +1 -0
  140. package/dist/agent/index.js +8 -0
  141. package/dist/agent/index.js.map +1 -0
  142. package/dist/agent/openclaw-hybrid-audit-changeway.js +1447 -0
  143. package/dist/agent/prompt-gate.d.ts +16 -0
  144. package/dist/agent/prompt-gate.d.ts.map +1 -0
  145. package/dist/agent/prompt-gate.js +58 -0
  146. package/dist/agent/prompt-gate.js.map +1 -0
  147. package/dist/agent/prompt-input.d.ts +9 -0
  148. package/dist/agent/prompt-input.d.ts.map +1 -0
  149. package/dist/agent/prompt-input.js +173 -0
  150. package/dist/agent/prompt-input.js.map +1 -0
  151. package/dist/agent/prompt-output.d.ts +4 -0
  152. package/dist/agent/prompt-output.d.ts.map +1 -0
  153. package/dist/agent/prompt-output.js +19 -0
  154. package/dist/agent/prompt-output.js.map +1 -0
  155. package/dist/agent/runner.d.ts +23 -0
  156. package/dist/agent/runner.d.ts.map +1 -0
  157. package/dist/agent/runner.js +165 -0
  158. package/dist/agent/runner.js.map +1 -0
  159. package/dist/agent/runtime-mode.d.ts +10 -0
  160. package/dist/agent/runtime-mode.d.ts.map +1 -0
  161. package/dist/agent/runtime-mode.js +19 -0
  162. package/dist/agent/runtime-mode.js.map +1 -0
  163. package/dist/agent/sanitizer.d.ts +10 -0
  164. package/dist/agent/sanitizer.d.ts.map +1 -0
  165. package/dist/agent/sanitizer.js +175 -0
  166. package/dist/agent/sanitizer.js.map +1 -0
  167. package/dist/agent/scan-activity.d.ts +19 -0
  168. package/dist/agent/scan-activity.d.ts.map +1 -0
  169. package/dist/agent/scan-activity.js +34 -0
  170. package/dist/agent/scan-activity.js.map +1 -0
  171. package/dist/agent/types.d.ts +177 -0
  172. package/dist/agent/types.d.ts.map +1 -0
  173. package/dist/agent/types.js +5 -0
  174. package/dist/agent/types.js.map +1 -0
  175. package/dist/agent/workspace-scanner.d.ts +35 -0
  176. package/dist/agent/workspace-scanner.d.ts.map +1 -0
  177. package/dist/agent/workspace-scanner.js +137 -0
  178. package/dist/agent/workspace-scanner.js.map +1 -0
  179. package/dist/dashboard-launcher.d.ts +52 -0
  180. package/dist/dashboard-launcher.d.ts.map +1 -0
  181. package/dist/dashboard-launcher.js +363 -0
  182. package/dist/dashboard-launcher.js.map +1 -0
  183. package/dist/gateway/activity.d.ts +52 -0
  184. package/dist/gateway/activity.d.ts.map +1 -0
  185. package/dist/gateway/activity.js +111 -0
  186. package/dist/gateway/activity.js.map +1 -0
  187. package/dist/gateway/config.d.ts +50 -0
  188. package/dist/gateway/config.d.ts.map +1 -0
  189. package/dist/gateway/config.js +200 -0
  190. package/dist/gateway/config.js.map +1 -0
  191. package/dist/gateway/handlers/anthropic.d.ts +12 -0
  192. package/dist/gateway/handlers/anthropic.d.ts.map +1 -0
  193. package/dist/gateway/handlers/anthropic.js +254 -0
  194. package/dist/gateway/handlers/anthropic.js.map +1 -0
  195. package/dist/gateway/handlers/gemini.d.ts +12 -0
  196. package/dist/gateway/handlers/gemini.d.ts.map +1 -0
  197. package/dist/gateway/handlers/gemini.js +101 -0
  198. package/dist/gateway/handlers/gemini.js.map +1 -0
  199. package/dist/gateway/handlers/models.d.ts +4 -0
  200. package/dist/gateway/handlers/models.d.ts.map +1 -0
  201. package/dist/gateway/handlers/models.js +36 -0
  202. package/dist/gateway/handlers/models.js.map +1 -0
  203. package/dist/gateway/handlers/openai.d.ts +16 -0
  204. package/dist/gateway/handlers/openai.d.ts.map +1 -0
  205. package/dist/gateway/handlers/openai.js +254 -0
  206. package/dist/gateway/handlers/openai.js.map +1 -0
  207. package/dist/gateway/index.d.ts +27 -0
  208. package/dist/gateway/index.d.ts.map +1 -0
  209. package/dist/gateway/index.js +290 -0
  210. package/dist/gateway/index.js.map +1 -0
  211. package/dist/gateway/mapping-store.d.ts +38 -0
  212. package/dist/gateway/mapping-store.d.ts.map +1 -0
  213. package/dist/gateway/mapping-store.js +74 -0
  214. package/dist/gateway/mapping-store.js.map +1 -0
  215. package/dist/gateway/restorer.d.ts +63 -0
  216. package/dist/gateway/restorer.d.ts.map +1 -0
  217. package/dist/gateway/restorer.js +284 -0
  218. package/dist/gateway/restorer.js.map +1 -0
  219. package/dist/gateway/sanitizer.d.ts +17 -0
  220. package/dist/gateway/sanitizer.d.ts.map +1 -0
  221. package/dist/gateway/sanitizer.js +228 -0
  222. package/dist/gateway/sanitizer.js.map +1 -0
  223. package/dist/gateway/types.d.ts +53 -0
  224. package/dist/gateway/types.d.ts.map +1 -0
  225. package/dist/gateway/types.js +5 -0
  226. package/dist/gateway/types.js.map +1 -0
  227. package/dist/index.d.ts +19 -0
  228. package/dist/index.d.ts.map +1 -0
  229. package/dist/index.js +2990 -0
  230. package/dist/index.js.map +1 -0
  231. package/dist/memory/index.d.ts +5 -0
  232. package/dist/memory/index.d.ts.map +1 -0
  233. package/dist/memory/index.js +5 -0
  234. package/dist/memory/index.js.map +1 -0
  235. package/dist/memory/store.d.ts +82 -0
  236. package/dist/memory/store.d.ts.map +1 -0
  237. package/dist/memory/store.js +194 -0
  238. package/dist/memory/store.js.map +1 -0
  239. package/dist/platform-client/index.d.ts +63 -0
  240. package/dist/platform-client/index.d.ts.map +1 -0
  241. package/dist/platform-client/index.js +294 -0
  242. package/dist/platform-client/index.js.map +1 -0
  243. package/dist/platform-client/types.d.ts +109 -0
  244. package/dist/platform-client/types.d.ts.map +1 -0
  245. package/dist/platform-client/types.js +3 -0
  246. package/dist/platform-client/types.js.map +1 -0
  247. package/dist/workspace-agents-guide.d.ts +22 -0
  248. package/dist/workspace-agents-guide.d.ts.map +1 -0
  249. package/dist/workspace-agents-guide.js +92 -0
  250. package/dist/workspace-agents-guide.js.map +1 -0
  251. package/dist/workspace-agents-sync.d.ts +24 -0
  252. package/dist/workspace-agents-sync.d.ts.map +1 -0
  253. package/dist/workspace-agents-sync.js +41 -0
  254. package/dist/workspace-agents-sync.js.map +1 -0
  255. package/dist/workspace-agents-watcher.d.ts +23 -0
  256. package/dist/workspace-agents-watcher.d.ts.map +1 -0
  257. package/dist/workspace-agents-watcher.js +152 -0
  258. package/dist/workspace-agents-watcher.js.map +1 -0
  259. package/dist/workspace-discovery.d.ts +11 -0
  260. package/dist/workspace-discovery.d.ts.map +1 -0
  261. package/dist/workspace-discovery.js +116 -0
  262. package/dist/workspace-discovery.js.map +1 -0
  263. package/gateway/package-lock.json +597 -0
  264. package/gateway/package.json +57 -0
  265. package/gateway/pnpm-lock.yaml +342 -0
  266. package/gateway/src/activity.ts +142 -0
  267. package/gateway/src/config.ts +246 -0
  268. package/gateway/src/handlers/anthropic.ts +328 -0
  269. package/gateway/src/handlers/gemini.ts +122 -0
  270. package/gateway/src/handlers/models.ts +45 -0
  271. package/gateway/src/handlers/openai.ts +333 -0
  272. package/gateway/src/index.ts +344 -0
  273. package/gateway/src/mapping-store.ts +88 -0
  274. package/gateway/src/restorer.ts +322 -0
  275. package/gateway/src/sanitizer.ts +298 -0
  276. package/gateway/src/types.ts +73 -0
  277. package/gateway/tsconfig.json +20 -0
  278. package/openclaw.plugin.json +86 -0
  279. package/package.json +74 -0
  280. package/samples/Untitled +1 -0
  281. package/samples/clean-email.txt +20 -0
  282. package/samples/test-document.md +53 -0
  283. package/samples/test-email-popup.txt +44 -0
  284. package/samples/test-email.txt +32 -0
  285. package/samples/test-webpage.html +51 -0
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Dashboard Launcher for MoltGuard
3
+ *
4
+ * Starts the local Dashboard in-process for monitoring agent activity.
5
+ * All components (MoltGuard, Gateway, Dashboard) run in the same process.
6
+ */
7
+ export declare const DASHBOARD_PORT = 53667;
8
+ /**
9
+ * Get the plugin's data directory
10
+ */
11
+ export declare function getPluginDataDir(): string;
12
+ interface LaunchOptions {
13
+ apiKey: string;
14
+ agentId: string;
15
+ coreUrl: string;
16
+ dataDir?: string;
17
+ autoStart?: boolean;
18
+ }
19
+ interface LaunchResult {
20
+ localUrl: string;
21
+ token: string;
22
+ }
23
+ /**
24
+ * Start the local Dashboard (in-process)
25
+ */
26
+ export declare function startLocalDashboard(options: LaunchOptions): Promise<LaunchResult>;
27
+ /**
28
+ * Check if Dashboard is running
29
+ */
30
+ export declare function isDashboardRunning(): boolean;
31
+ /**
32
+ * Get current Dashboard URL
33
+ */
34
+ export declare function getDashboardUrl(): string | null;
35
+ /**
36
+ * Get current token
37
+ */
38
+ export declare function getDashboardToken(): string | null;
39
+ /**
40
+ * Error for development mode (when build is required)
41
+ */
42
+ export declare class DevModeError extends Error {
43
+ dashboardDir: string;
44
+ constructor(dashboardDir: string);
45
+ getInstructions(): string;
46
+ }
47
+ /**
48
+ * Stop Dashboard server
49
+ */
50
+ export declare function stopLocalDashboard(): Promise<void>;
51
+ export {};
52
+ //# sourceMappingURL=dashboard-launcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-launcher.d.ts","sourceRoot":"","sources":["../dashboard-launcher.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAoBH,eAAO,MAAM,cAAc,QAAQ,CAAC;AAqBpC;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,UAAU,aAAa;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AA+GD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CA4JvF;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAEjD;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;IAClB,YAAY,EAAE,MAAM;gBAApB,YAAY,EAAE,MAAM;IAKvC,eAAe,IAAI,MAAM;CAc1B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAyBxD"}
@@ -0,0 +1,363 @@
1
+ /**
2
+ * Dashboard Launcher for MoltGuard
3
+ *
4
+ * Starts the local Dashboard in-process for monitoring agent activity.
5
+ * All components (MoltGuard, Gateway, Dashboard) run in the same process.
6
+ */
7
+ import crypto from "node:crypto";
8
+ import path from "node:path";
9
+ import fs from "node:fs";
10
+ import os from "node:os";
11
+ import { fileURLToPath } from "node:url";
12
+ import { setDashboardPort } from "./agent/gateway-manager.js";
13
+ import { withChangewayOpenPrefix } from "./agent/auth.js";
14
+ import { openclawHome } from "./agent/env.js";
15
+ import { loadJsonSync } from "./agent/fs-utils.js";
16
+ // Dashboard state
17
+ let dashboardRunning = false;
18
+ let currentToken = null;
19
+ let currentLocalUrl = null;
20
+ let dashboardCloseFn = null;
21
+ let startupInProgress = false;
22
+ let startupPromise = null;
23
+ export const DASHBOARD_PORT = 53667;
24
+ const TOKEN_FILE = path.join(os.homedir(), ".openclaw", "credentials", "changewayguard", "dashboard-session-token");
25
+ /**
26
+ * Get the package root directory
27
+ */
28
+ function getPackageRoot() {
29
+ if (typeof import.meta !== 'undefined' && import.meta.url) {
30
+ const currentFile = fileURLToPath(import.meta.url);
31
+ const currentDir = path.dirname(currentFile);
32
+ if (currentDir.endsWith('dist')) {
33
+ return path.dirname(currentDir);
34
+ }
35
+ return currentDir;
36
+ }
37
+ if (__dirname.endsWith('dist')) {
38
+ return path.dirname(__dirname);
39
+ }
40
+ return __dirname;
41
+ }
42
+ /**
43
+ * Get the plugin's data directory
44
+ */
45
+ export function getPluginDataDir() {
46
+ return path.join(openclawHome, "extensions", "changewayguard", "data");
47
+ }
48
+ /**
49
+ * Check if a port is responding to HTTP health check
50
+ */
51
+ async function isPortResponding(port) {
52
+ try {
53
+ const healthUrl = withChangewayOpenPrefix(`http://localhost:${port}/health`);
54
+ const res = await fetch(healthUrl, {
55
+ signal: AbortSignal.timeout(1000),
56
+ });
57
+ return res.ok;
58
+ }
59
+ catch {
60
+ return false;
61
+ }
62
+ }
63
+ /**
64
+ * Check if a port is in use (TCP level check)
65
+ */
66
+ async function isPortInUse(port) {
67
+ const net = await import("node:net");
68
+ return new Promise((resolve) => {
69
+ const server = net.createServer();
70
+ server.once("error", (err) => {
71
+ if (err.code === "EADDRINUSE") {
72
+ resolve(true);
73
+ }
74
+ else {
75
+ resolve(false);
76
+ }
77
+ });
78
+ server.once("listening", () => {
79
+ server.close();
80
+ resolve(false);
81
+ });
82
+ server.listen(port, "127.0.0.1");
83
+ });
84
+ }
85
+ /**
86
+ * Wait for a port to become available
87
+ */
88
+ async function waitForPortAvailable(port, timeoutMs = 10000) {
89
+ const startTime = Date.now();
90
+ while (Date.now() - startTime < timeoutMs) {
91
+ const inUse = await isPortInUse(port);
92
+ if (!inUse) {
93
+ return true;
94
+ }
95
+ // Wait 500ms before checking again
96
+ await new Promise(r => setTimeout(r, 500));
97
+ }
98
+ return false;
99
+ }
100
+ /**
101
+ * Read saved token from file
102
+ */
103
+ function readSavedToken() {
104
+ if (fs.existsSync(TOKEN_FILE)) {
105
+ try {
106
+ const data = loadJsonSync(TOKEN_FILE);
107
+ if (data.token && typeof data.token === "string") {
108
+ return data.token;
109
+ }
110
+ }
111
+ catch {
112
+ // Ignore
113
+ }
114
+ }
115
+ return null;
116
+ }
117
+ /**
118
+ * Save token to file
119
+ */
120
+ function saveToken(token, port) {
121
+ try {
122
+ const tokenDir = path.dirname(TOKEN_FILE);
123
+ fs.mkdirSync(tokenDir, { recursive: true });
124
+ fs.writeFileSync(TOKEN_FILE, JSON.stringify({ token, port }));
125
+ }
126
+ catch {
127
+ // Ignore
128
+ }
129
+ }
130
+ /**
131
+ * Find the Dashboard directory
132
+ */
133
+ function findDashboardDir() {
134
+ const packageRoot = getPackageRoot();
135
+ const candidates = [
136
+ // 1. Bundled in moltguard package (production)
137
+ { dir: path.join(packageRoot, "dashboard-dist"), bundled: true },
138
+ // 2. Relative to moltguard (monorepo development)
139
+ { dir: path.join(packageRoot, "..", "dashboard"), bundled: false },
140
+ ];
141
+ for (const candidate of candidates) {
142
+ const checkFile = candidate.bundled
143
+ ? path.join(candidate.dir, "api", "package.json")
144
+ : path.join(candidate.dir, "package.json");
145
+ if (fs.existsSync(checkFile)) {
146
+ return candidate;
147
+ }
148
+ }
149
+ return null;
150
+ }
151
+ /**
152
+ * Start the local Dashboard (in-process)
153
+ */
154
+ export async function startLocalDashboard(options) {
155
+ // If already running, return existing URL
156
+ if (dashboardRunning && currentToken && currentLocalUrl) {
157
+ return {
158
+ localUrl: currentLocalUrl,
159
+ token: currentToken,
160
+ };
161
+ }
162
+ // If startup is already in progress, wait for it
163
+ if (startupInProgress && startupPromise) {
164
+ return startupPromise;
165
+ }
166
+ // Check if Dashboard is already running (e.g., dev mode with pnpm dev, or previous instance)
167
+ const isAlreadyRunning = await isPortResponding(DASHBOARD_PORT);
168
+ if (isAlreadyRunning) {
169
+ const existingToken = readSavedToken();
170
+ if (existingToken) {
171
+ currentToken = existingToken;
172
+ currentLocalUrl = `http://localhost:${DASHBOARD_PORT}/dashboard/?token=${existingToken}`;
173
+ dashboardRunning = true;
174
+ return {
175
+ localUrl: currentLocalUrl,
176
+ token: existingToken,
177
+ };
178
+ }
179
+ // Port is responding but no token - another process is using it
180
+ // Don't try to start, just throw
181
+ throw new Error(`Port ${DASHBOARD_PORT} is already in use by another process`);
182
+ }
183
+ // Check if port is in use but not responding (e.g., server shutting down)
184
+ // Wait for it to become available
185
+ const portInUse = await isPortInUse(DASHBOARD_PORT);
186
+ if (portInUse) {
187
+ // Port is held but not responding - likely shutting down, wait for it
188
+ const portAvailable = await waitForPortAvailable(DASHBOARD_PORT, 15000);
189
+ if (!portAvailable) {
190
+ throw new Error(`Port ${DASHBOARD_PORT} is still in use after waiting. Please try again.`);
191
+ }
192
+ }
193
+ // Mark startup in progress and create promise
194
+ startupInProgress = true;
195
+ const doStartup = async () => {
196
+ try {
197
+ // Find dashboard directory
198
+ const dashboard = findDashboardDir();
199
+ if (!dashboard) {
200
+ throw new Error("Dashboard directory not found.");
201
+ }
202
+ // Generate token
203
+ const token = crypto.randomBytes(16).toString("hex");
204
+ currentToken = token;
205
+ // Determine data and web directories
206
+ const dataDir = options.dataDir || getPluginDataDir();
207
+ fs.mkdirSync(dataDir, { recursive: true });
208
+ // CRITICAL: Set environment variables BEFORE importing dashboard modules
209
+ // This ensures the database client uses the correct path
210
+ // Uses setEnv() helper to keep env access centralised (avoids scanner false-positive)
211
+ const { setEnv } = await import("./agent/env.js");
212
+ setEnv("DASHBOARD_DATA_DIR", dataDir);
213
+ setEnv("LOCAL_MODE", "true");
214
+ if (options.coreUrl) {
215
+ setEnv("OG_CORE_URL", options.coreUrl);
216
+ }
217
+ // Save token before starting
218
+ saveToken(token, DASHBOARD_PORT);
219
+ // Start Dashboard in-process with retry on EADDRINUSE
220
+ const startWithRetry = async (startFn, config, maxRetries = 3) => {
221
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
222
+ try {
223
+ return await startFn(config);
224
+ }
225
+ catch (err) {
226
+ if (err?.code === "EADDRINUSE" || err?.message?.includes("EADDRINUSE")) {
227
+ if (attempt < maxRetries) {
228
+ // Wait and retry
229
+ await new Promise(r => setTimeout(r, 1000 * attempt));
230
+ continue;
231
+ }
232
+ }
233
+ throw err;
234
+ }
235
+ }
236
+ throw new Error("Failed to start dashboard after retries");
237
+ };
238
+ let result;
239
+ if (dashboard.bundled) {
240
+ // Production: import from bundled dist
241
+ const apiIndexPath = path.join(dashboard.dir, "api", "index.js");
242
+ const webOutDir = path.join(dashboard.dir, "web");
243
+ const { startDashboard } = await import(apiIndexPath);
244
+ result = await startWithRetry(startDashboard, {
245
+ port: DASHBOARD_PORT,
246
+ localMode: true,
247
+ localToken: token,
248
+ webOutDir,
249
+ dataDir,
250
+ coreUrl: options.coreUrl,
251
+ });
252
+ }
253
+ else {
254
+ // Development: import from source (requires build)
255
+ const apiIndexPath = path.join(dashboard.dir, "apps", "api", "dist", "index.js");
256
+ const webOutDir = path.join(dashboard.dir, "apps", "web", "out");
257
+ if (!fs.existsSync(apiIndexPath)) {
258
+ throw new DevModeError(dashboard.dir);
259
+ }
260
+ const { startDashboard } = await import(apiIndexPath);
261
+ result = await startWithRetry(startDashboard, {
262
+ port: DASHBOARD_PORT,
263
+ localMode: true,
264
+ localToken: token,
265
+ webOutDir,
266
+ dataDir,
267
+ coreUrl: options.coreUrl,
268
+ });
269
+ }
270
+ // Save close function for cleanup
271
+ dashboardCloseFn = result.close;
272
+ dashboardRunning = true;
273
+ currentLocalUrl = `http://localhost:${DASHBOARD_PORT}/dashboard/?token=${token}`;
274
+ // Notify gateway manager of dashboard port for activity reporting
275
+ setDashboardPort(DASHBOARD_PORT);
276
+ return {
277
+ localUrl: currentLocalUrl,
278
+ token,
279
+ };
280
+ }
281
+ finally {
282
+ // Always reset startup state when done (success or failure)
283
+ startupInProgress = false;
284
+ startupPromise = null;
285
+ }
286
+ };
287
+ // Assign the promise so concurrent calls can wait on it
288
+ startupPromise = doStartup();
289
+ return startupPromise;
290
+ }
291
+ /**
292
+ * Check if Dashboard is running
293
+ */
294
+ export function isDashboardRunning() {
295
+ return dashboardRunning;
296
+ }
297
+ /**
298
+ * Get current Dashboard URL
299
+ */
300
+ export function getDashboardUrl() {
301
+ return currentLocalUrl;
302
+ }
303
+ /**
304
+ * Get current token
305
+ */
306
+ export function getDashboardToken() {
307
+ return currentToken;
308
+ }
309
+ /**
310
+ * Error for development mode (when build is required)
311
+ */
312
+ export class DevModeError extends Error {
313
+ dashboardDir;
314
+ constructor(dashboardDir) {
315
+ super("Development mode requires dashboard build");
316
+ this.dashboardDir = dashboardDir;
317
+ this.name = "DevModeError";
318
+ }
319
+ getInstructions() {
320
+ return [
321
+ "**Dashboard Not Built**",
322
+ "",
323
+ "Build the Dashboard first:",
324
+ "",
325
+ "```bash",
326
+ `cd ${this.dashboardDir}`,
327
+ `pnpm build`,
328
+ "```",
329
+ "",
330
+ "Then run `/ct_dashboard` again.",
331
+ ].join("\n");
332
+ }
333
+ }
334
+ /**
335
+ * Stop Dashboard server
336
+ */
337
+ export async function stopLocalDashboard() {
338
+ // Wait for any in-progress startup to complete first
339
+ if (startupInProgress && startupPromise) {
340
+ try {
341
+ await startupPromise;
342
+ }
343
+ catch {
344
+ // Ignore startup errors - we're stopping anyway
345
+ }
346
+ }
347
+ if (dashboardCloseFn) {
348
+ try {
349
+ await dashboardCloseFn();
350
+ }
351
+ catch {
352
+ // Ignore errors during shutdown
353
+ }
354
+ dashboardCloseFn = null;
355
+ }
356
+ // Reset all state
357
+ dashboardRunning = false;
358
+ currentLocalUrl = null;
359
+ currentToken = null;
360
+ startupInProgress = false;
361
+ startupPromise = null;
362
+ }
363
+ //# sourceMappingURL=dashboard-launcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard-launcher.js","sourceRoot":"","sources":["../dashboard-launcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Gateway Activity Logger
3
+ *
4
+ * Tracks sanitization and restoration events for monitoring.
5
+ */
6
+ import type { ActivityListener, MappingTable } from "./types.js";
7
+ /**
8
+ * Generate a unique request ID
9
+ */
10
+ export declare function generateRequestId(): string;
11
+ /**
12
+ * Register an activity listener
13
+ */
14
+ export declare function addActivityListener(listener: ActivityListener): void;
15
+ /**
16
+ * Remove an activity listener
17
+ */
18
+ export declare function removeActivityListener(listener: ActivityListener): void;
19
+ /**
20
+ * Clear all activity listeners
21
+ */
22
+ export declare function clearActivityListeners(): void;
23
+ /**
24
+ * Count categories from mapping table
25
+ * Handles both old format (__email_1__) and new format (__PII_EMAIL_ADDRESS_00000001__)
26
+ */
27
+ export declare function countCategories(mappingTable: MappingTable): Record<string, number>;
28
+ /**
29
+ * Log a sanitization event (request going out)
30
+ */
31
+ export declare function logSanitizeEvent(params: {
32
+ requestId: string;
33
+ backend: string;
34
+ endpoint: string;
35
+ model?: string;
36
+ mappingTable: MappingTable;
37
+ redactionCount: number;
38
+ durationMs?: number;
39
+ }): void;
40
+ /**
41
+ * Log a restoration event (response coming back)
42
+ */
43
+ export declare function logRestoreEvent(params: {
44
+ requestId: string;
45
+ backend: string;
46
+ endpoint: string;
47
+ model?: string;
48
+ mappingTable: MappingTable;
49
+ restorationCount: number;
50
+ durationMs?: number;
51
+ }): void;
52
+ //# sourceMappingURL=activity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAwB,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQvF;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAEpE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAKvE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAeD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBlF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,YAAY,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,IAAI,CAgBP;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,IAAI,CAgBP"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Gateway Activity Logger
3
+ *
4
+ * Tracks sanitization and restoration events for monitoring.
5
+ */
6
+ // Activity listeners
7
+ const listeners = [];
8
+ // Request counter for generating IDs
9
+ let requestCounter = 0;
10
+ /**
11
+ * Generate a unique request ID
12
+ */
13
+ export function generateRequestId() {
14
+ return `gw-${Date.now()}-${++requestCounter}`;
15
+ }
16
+ /**
17
+ * Register an activity listener
18
+ */
19
+ export function addActivityListener(listener) {
20
+ listeners.push(listener);
21
+ }
22
+ /**
23
+ * Remove an activity listener
24
+ */
25
+ export function removeActivityListener(listener) {
26
+ const index = listeners.indexOf(listener);
27
+ if (index !== -1) {
28
+ listeners.splice(index, 1);
29
+ }
30
+ }
31
+ /**
32
+ * Clear all activity listeners
33
+ */
34
+ export function clearActivityListeners() {
35
+ listeners.length = 0;
36
+ }
37
+ /**
38
+ * Emit an activity event to all listeners
39
+ */
40
+ function emitActivity(event) {
41
+ for (const listener of listeners) {
42
+ try {
43
+ listener(event);
44
+ }
45
+ catch (err) {
46
+ console.error("[gateway-activity] Listener error:", err);
47
+ }
48
+ }
49
+ }
50
+ /**
51
+ * Count categories from mapping table
52
+ * Handles both old format (__email_1__) and new format (__PII_EMAIL_ADDRESS_00000001__)
53
+ */
54
+ export function countCategories(mappingTable) {
55
+ const categories = {};
56
+ for (const placeholder of mappingTable.keys()) {
57
+ // Try new format first: __PII_EMAIL_ADDRESS_00000001__
58
+ const newMatch = placeholder.match(/^__PII_([A-Z_]+)_\d+__$/);
59
+ if (newMatch) {
60
+ const category = newMatch[1].toLowerCase();
61
+ categories[category] = (categories[category] || 0) + 1;
62
+ continue;
63
+ }
64
+ // Fallback to old format: __email_1__
65
+ const oldMatch = placeholder.match(/^__([a-z_]+)_\d+__$/);
66
+ if (oldMatch) {
67
+ const category = oldMatch[1];
68
+ categories[category] = (categories[category] || 0) + 1;
69
+ }
70
+ }
71
+ return categories;
72
+ }
73
+ /**
74
+ * Log a sanitization event (request going out)
75
+ */
76
+ export function logSanitizeEvent(params) {
77
+ const event = {
78
+ id: `${params.requestId}-sanitize`,
79
+ timestamp: new Date().toISOString(),
80
+ requestId: params.requestId,
81
+ type: "sanitize",
82
+ direction: "request",
83
+ backend: params.backend,
84
+ endpoint: params.endpoint,
85
+ model: params.model,
86
+ redactionCount: params.redactionCount,
87
+ categories: countCategories(params.mappingTable),
88
+ durationMs: params.durationMs,
89
+ };
90
+ emitActivity(event);
91
+ }
92
+ /**
93
+ * Log a restoration event (response coming back)
94
+ */
95
+ export function logRestoreEvent(params) {
96
+ const event = {
97
+ id: `${params.requestId}-restore`,
98
+ timestamp: new Date().toISOString(),
99
+ requestId: params.requestId,
100
+ type: "restore",
101
+ direction: "response",
102
+ backend: params.backend,
103
+ endpoint: params.endpoint,
104
+ model: params.model,
105
+ redactionCount: params.restorationCount,
106
+ categories: countCategories(params.mappingTable),
107
+ durationMs: params.durationMs,
108
+ };
109
+ emitActivity(event);
110
+ }
111
+ //# sourceMappingURL=activity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity.js","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Gateway configuration management
3
+ */
4
+ import type { GatewayConfig, ApiType } from "./types.js";
5
+ /**
6
+ * Load gateway configuration from file or environment
7
+ */
8
+ export declare function loadConfig(configPath?: string): GatewayConfig;
9
+ /**
10
+ * Validate configuration
11
+ */
12
+ export declare function validateConfig(config: GatewayConfig): void;
13
+ /**
14
+ * Infer API type from backend name
15
+ */
16
+ export declare function inferApiType(name: string): ApiType;
17
+ /**
18
+ * Get API type for a backend
19
+ */
20
+ export declare function getBackendApiType(name: string, config: GatewayConfig): ApiType;
21
+ /**
22
+ * Find backend by API key
23
+ */
24
+ export declare function findBackendByApiKey(apiKey: string, config: GatewayConfig): {
25
+ name: string;
26
+ backend: typeof config.backends[string];
27
+ } | null;
28
+ /**
29
+ * Find default backend for an API type
30
+ */
31
+ export declare function findDefaultBackend(apiType: ApiType, config: GatewayConfig): {
32
+ name: string;
33
+ backend: typeof config.backends[string];
34
+ } | null;
35
+ /**
36
+ * Find backend by request path prefix
37
+ * Matches the longest pathPrefix that is a prefix of the request path
38
+ */
39
+ export declare function findBackendByPathPrefix(requestPath: string, config: GatewayConfig): {
40
+ name: string;
41
+ backend: typeof config.backends[string];
42
+ } | null;
43
+ /**
44
+ * Find backend by model name
45
+ */
46
+ export declare function findBackendByModel(modelName: string, config: GatewayConfig): {
47
+ name: string;
48
+ backend: typeof config.backends[string];
49
+ } | null;
50
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAIzD;;GAEG;AACH,wBAAgB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,aAAa,CAyB7D;AAmFD;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAkB1D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUlD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAM9E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAOlE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,aAAa,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAelE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAclE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,GACpB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAOlE"}