@graphty/remote-logger 1.2.2 → 1.3.0

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 (84) hide show
  1. package/README.md +53 -2
  2. package/dist/bundle/browser-entry.d.ts +34 -0
  3. package/dist/bundle/browser-entry.d.ts.map +1 -0
  4. package/dist/bundle/browser-entry.js +129 -0
  5. package/dist/bundle/browser-entry.js.map +1 -0
  6. package/dist/client/RemoteLogClient.d.ts +2 -1
  7. package/dist/client/RemoteLogClient.d.ts.map +1 -1
  8. package/dist/client/RemoteLogClient.js +20 -10
  9. package/dist/client/RemoteLogClient.js.map +1 -1
  10. package/dist/client/types.d.ts +6 -0
  11. package/dist/client/types.d.ts.map +1 -1
  12. package/dist/mcp/index.d.ts +1 -1
  13. package/dist/mcp/index.d.ts.map +1 -1
  14. package/dist/mcp/index.js +20 -1
  15. package/dist/mcp/index.js.map +1 -1
  16. package/dist/mcp/mcp-server.d.ts +5 -0
  17. package/dist/mcp/mcp-server.d.ts.map +1 -1
  18. package/dist/mcp/mcp-server.js +54 -8
  19. package/dist/mcp/mcp-server.js.map +1 -1
  20. package/dist/mcp/tools/index.d.ts +6 -6
  21. package/dist/mcp/tools/index.d.ts.map +1 -1
  22. package/dist/mcp/tools/index.js +1 -1
  23. package/dist/mcp/tools/index.js.map +1 -1
  24. package/dist/mcp/tools/logs-clear.d.ts +1 -2
  25. package/dist/mcp/tools/logs-clear.d.ts.map +1 -1
  26. package/dist/mcp/tools/logs-get-all.d.ts +1 -2
  27. package/dist/mcp/tools/logs-get-all.d.ts.map +1 -1
  28. package/dist/mcp/tools/logs-get-errors.d.ts +1 -2
  29. package/dist/mcp/tools/logs-get-errors.d.ts.map +1 -1
  30. package/dist/mcp/tools/logs-get-file-path.d.ts +8 -2
  31. package/dist/mcp/tools/logs-get-file-path.d.ts.map +1 -1
  32. package/dist/mcp/tools/logs-get-file-path.js +1 -1
  33. package/dist/mcp/tools/logs-get-file-path.js.map +1 -1
  34. package/dist/mcp/tools/logs-receive.d.ts +9 -10
  35. package/dist/mcp/tools/logs-receive.d.ts.map +1 -1
  36. package/dist/mcp/tools/logs-search.d.ts +1 -2
  37. package/dist/mcp/tools/logs-search.d.ts.map +1 -1
  38. package/dist/mcp/tools/logs-status.d.ts.map +1 -1
  39. package/dist/mcp/tools/logs-status.js +4 -1
  40. package/dist/mcp/tools/logs-status.js.map +1 -1
  41. package/dist/remote-logger.browser.js +166 -0
  42. package/dist/remote-logger.browser.js.map +1 -0
  43. package/dist/server/dual-server.d.ts +7 -4
  44. package/dist/server/dual-server.d.ts.map +1 -1
  45. package/dist/server/dual-server.js +124 -50
  46. package/dist/server/dual-server.js.map +1 -1
  47. package/dist/server/log-server.d.ts +12 -2
  48. package/dist/server/log-server.d.ts.map +1 -1
  49. package/dist/server/log-server.js +109 -63
  50. package/dist/server/log-server.js.map +1 -1
  51. package/dist/server/log-storage.d.ts +4 -0
  52. package/dist/server/log-storage.d.ts.map +1 -1
  53. package/dist/server/log-storage.js.map +1 -1
  54. package/dist/server/proxy.d.ts +39 -0
  55. package/dist/server/proxy.d.ts.map +1 -0
  56. package/dist/server/proxy.js +290 -0
  57. package/dist/server/proxy.js.map +1 -0
  58. package/dist/server/self-signed-cert.d.ts +9 -0
  59. package/dist/server/self-signed-cert.d.ts.map +1 -1
  60. package/dist/server/self-signed-cert.js +9 -0
  61. package/dist/server/self-signed-cert.js.map +1 -1
  62. package/dist/ui/ConsoleCaptureUI.d.ts.map +1 -1
  63. package/dist/ui/ConsoleCaptureUI.js +6 -1
  64. package/dist/ui/ConsoleCaptureUI.js.map +1 -1
  65. package/package.json +7 -2
  66. package/src/bundle/browser-entry.ts +157 -0
  67. package/src/client/RemoteLogClient.ts +22 -11
  68. package/src/client/types.ts +6 -0
  69. package/src/mcp/index.ts +42 -0
  70. package/src/mcp/mcp-server.ts +54 -8
  71. package/src/mcp/tools/index.ts +7 -0
  72. package/src/mcp/tools/logs-clear.ts +1 -1
  73. package/src/mcp/tools/logs-get-all.ts +1 -1
  74. package/src/mcp/tools/logs-get-errors.ts +1 -1
  75. package/src/mcp/tools/logs-get-file-path.ts +2 -2
  76. package/src/mcp/tools/logs-receive.ts +1 -1
  77. package/src/mcp/tools/logs-search.ts +1 -1
  78. package/src/mcp/tools/logs-status.ts +4 -1
  79. package/src/server/dual-server.ts +165 -57
  80. package/src/server/log-server.ts +126 -68
  81. package/src/server/log-storage.ts +4 -0
  82. package/src/server/proxy.ts +357 -0
  83. package/src/server/self-signed-cert.ts +9 -0
  84. package/src/ui/ConsoleCaptureUI.ts +6 -1
@@ -5,7 +5,7 @@
5
5
  export { logsClearHandler, logsClearInputSchema, logsClearTool, } from "./logs-clear.js";
6
6
  export { logsGetAllHandler, logsGetAllInputSchema, logsGetAllTool, } from "./logs-get-all.js";
7
7
  export { logsGetErrorsHandler, logsGetErrorsInputSchema, logsGetErrorsTool, } from "./logs-get-errors.js";
8
- export { logsGetFilePathHandler, logsGetFilePathInputSchema, logsGetFilePathTool, } from "./logs-get-file-path.js";
8
+ export { getLogFilePath, logsGetFilePathHandler, logsGetFilePathInputSchema, logsGetFilePathTool, } from "./logs-get-file-path.js";
9
9
  export { logsGetRecentHandler, logsGetRecentInputSchema, logsGetRecentTool, } from "./logs-get-recent.js";
10
10
  export { logsListSessionsHandler, logsListSessionsInputSchema, logsListSessionsTool, } from "./logs-list-sessions.js";
11
11
  export { logsReceiveHandler, logsReceiveInputSchema, logsReceiveTool, } from "./logs-receive.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/tools/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,gBAAgB,EAEhB,oBAAoB,EACpB,aAAa,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,iBAAiB,EAEjB,qBAAqB,EACrB,cAAc,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,oBAAoB,EAEpB,wBAAwB,EACxB,iBAAiB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACH,sBAAsB,EAEtB,0BAA0B,EAC1B,mBAAmB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACH,oBAAoB,EAEpB,wBAAwB,EAExB,iBAAiB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACH,uBAAuB,EAEvB,2BAA2B,EAE3B,oBAAoB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACH,kBAAkB,EAElB,sBAAsB,EACtB,eAAe,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,iBAAiB,EAEjB,qBAAqB,EACrB,cAAc,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACH,iBAAiB,EAEjB,qBAAqB,EAErB,cAAc,GACjB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp/tools/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,gBAAgB,EAEhB,oBAAoB,EAEpB,aAAa,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,iBAAiB,EAEjB,qBAAqB,EAErB,cAAc,GACjB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,oBAAoB,EAEpB,wBAAwB,EAExB,iBAAiB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACH,cAAc,EACd,sBAAsB,EAEtB,0BAA0B,EAE1B,mBAAmB,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACH,oBAAoB,EAEpB,wBAAwB,EAExB,iBAAiB,GACpB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACH,uBAAuB,EAEvB,2BAA2B,EAE3B,oBAAoB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACH,kBAAkB,EAElB,sBAAsB,EAEtB,eAAe,GAClB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,iBAAiB,EAEjB,qBAAqB,EAErB,cAAc,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACH,iBAAiB,EAEjB,qBAAqB,EAErB,cAAc,GACjB,MAAM,kBAAkB,CAAC"}
@@ -32,7 +32,7 @@ export type LogsClearInput = z.infer<typeof logsClearInputSchema>;
32
32
  /**
33
33
  * Output type for the logs_clear handler.
34
34
  */
35
- interface LogsClearOutput {
35
+ export interface LogsClearOutput {
36
36
  /** Whether the operation succeeded */
37
37
  success: boolean;
38
38
  /** Number of sessions cleared */
@@ -73,5 +73,4 @@ export declare const logsClearTool: {
73
73
  confirm?: boolean | undefined;
74
74
  }>;
75
75
  };
76
- export {};
77
76
  //# sourceMappingURL=logs-clear.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs-clear.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-clear.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,oBAAoB;IAC7B,mGAAmG;;IAEnG,wEAAwE;;IAExE,iFAAiF;;;;;;;;;;EAEnF,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;GAEG;AACH,UAAU,eAAe;IACrB,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAC/B,OAAO,CAAC,eAAe,CAAC,CAmB1B;AAED;;GAEG;AACH,eAAO,MAAM,aAAa;;;;QA7DtB,mGAAmG;;QAEnG,wEAAwE;;QAExE,iFAAiF;;;;;;;;;;;CAkEpF,CAAC"}
1
+ {"version":3,"file":"logs-clear.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-clear.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D;;GAEG;AACH,eAAO,MAAM,oBAAoB;IAC7B,mGAAmG;;IAEnG,wEAAwE;;IAExE,iFAAiF;;;;;;;;;;EAEnF,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,GAC/B,OAAO,CAAC,eAAe,CAAC,CAmB1B;AAED;;GAEG;AACH,eAAO,MAAM,aAAa;;;;QA7DtB,mGAAmG;;QAEnG,wEAAwE;;QAExE,iFAAiF;;;;;;;;;;;CAkEpF,CAAC"}
@@ -24,7 +24,7 @@ export type LogsGetAllInput = z.infer<typeof logsGetAllInputSchema>;
24
24
  /**
25
25
  * Output type for the logs_get_all handler.
26
26
  */
27
- interface LogsGetAllOutput {
27
+ export interface LogsGetAllOutput {
28
28
  /** Logs grouped by session ID */
29
29
  sessions: Record<string, LogEntry[]>;
30
30
  /** Number of sessions */
@@ -57,5 +57,4 @@ export declare const logsGetAllTool: {
57
57
  projectMarker?: string | undefined;
58
58
  }>;
59
59
  };
60
- export {};
61
60
  //# sourceMappingURL=logs-get-all.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs-get-all.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-get-all.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAExE;;GAEG;AACH,eAAO,MAAM,qBAAqB;IAC9B,wFAAwF;;;;;;EAE1F,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,UAAU,gBAAgB;IACtB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrC,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC7B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAgB3B;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;QAtDvB,wFAAwF;;;;;;;CA8D3F,CAAC"}
1
+ {"version":3,"file":"logs-get-all.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-get-all.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAExE;;GAEG;AACH,eAAO,MAAM,qBAAqB;IAC9B,wFAAwF;;;;;;EAE1F,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IACrC,yBAAyB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC7B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,OAAO,CAAC,eAAe,CAAC,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAgB3B;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;QAtDvB,wFAAwF;;;;;;;CA8D3F,CAAC"}
@@ -28,7 +28,7 @@ export type LogsGetErrorsInput = z.infer<typeof logsGetErrorsInputSchema>;
28
28
  /**
29
29
  * Output type for the logs_get_errors handler.
30
30
  */
31
- interface LogsGetErrorsOutput {
31
+ export interface LogsGetErrorsOutput {
32
32
  /** Array of ERROR level log entries */
33
33
  errors: LogEntryWithSession[];
34
34
  /** Number of errors returned */
@@ -62,5 +62,4 @@ export declare const logsGetErrorsTool: {
62
62
  since?: string | undefined;
63
63
  }>;
64
64
  };
65
- export {};
66
65
  //# sourceMappingURL=logs-get-errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs-get-errors.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-get-errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,wBAAwB;IACjC,uFAAuF;;IAEvF,gGAAgG;;;;;;;;EAElG,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;GAEG;AACH,UAAU,mBAAmB;IACzB,uCAAuC;IACvC,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAChC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACnC,OAAO,CAAC,mBAAmB,CAAC,CAU9B;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;QA/C1B,uFAAuF;;QAEvF,gGAAgG;;;;;;;;;CAqDnG,CAAC"}
1
+ {"version":3,"file":"logs-get-errors.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-get-errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,wBAAwB;IACjC,uFAAuF;;IAEvF,gGAAgG;;;;;;;;EAElG,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC,uCAAuC;IACvC,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAChC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACnC,OAAO,CAAC,mBAAmB,CAAC,CAU9B;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB;;;;QA/C1B,uFAAuF;;QAEvF,gGAAgG;;;;;;;;;CAqDnG,CAAC"}
@@ -28,7 +28,7 @@ export type LogsGetFilePathInput = z.infer<typeof logsGetFilePathInputSchema>;
28
28
  /**
29
29
  * Output type for the logs_get_file_path handler.
30
30
  */
31
- interface LogsGetFilePathOutput {
31
+ export interface LogsGetFilePathOutput {
32
32
  /** Full path to the JSONL log file */
33
33
  path: string;
34
34
  /** Whether the file exists */
@@ -36,6 +36,13 @@ interface LogsGetFilePathOutput {
36
36
  /** File size in bytes (0 if file doesn't exist) */
37
37
  size: number;
38
38
  }
39
+ /**
40
+ * Get the default JSONL file path for a project marker.
41
+ * This is used when no JsonlWriter is configured.
42
+ * @param projectMarker - The project marker
43
+ * @returns Full path to the JSONL file
44
+ */
45
+ export declare function getLogFilePath(projectMarker: string): string;
39
46
  /**
40
47
  * Handler for the logs_get_file_path tool.
41
48
  *
@@ -65,5 +72,4 @@ export declare const logsGetFilePathTool: {
65
72
  workingDirectory?: string | undefined;
66
73
  }>;
67
74
  };
68
- export {};
69
75
  //# sourceMappingURL=logs-get-file-path.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs-get-file-path.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-get-file-path.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAG9D;;GAEG;AACH,eAAO,MAAM,0BAA0B;IACnC,iGAAiG;;IAEjG,qFAAqF;;;;;;;;EAEvF,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E;;GAEG;AACH,UAAU,qBAAqB;IAC3B,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;CAChB;AAYD;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACrC,OAAO,CAAC,qBAAqB,CAAC,CA2ChC;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;QA7F5B,iGAAiG;;QAEjG,qFAAqF;;;;;;;;;CAmGxF,CAAC"}
1
+ {"version":3,"file":"logs-get-file-path.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-get-file-path.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAG9D;;GAEG;AACH,eAAO,MAAM,0BAA0B;IACnC,iGAAiG;;IAEjG,qFAAqF;;;;;;;;EAEvF,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,OAAO,CAAC,oBAAoB,CAAC,GACrC,OAAO,CAAC,qBAAqB,CAAC,CA2ChC;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;QA7F5B,iGAAiG;;QAEjG,qFAAqF;;;;;;;;;CAmGxF,CAAC"}
@@ -24,7 +24,7 @@ export const logsGetFilePathInputSchema = z.object({
24
24
  * @param projectMarker - The project marker
25
25
  * @returns Full path to the JSONL file
26
26
  */
27
- function getLogFilePath(projectMarker) {
27
+ export function getLogFilePath(projectMarker) {
28
28
  return path.join(os.tmpdir(), "remote-logger", projectMarker, "logs.jsonl");
29
29
  }
30
30
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"logs-get-file-path.js","sourceRoot":"","sources":["../../../src/mcp/tools/logs-get-file-path.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAG5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,iGAAiG;IACjG,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,qFAAqF;IACrF,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAmBH;;;;;GAKG;AACH,SAAS,cAAc,CAAC,aAAqB;IACzC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAClC,OAAmB,EACnB,KAAoC;IAEpC,yBAAyB;IACzB,MAAM,aAAa,GAAG,oBAAoB,CAAC;QACvC,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;KAC3C,CAAC,CAAC;IAEH,qEAAqE;IACrE,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,WAAW;QACxB,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,aAAa,CAAC;QACxC,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;IAEpC,qCAAqC;IACrC,wDAAwD;IACxD,IAAI,WAAW,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QACtD,IAAI,KAAK,EAAE,CAAC;YACR,OAAO,OAAO,CAAC,OAAO,CAAC;gBACnB,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,IAAI,EAAE,KAAK,CAAC,IAAI;aACnB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,wCAAwC;IACxC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,GAAG,IAAI,CAAC;QACd,CAAC,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACL,mCAAmC;IACvC,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC;QACnB,IAAI,EAAE,QAAQ;QACd,MAAM;QACN,IAAI;KACP,CAAC,CAAC;AACP,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IAC/B,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EACP,yDAAyD;QACzD,kEAAkE;QAClE,qCAAqC;QACrC,2EAA2E;IAC/E,WAAW,EAAE,0BAA0B;CAC1C,CAAC"}
1
+ {"version":3,"file":"logs-get-file-path.js","sourceRoot":"","sources":["../../../src/mcp/tools/logs-get-file-path.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAG5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,iGAAiG;IACjG,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,qFAAqF;IACrF,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAmBH;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,aAAqB;IAChD,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAClC,OAAmB,EACnB,KAAoC;IAEpC,yBAAyB;IACzB,MAAM,aAAa,GAAG,oBAAoB,CAAC;QACvC,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB;KAC3C,CAAC,CAAC;IAEH,qEAAqE;IACrE,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,WAAW;QACxB,CAAC,CAAC,WAAW,CAAC,WAAW,CAAC,aAAa,CAAC;QACxC,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,CAAC;IAEpC,qCAAqC;IACrC,wDAAwD;IACxD,IAAI,WAAW,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,WAAW,CAAC,YAAY,CAAC,aAAa,CAAC,CAAC;QACtD,IAAI,KAAK,EAAE,CAAC;YACR,OAAO,OAAO,CAAC,OAAO,CAAC;gBACnB,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,IAAI,EAAE,KAAK,CAAC,IAAI;aACnB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,wCAAwC;IACxC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,IAAI,GAAG,CAAC,CAAC;IAEb,IAAI,CAAC;QACD,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACpC,MAAM,GAAG,IAAI,CAAC;QACd,CAAC,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACL,mCAAmC;IACvC,CAAC;IAED,OAAO,OAAO,CAAC,OAAO,CAAC;QACnB,IAAI,EAAE,QAAQ;QACd,MAAM;QACN,IAAI;KACP,CAAC,CAAC;AACP,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;IAC/B,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EACP,yDAAyD;QACzD,kEAAkE;QAClE,qCAAqC;QACrC,2EAA2E;IAC/E,WAAW,EAAE,0BAA0B;CAC1C,CAAC"}
@@ -23,14 +23,14 @@ export declare const logsReceiveInputSchema: z.ZodObject<{
23
23
  /** Additional structured data to attach to the log entry. */
24
24
  data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
25
25
  }, "strip", z.ZodTypeAny, {
26
+ time: string;
26
27
  level: string;
27
28
  message: string;
28
- time: string;
29
29
  data?: Record<string, unknown> | undefined;
30
30
  }, {
31
+ time: string;
31
32
  level: string;
32
33
  message: string;
33
- time: string;
34
34
  data?: Record<string, unknown> | undefined;
35
35
  }>, "many">;
36
36
  /** Project identifier for filtering. Derived from sessionId prefix if not provided. */
@@ -42,9 +42,9 @@ export declare const logsReceiveInputSchema: z.ZodObject<{
42
42
  }, "strip", z.ZodTypeAny, {
43
43
  sessionId: string;
44
44
  logs: {
45
+ time: string;
45
46
  level: string;
46
47
  message: string;
47
- time: string;
48
48
  data?: Record<string, unknown> | undefined;
49
49
  }[];
50
50
  projectMarker?: string | undefined;
@@ -53,9 +53,9 @@ export declare const logsReceiveInputSchema: z.ZodObject<{
53
53
  }, {
54
54
  sessionId: string;
55
55
  logs: {
56
+ time: string;
56
57
  level: string;
57
58
  message: string;
58
- time: string;
59
59
  data?: Record<string, unknown> | undefined;
60
60
  }[];
61
61
  projectMarker?: string | undefined;
@@ -69,7 +69,7 @@ export type LogsReceiveInput = z.infer<typeof logsReceiveInputSchema>;
69
69
  /**
70
70
  * Output type for the logs_receive handler.
71
71
  */
72
- interface LogsReceiveOutput {
72
+ export interface LogsReceiveOutput {
73
73
  /** Whether the operation succeeded */
74
74
  success: boolean;
75
75
  /** Number of logs stored */
@@ -107,14 +107,14 @@ export declare const logsReceiveTool: {
107
107
  /** Additional structured data to attach to the log entry. */
108
108
  data: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
109
109
  }, "strip", z.ZodTypeAny, {
110
+ time: string;
110
111
  level: string;
111
112
  message: string;
112
- time: string;
113
113
  data?: Record<string, unknown> | undefined;
114
114
  }, {
115
+ time: string;
115
116
  level: string;
116
117
  message: string;
117
- time: string;
118
118
  data?: Record<string, unknown> | undefined;
119
119
  }>, "many">;
120
120
  /** Project identifier for filtering. Derived from sessionId prefix if not provided. */
@@ -126,9 +126,9 @@ export declare const logsReceiveTool: {
126
126
  }, "strip", z.ZodTypeAny, {
127
127
  sessionId: string;
128
128
  logs: {
129
+ time: string;
129
130
  level: string;
130
131
  message: string;
131
- time: string;
132
132
  data?: Record<string, unknown> | undefined;
133
133
  }[];
134
134
  projectMarker?: string | undefined;
@@ -137,9 +137,9 @@ export declare const logsReceiveTool: {
137
137
  }, {
138
138
  sessionId: string;
139
139
  logs: {
140
+ time: string;
140
141
  level: string;
141
142
  message: string;
142
- time: string;
143
143
  data?: Record<string, unknown> | undefined;
144
144
  }[];
145
145
  projectMarker?: string | undefined;
@@ -147,5 +147,4 @@ export declare const logsReceiveTool: {
147
147
  pageUrl?: string | undefined;
148
148
  }>;
149
149
  };
150
- export {};
151
150
  //# sourceMappingURL=logs-receive.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs-receive.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-receive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAgB9D;;GAEG;AACH,eAAO,MAAM,sBAAsB;IAC/B,+EAA+E;;IAE/E,kEAAkE;;QAhBlE,iFAAiF;;QAEjF,+DAA+D;;QAE/D,4BAA4B;;QAE5B,6DAA6D;;;;;;;;;;;;;IAY7D,uFAAuF;;IAEvF,oDAAoD;;IAEpD,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;EAEnD,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;GAEG;AACH,UAAU,iBAAiB;IACvB,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,gBAAgB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAY5B;AAED;;GAEG;AACH,eAAO,MAAM,eAAe;;;;QA1DxB,+EAA+E;;QAE/E,kEAAkE;;YAhBlE,iFAAiF;;YAEjF,+DAA+D;;YAE/D,4BAA4B;;YAE5B,6DAA6D;;;;;;;;;;;;;QAY7D,uFAAuF;;QAEvF,oDAAoD;;QAEpD,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;CA0DpD,CAAC"}
1
+ {"version":3,"file":"logs-receive.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-receive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAgB9D;;GAEG;AACH,eAAO,MAAM,sBAAsB;IAC/B,+EAA+E;;IAE/E,kEAAkE;;QAhBlE,iFAAiF;;QAEjF,+DAA+D;;QAE/D,4BAA4B;;QAE5B,6DAA6D;;;;;;;;;;;;;IAY7D,uFAAuF;;IAEvF,oDAAoD;;IAEpD,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;EAEnD,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAC9B,sCAAsC;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAC9B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,gBAAgB,GACxB,OAAO,CAAC,iBAAiB,CAAC,CAY5B;AAED;;GAEG;AACH,eAAO,MAAM,eAAe;;;;QA1DxB,+EAA+E;;QAE/E,kEAAkE;;YAhBlE,iFAAiF;;YAEjF,+DAA+D;;YAE/D,4BAA4B;;YAE5B,6DAA6D;;;;;;;;;;;;;QAY7D,uFAAuF;;QAEvF,oDAAoD;;QAEpD,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;CA0DpD,CAAC"}
@@ -40,7 +40,7 @@ export type LogsSearchInput = z.infer<typeof logsSearchInputSchema>;
40
40
  /**
41
41
  * Output type for the logs_search handler.
42
42
  */
43
- interface LogsSearchOutput {
43
+ export interface LogsSearchOutput {
44
44
  /** Matching log entries */
45
45
  results: LogEntryWithSession[];
46
46
  /** Number of results returned */
@@ -88,5 +88,4 @@ export declare const logsSearchTool: {
88
88
  limit?: number | undefined;
89
89
  }>;
90
90
  };
91
- export {};
92
91
  //# sourceMappingURL=logs-search.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"logs-search.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-search.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,qBAAqB;IAC9B,sDAAsD;;IAEtD,wFAAwF;;IAExF,yFAAyF;;IAEzF,mEAAmE;;IAEnE,2EAA2E;;;;;;;;;;;;;;EAE7E,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,UAAU,gBAAgB;IACtB,2BAA2B;IAC3B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC7B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,eAAe,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA0B3B;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;QAvEvB,sDAAsD;;QAEtD,wFAAwF;;QAExF,yFAAyF;;QAEzF,mEAAmE;;QAEnE,2EAA2E;;;;;;;;;;;;;;;CAuE9E,CAAC"}
1
+ {"version":3,"file":"logs-search.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-search.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAEnF;;GAEG;AACH,eAAO,MAAM,qBAAqB;IAC9B,sDAAsD;;IAEtD,wFAAwF;;IAExF,yFAAyF;;IAEzF,mEAAmE;;IAEnE,2EAA2E;;;;;;;;;;;;;;EAE7E,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC7B,2BAA2B;IAC3B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC7B,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,eAAe,GACvB,OAAO,CAAC,gBAAgB,CAAC,CA0B3B;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;QAvEvB,sDAAsD;;QAEtD,wFAAwF;;QAExF,yFAAyF;;QAEzF,mEAAmE;;QAEnE,2EAA2E;;;;;;;;;;;;;;;CAuE9E,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"logs-status.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE5E;;GAEG;AACH,eAAO,MAAM,qBAAqB,gDAAe,CAAC;AAElD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IAClD,+BAA+B;IAC/B,WAAW,EAAE;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,GAAG,EAAE,MAAM,CAAC;KACf,CAAC;CACL;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAYhF;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;CAU1B,CAAC"}
1
+ {"version":3,"file":"logs-status.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/logs-status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE5E;;GAEG;AACH,eAAO,MAAM,qBAAqB,gDAAe,CAAC;AAElD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IAClD,+BAA+B;IAC/B,WAAW,EAAE;QACT,QAAQ,EAAE,MAAM,CAAC;QACjB,SAAS,EAAE,MAAM,CAAC;QAClB,GAAG,EAAE,MAAM,CAAC;KACf,CAAC;CACL;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAYhF;AAED;;GAEG;AACH,eAAO,MAAM,cAAc;;;;CAa1B,CAAC"}
@@ -36,9 +36,12 @@ export const logsStatusTool = {
36
36
  name: "logs_status",
37
37
  description: "Get the status of the remote log server. " +
38
38
  "Returns health metrics (uptime, session count, log count, memory usage), " +
39
- "HTTP endpoint configuration (port, host, URL for browser clients), " +
39
+ "HTTP endpoint configuration (port, host, URL for browser clients, script URL for zero-config injection, " +
40
+ "proxy base URL for debugging third-party sites), " +
40
41
  "and retention settings (how long logs are kept before automatic cleanup). " +
41
42
  "Use this to verify the server is running, find the endpoint URL for configuring browser clients, " +
43
+ "get the script URL (server.scriptUrl) for injecting via a script tag, " +
44
+ "get the proxy URL (server.proxyBaseUrl) for debugging third-party sites, " +
42
45
  "or check server configuration.",
43
46
  inputSchema: logsStatusInputSchema,
44
47
  };
@@ -1 +1 @@
1
- {"version":3,"file":"logs-status.js","sourceRoot":"","sources":["../../../src/mcp/tools/logs-status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAI5B;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAmBlD;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAmB;IACjD,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAEvC,OAAO,OAAO,CAAC,OAAO,CAAC;QACnB,GAAG,MAAM;QACT,WAAW,EAAE;YACT,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,GAAG,EAAE,QAAQ,CAAC,GAAG;SACpB;KACJ,CAAC,CAAC;AACP,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC1B,IAAI,EAAE,aAAa;IACnB,WAAW,EACP,2CAA2C;QAC3C,2EAA2E;QAC3E,qEAAqE;QACrE,4EAA4E;QAC5E,mGAAmG;QACnG,gCAAgC;IACpC,WAAW,EAAE,qBAAqB;CACrC,CAAC"}
1
+ {"version":3,"file":"logs-status.js","sourceRoot":"","sources":["../../../src/mcp/tools/logs-status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAI5B;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAmBlD;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAmB;IACjD,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAEvC,OAAO,OAAO,CAAC,OAAO,CAAC;QACnB,GAAG,MAAM;QACT,WAAW,EAAE;YACT,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,GAAG,EAAE,QAAQ,CAAC,GAAG;SACpB;KACJ,CAAC,CAAC;AACP,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC1B,IAAI,EAAE,aAAa;IACnB,WAAW,EACP,2CAA2C;QAC3C,2EAA2E;QAC3E,0GAA0G;QAC1G,mDAAmD;QACnD,4EAA4E;QAC5E,mGAAmG;QACnG,wEAAwE;QACxE,2EAA2E;QAC3E,gCAAgC;IACpC,WAAW,EAAE,qBAAqB;CACrC,CAAC"}
@@ -0,0 +1,166 @@
1
+ var RemoteLogger=(function(l){"use strict";function a(s){try{if(s==="__REMOTE_LOG_PROJECT_MARKER__")return typeof __REMOTE_LOG_PROJECT_MARKER__<"u"?__REMOTE_LOG_PROJECT_MARKER__:void 0;if(s==="__REMOTE_LOG_WORKTREE_PATH__")return typeof __REMOTE_LOG_WORKTREE_PATH__<"u"?__REMOTE_LOG_WORKTREE_PATH__:void 0}catch{return}}const f=1e3,m=3,y=1e3,b="session",w=5e3;function _(s){const e=Date.now().toString(36),t=Math.random().toString(36).substring(2,8);return`${s}-${e}-${t}`}class u{constructor(e){this.pendingLogs=[],this.batchTimer=null,this.isClosed=!1,this.flushPromise=null,this.throttleLastTimes=new Map,this.serverUrl=e.serverUrl,this.sessionId=_(e.sessionPrefix??b),this.batchIntervalMs=e.batchIntervalMs??f,this.maxRetries=e.maxRetries??m,this.retryDelayMs=e.retryDelayMs??y,this.throttlePatterns=e.throttlePatterns??[],this.timeoutMs=e.timeoutMs??w,this.projectMarker=e.projectMarker??a("__REMOTE_LOG_PROJECT_MARKER__"),this.worktreePath=e.worktreePath??a("__REMOTE_LOG_WORKTREE_PATH__")}shouldThrottle(e){const t=Date.now();for(const{pattern:o,intervalMs:i}of this.throttlePatterns)if(o.test(e)){const d=o.source,r=this.throttleLastTimes.get(d)??0;return t-r<i?!0:(this.throttleLastTimes.set(d,t),!1)}return!1}log(e,t,o){if(this.isClosed||this.shouldThrottle(t))return;const i={time:new Date().toISOString(),level:e,message:t,...o!==void 0&&{data:o}};this.pendingLogs.push(i),this.scheduleBatchSend()}scheduleBatchSend(){this.batchTimer!==null||this.isClosed||(this.batchTimer=setTimeout(()=>{this.batchTimer=null,this.sendBatch()},this.batchIntervalMs))}async sendBatch(){if(this.pendingLogs.length===0)return;const e=this.pendingLogs;this.pendingLogs=[],await this.sendWithRetry(e)}async sendWithRetry(e){let t=null;for(let o=0;o<=this.maxRetries;o++)try{await this.sendRequest(e);return}catch(i){if(t=i instanceof Error?i:new Error(String(i)),o<this.maxRetries){const d=this.retryDelayMs*Math.pow(2,o);await this.sleep(d)}}console.error("[RemoteLogClient] Failed to send logs after retries:",t?.message)}async sendRequest(e){const t={sessionId:this.sessionId,logs:e};this.projectMarker!==void 0&&(t.projectMarker=this.projectMarker),this.worktreePath!==void 0&&(t.worktreePath=this.worktreePath);const o=new AbortController,i=setTimeout(()=>{o.abort()},this.timeoutMs);try{const d=await fetch(`${this.serverUrl}/log`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t),signal:o.signal});if(!d.ok)throw new Error(`HTTP ${d.status}: ${d.statusText}`)}finally{clearTimeout(i)}}sleep(e){return new Promise(t=>setTimeout(t,e))}async flush(){this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.flushPromise!==null&&await this.flushPromise,this.pendingLogs.length>0&&(this.flushPromise=this.sendBatch(),await this.flushPromise,this.flushPromise=null)}async close(){this.isClosed||(this.isClosed=!0,await this.flush())}}const n=globalThis.console;class h{constructor(){this.logs=[],this.buttonContainer=null,this.originalMethods={log:n.log.bind(n),error:n.error.bind(n),warn:n.warn.bind(n),info:n.info.bind(n),debug:n.debug.bind(n)},this.interceptConsole(),this.createUI(),this.setupGlobalMethods()}interceptConsole(){const e=["log","error","warn","info","debug"];for(const t of e){const o=this.originalMethods[t];n[t]=(...i)=>{this.logs.push({type:t,args:i,timestamp:new Date().toISOString()}),this.updateButtonBadge(),o.apply(n,i)}}}createUI(){if(typeof document>"u")return;this.buttonContainer=document.createElement("div"),this.buttonContainer.id="console-capture-container",this.buttonContainer.innerHTML=`
2
+ <button id="console-capture-btn" style="
3
+ position: fixed;
4
+ top: 20px;
5
+ right: 20px;
6
+ width: 32px;
7
+ height: 32px;
8
+ border-radius: 16px;
9
+ background: rgba(128, 128, 128, 0.3);
10
+ color: rgba(255, 255, 255, 0.8);
11
+ border: 1px solid rgba(255, 255, 255, 0.2);
12
+ cursor: pointer;
13
+ box-shadow: 0 1px 4px rgba(0,0,0,0.1);
14
+ z-index: 99999;
15
+ font-size: 14px;
16
+ display: flex;
17
+ align-items: center;
18
+ justify-content: center;
19
+ transition: all 0.2s;
20
+ opacity: 0.6;
21
+ ">📋</button>
22
+ <div id="console-capture-menu" style="
23
+ position: fixed;
24
+ top: 60px;
25
+ right: 20px;
26
+ background: white;
27
+ border-radius: 8px;
28
+ box-shadow: 0 2px 20px rgba(0,0,0,0.2);
29
+ padding: 10px;
30
+ z-index: 99998;
31
+ display: none;
32
+ ">
33
+ <button id="cc-copy" style="
34
+ display: block;
35
+ width: 100%;
36
+ padding: 8px 16px;
37
+ margin: 4px 0;
38
+ border: none;
39
+ background: #4CAF50;
40
+ color: white;
41
+ border-radius: 4px;
42
+ cursor: pointer;
43
+ ">📋 Copy Logs</button>
44
+ <button id="cc-download" style="
45
+ display: block;
46
+ width: 100%;
47
+ padding: 8px 16px;
48
+ margin: 4px 0;
49
+ border: none;
50
+ background: #FF9800;
51
+ color: white;
52
+ border-radius: 4px;
53
+ cursor: pointer;
54
+ ">💾 Download</button>
55
+ <button id="cc-clear" style="
56
+ display: block;
57
+ width: 100%;
58
+ padding: 8px 16px;
59
+ margin: 4px 0;
60
+ border: none;
61
+ background: #f44336;
62
+ color: white;
63
+ border-radius: 4px;
64
+ cursor: pointer;
65
+ ">🗑️ Clear</button>
66
+ <button id="cc-show" style="
67
+ display: block;
68
+ width: 100%;
69
+ padding: 8px 16px;
70
+ margin: 4px 0;
71
+ border: none;
72
+ background: #9C27B0;
73
+ color: white;
74
+ border-radius: 4px;
75
+ cursor: pointer;
76
+ ">👁️ Show Logs</button>
77
+ <div style="
78
+ margin-top: 10px;
79
+ padding-top: 10px;
80
+ border-top: 1px solid #ddd;
81
+ font-size: 12px;
82
+ color: #666;
83
+ text-align: center;
84
+ ">
85
+ <div>Logs: <span id="cc-count">0</span></div>
86
+ </div>
87
+ </div>
88
+ `,document.body.appendChild(this.buttonContainer);const e=document.getElementById("console-capture-btn"),t=document.getElementById("console-capture-menu");if(e&&t){e.addEventListener("mouseenter",()=>{e.style.opacity="1",e.style.background="rgba(128, 128, 128, 0.5)"}),e.addEventListener("mouseleave",()=>{e.style.opacity="0.6",e.style.background="rgba(128, 128, 128, 0.3)"}),e.addEventListener("click",()=>{t.style.display=t.style.display==="none"?"block":"none"});const o=document.getElementById("cc-copy"),i=document.getElementById("cc-download"),d=document.getElementById("cc-clear"),r=document.getElementById("cc-show");o&&o.addEventListener("click",()=>{this.copyLogs(),t.style.display="none"}),i&&i.addEventListener("click",()=>{this.downloadLogs(),t.style.display="none"}),d&&d.addEventListener("click",()=>{this.clearLogs(),t.style.display="none"}),r&&r.addEventListener("click",()=>{this.showLogsModal(),t.style.display="none"}),document.addEventListener("click",c=>{this.buttonContainer&&!this.buttonContainer.contains(c.target)&&(t.style.display="none")})}}updateButtonBadge(){if(typeof document>"u")return;const e=document.getElementById("cc-count");e&&(e.textContent=String(this.logs.length))}formatLog(e){const t=e.args.map(o=>{if(typeof o=="string")return o;if(o instanceof Error)return`${o.name}: ${o.message}
89
+ ${o.stack??""}`;try{return JSON.stringify(o,null,2)}catch{return String(o)}}).join(" ");return`[${e.timestamp}] [${e.type.toUpperCase()}] ${t}`}setupGlobalMethods(){if(typeof window<"u"){const e=()=>[...this.logs];window.__console__={copy:()=>this.copyLogs(),download:()=>{this.downloadLogs()},clear:()=>{this.clearLogs()},get:()=>this.getLogs(),get logs(){return e()}}}}showCopySuccess(){if(typeof document>"u")return;const e=document.getElementById("console-capture-btn");e&&(e.innerHTML="✅",setTimeout(()=>{e.innerHTML="📋"},1500)),n.log("📋 Console logs copied to clipboard!")}showCopyError(){if(typeof document>"u")return;const e=document.getElementById("console-capture-btn");e&&(e.innerHTML="❌",setTimeout(()=>{e.innerHTML="📋"},1500)),n.log("❌ Failed to copy to clipboard. Here are your logs:"),n.log("═".repeat(50)),n.log(this.getLogs()),n.log("═".repeat(50))}copyUsingTextarea(e){if(typeof document>"u")return;const t=document.createElement("textarea");t.value=e,t.style.cssText="position: absolute; left: -9999px; top: -9999px;",document.body.appendChild(t),t.select(),t.setSelectionRange(0,99999);try{document.execCommand("copy")?this.showCopySuccess():this.showCopyError()}catch{this.showCopyError()}finally{document.body.removeChild(t)}}showLogsModal(){if(typeof document>"u")return;const e=document.getElementById("console-logs-modal");e&&e.remove();const t=document.createElement("div");t.id="console-logs-modal",t.innerHTML=`
90
+ <div style="
91
+ position: fixed;
92
+ top: 0;
93
+ left: 0;
94
+ right: 0;
95
+ bottom: 0;
96
+ background: rgba(0,0,0,0.5);
97
+ z-index: 100001;
98
+ display: flex;
99
+ align-items: center;
100
+ justify-content: center;
101
+ ">
102
+ <div style="
103
+ background: white;
104
+ border-radius: 8px;
105
+ width: 90%;
106
+ max-width: 800px;
107
+ height: 85vh;
108
+ max-height: 85vh;
109
+ display: flex;
110
+ flex-direction: column;
111
+ box-shadow: 0 4px 20px rgba(0,0,0,0.3);
112
+ ">
113
+ <div style="
114
+ padding: 16px;
115
+ border-bottom: 1px solid #ddd;
116
+ display: flex;
117
+ justify-content: space-between;
118
+ align-items: center;
119
+ ">
120
+ <h3 style="margin: 0; color: #333;">Console Logs</h3>
121
+ <button id="close-modal" style="
122
+ background: none;
123
+ border: none;
124
+ font-size: 24px;
125
+ cursor: pointer;
126
+ color: #666;
127
+ ">×</button>
128
+ </div>
129
+ <textarea id="logs-textarea" style="
130
+ flex: 1;
131
+ margin: 16px;
132
+ padding: 12px;
133
+ border: 1px solid #ddd;
134
+ border-radius: 4px;
135
+ font-family: monospace;
136
+ font-size: 12px;
137
+ resize: none;
138
+ background: #f5f5f5;
139
+ min-height: 50vh;
140
+ overflow-y: auto;
141
+ " readonly>${this.getLogs()}</textarea>
142
+ <div style="
143
+ padding: 16px;
144
+ border-top: 1px solid #ddd;
145
+ text-align: center;
146
+ ">
147
+ <button id="select-all-logs" style="
148
+ padding: 8px 24px;
149
+ background: #2196F3;
150
+ color: white;
151
+ border: none;
152
+ border-radius: 4px;
153
+ cursor: pointer;
154
+ font-size: 14px;
155
+ ">Select All</button>
156
+ <span style="
157
+ margin-left: 16px;
158
+ color: #666;
159
+ font-size: 14px;
160
+ ">Press Ctrl+C (or Cmd+C) to copy</span>
161
+ </div>
162
+ </div>
163
+ </div>
164
+ `,document.body.appendChild(t);const o=document.getElementById("close-modal");o&&o.addEventListener("click",()=>{t.remove()}),t.addEventListener("click",r=>{r.target===t.firstElementChild&&t.remove()});const i=document.getElementById("logs-textarea"),d=document.getElementById("select-all-logs");d&&i&&d.addEventListener("click",()=>{i.select(),i.focus()}),i&&setTimeout(()=>{i.select(),i.focus()},100)}getLogs(){return this.logs.map(e=>this.formatLog(e)).join(`
165
+ `)}clearLogs(){this.logs=[],this.updateButtonBadge(),n.log("🗑️ Console logs cleared")}async copyLogs(){const e=this.getLogs();try{typeof navigator<"u"&&navigator.clipboard&&navigator.clipboard.writeText?(await navigator.clipboard.writeText(e),this.showCopySuccess()):this.copyUsingTextarea(e)}catch{n.warn("Clipboard API failed, using fallback"),this.copyUsingTextarea(e)}}downloadLogs(){if(typeof document>"u")return;const e=this.getLogs(),t=new Blob([e],{type:"text/plain"}),o=URL.createObjectURL(t),d=`console-logs-${new Date().toISOString().replace(/[:.]/g,"-")}.txt`,r=document.createElement("a");r.href=o,r.download=d,document.body.appendChild(r),r.click(),document.body.removeChild(r),URL.revokeObjectURL(o),n.log("💾 Console logs downloaded!")}destroy(){if(n.log=this.originalMethods.log,n.error=this.originalMethods.error,n.warn=this.originalMethods.warn,n.info=this.originalMethods.info,n.debug=this.originalMethods.debug,typeof document<"u"&&this.buttonContainer&&this.buttonContainer.parentNode&&this.buttonContainer.parentNode.removeChild(this.buttonContainer),typeof document<"u"){const e=document.getElementById("console-logs-modal");e&&e.remove()}typeof window<"u"&&delete window.__console__}}const E={log:"LOG",warn:"WARN",error:"ERROR",info:"INFO",debug:"DEBUG"},p=["log","warn","error","info","debug"];function x(){if(typeof window<"u"&&window.__REMOTE_LOG_SERVER_URL__)return window.__REMOTE_LOG_SERVER_URL__;if(typeof document<"u"&&document.currentScript)try{return new URL(document.currentScript.src).origin}catch{}if(typeof window<"u"&&window.location)return window.location.origin}function L(){if(typeof document>"u"||!document.currentScript)return!1;try{const{src:s}=document.currentScript;return s?new URL(s).searchParams.get("ui")==="true":!1}catch{return!1}}function T(s){if(typeof s=="string")return s;if(s instanceof Error)return`${s.name}: ${s.message}`;try{return JSON.stringify(s)}catch{return String(s)}}function R(s){return s.map(T).join(" ")}function g(){const s=x();if(!s){console.warn("[RemoteLogger] Could not detect server URL. Set window.__REMOTE_LOG_SERVER_URL__ before loading.");return}const e=new u({serverUrl:s,sessionPrefix:"remote",batchIntervalMs:500}),t={};for(const r of p)t[r]=console[r],console[r]=(...c)=>{t[r].apply(console,c);const v=R(c);e.log(E[r],v)};let o;L()&&(o=new h);const d={client:e,ui:o,destroy:()=>{for(const r of p)console[r]=t[r];e.close(),o&&o.destroy(),typeof window<"u"&&delete window.__remoteLogger__}};return typeof window<"u"&&(window.__remoteLogger__=d),d}return g(),l.ConsoleCaptureUI=h,l.RemoteLogClient=u,l.initRemoteLogger=g,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"}),l})({});
166
+ //# sourceMappingURL=remote-logger.browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-logger.browser.js","sources":["../src/client/RemoteLogClient.ts","../src/ui/ConsoleCaptureUI.ts","../src/bundle/browser-entry.ts"],"sourcesContent":["/**\n * Browser client for sending log messages to a remote server.\n * Provides batching and automatic retry with exponential backoff.\n * @module client/RemoteLogClient\n */\n\nimport type { LogEntry, RemoteLogClientOptions, ThrottlePattern } from \"./types.js\";\n\n/**\n * Global variables that may be injected by the Vite plugin.\n * These provide automatic project marker detection.\n */\ndeclare const __REMOTE_LOG_PROJECT_MARKER__: string | undefined;\ndeclare const __REMOTE_LOG_WORKTREE_PATH__: string | undefined;\n\n/**\n * Safely read a global variable that may or may not be defined.\n * @param name - Name of the global variable\n * @returns The value of the global variable, or undefined if not defined\n */\nfunction getGlobalValue(name: \"__REMOTE_LOG_PROJECT_MARKER__\" | \"__REMOTE_LOG_WORKTREE_PATH__\"): string | undefined {\n try {\n if (name === \"__REMOTE_LOG_PROJECT_MARKER__\") {\n return typeof __REMOTE_LOG_PROJECT_MARKER__ !== \"undefined\" ? __REMOTE_LOG_PROJECT_MARKER__ : undefined;\n }\n if (name === \"__REMOTE_LOG_WORKTREE_PATH__\") {\n return typeof __REMOTE_LOG_WORKTREE_PATH__ !== \"undefined\" ? __REMOTE_LOG_WORKTREE_PATH__ : undefined;\n }\n } catch {\n // ReferenceError if the global is not defined at all\n return undefined;\n }\n return undefined;\n}\n\n/** Default configuration values */\nconst DEFAULT_BATCH_INTERVAL_MS = 1000;\nconst DEFAULT_MAX_RETRIES = 3;\nconst DEFAULT_RETRY_DELAY_MS = 1000;\nconst DEFAULT_SESSION_PREFIX = \"session\";\nconst DEFAULT_TIMEOUT_MS = 5000;\n\n/**\n * Generates a unique session ID with the given prefix.\n * Format: {prefix}-{timestamp}-{random}\n * @param prefix - The prefix to use for the session ID\n * @returns A unique session ID string\n */\nfunction generateSessionId(prefix: string): string {\n const timestamp = Date.now().toString(36);\n const random = Math.random().toString(36).substring(2, 8);\n return `${prefix}-${timestamp}-${random}`;\n}\n\n/**\n * Client for sending log messages to a remote logging server.\n *\n * Features:\n * - Batches multiple log entries before sending\n * - Automatic retry with exponential backoff on network failures\n * - Unique session ID for correlating logs\n * @example\n * ```typescript\n * const client = new RemoteLogClient({\n * serverUrl: \"http://localhost:9080\",\n * sessionPrefix: \"myapp\",\n * });\n *\n * client.log(\"INFO\", \"User logged in\", { userId: 123 });\n * client.log(\"DEBUG\", \"Loading data...\");\n *\n * // Flush immediately when needed\n * await client.flush();\n *\n * // Clean up when done\n * await client.close();\n * ```\n */\nexport class RemoteLogClient {\n /** Unique identifier for this logging session */\n readonly sessionId: string;\n\n private readonly serverUrl: string;\n private readonly batchIntervalMs: number;\n private readonly maxRetries: number;\n private readonly retryDelayMs: number;\n private readonly throttlePatterns: ThrottlePattern[];\n private readonly projectMarker: string | undefined;\n private readonly worktreePath: string | undefined;\n private readonly timeoutMs: number;\n\n private pendingLogs: LogEntry[] = [];\n private batchTimer: ReturnType<typeof setTimeout> | null = null;\n private isClosed = false;\n private flushPromise: Promise<void> | null = null;\n\n /** Tracks when each throttle pattern was last allowed through */\n private throttleLastTimes = new Map<string, number>();\n\n /**\n * Creates a new RemoteLogClient.\n * @param options - Configuration options\n */\n constructor(options: RemoteLogClientOptions) {\n this.serverUrl = options.serverUrl;\n this.sessionId = generateSessionId(options.sessionPrefix ?? DEFAULT_SESSION_PREFIX);\n this.batchIntervalMs = options.batchIntervalMs ?? DEFAULT_BATCH_INTERVAL_MS;\n this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;\n this.retryDelayMs = options.retryDelayMs ?? DEFAULT_RETRY_DELAY_MS;\n this.throttlePatterns = options.throttlePatterns ?? [];\n this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\n // Priority: explicit option > global variable\n this.projectMarker = options.projectMarker ?? getGlobalValue(\"__REMOTE_LOG_PROJECT_MARKER__\");\n this.worktreePath = options.worktreePath ?? getGlobalValue(\"__REMOTE_LOG_WORKTREE_PATH__\");\n }\n\n /**\n * Checks if a message should be throttled based on configured patterns.\n * Updates the last time tracking if the message is allowed through.\n * @param message - The message to check\n * @returns true if the message should be dropped (throttled)\n */\n private shouldThrottle(message: string): boolean {\n const now = Date.now();\n\n for (const { pattern, intervalMs } of this.throttlePatterns) {\n if (pattern.test(message)) {\n const key = pattern.source;\n const lastTime = this.throttleLastTimes.get(key) ?? 0;\n\n if (now - lastTime < intervalMs) {\n // Within throttle window, drop this message\n return true;\n }\n\n // Outside throttle window, update timestamp and allow through\n this.throttleLastTimes.set(key, now);\n return false;\n }\n }\n\n // No matching pattern, allow through\n return false;\n }\n\n /**\n * Logs a message at the specified level.\n * @param level - Log level (e.g., \"INFO\", \"DEBUG\", \"WARN\", \"ERROR\")\n * @param message - The log message\n * @param data - Optional additional data to include\n */\n log(level: string, message: string, data?: Record<string, unknown>): void {\n if (this.isClosed) {\n return;\n }\n\n // Check throttling before adding to buffer\n if (this.shouldThrottle(message)) {\n return;\n }\n\n const entry: LogEntry = {\n time: new Date().toISOString(),\n level,\n message,\n ...(data !== undefined && { data }),\n };\n\n this.pendingLogs.push(entry);\n this.scheduleBatchSend();\n }\n\n /**\n * Schedules a batch send after the configured interval.\n * If a timer is already scheduled, does nothing.\n */\n private scheduleBatchSend(): void {\n if (this.batchTimer !== null || this.isClosed) {\n return;\n }\n\n this.batchTimer = setTimeout(() => {\n this.batchTimer = null;\n void this.sendBatch();\n }, this.batchIntervalMs);\n }\n\n /**\n * Sends the current batch of logs to the server.\n * Uses retry logic with exponential backoff on failure.\n */\n private async sendBatch(): Promise<void> {\n if (this.pendingLogs.length === 0) {\n return;\n }\n\n // Take the current logs and clear the pending array\n const logsToSend = this.pendingLogs;\n this.pendingLogs = [];\n\n await this.sendWithRetry(logsToSend);\n }\n\n /**\n * Sends logs with retry logic using exponential backoff.\n * @param logs - The log entries to send\n */\n private async sendWithRetry(logs: LogEntry[]): Promise<void> {\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n await this.sendRequest(logs);\n return; // Success!\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt < this.maxRetries) {\n // Exponential backoff: delay * 2^attempt\n const delay = this.retryDelayMs * Math.pow(2, attempt);\n await this.sleep(delay);\n }\n }\n }\n\n // All retries exhausted - log the error but don't throw\n // In a browser context, we don't want to break the application\n console.error(\"[RemoteLogClient] Failed to send logs after retries:\", lastError?.message);\n }\n\n /**\n * Makes the actual HTTP request to send logs.\n * @param logs - The log entries to send\n * @throws Error if the request fails or times out\n */\n private async sendRequest(logs: LogEntry[]): Promise<void> {\n const requestBody: {\n sessionId: string;\n logs: LogEntry[];\n projectMarker?: string;\n worktreePath?: string;\n } = {\n sessionId: this.sessionId,\n logs,\n };\n\n // Only include these fields if they have values\n if (this.projectMarker !== undefined) {\n requestBody.projectMarker = this.projectMarker;\n }\n if (this.worktreePath !== undefined) {\n requestBody.worktreePath = this.worktreePath;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => { controller.abort(); }, this.timeoutMs);\n\n try {\n const response = await fetch(`${this.serverUrl}/log`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(requestBody),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Helper to sleep for the specified duration.\n * @param ms - Milliseconds to sleep\n * @returns A promise that resolves after the specified time\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Immediately flushes all pending logs to the server.\n * Useful before page unload or when immediate delivery is needed.\n */\n async flush(): Promise<void> {\n // Cancel any scheduled batch\n if (this.batchTimer !== null) {\n clearTimeout(this.batchTimer);\n this.batchTimer = null;\n }\n\n // Wait for any in-progress flush\n if (this.flushPromise !== null) {\n await this.flushPromise;\n }\n\n // Send any remaining logs\n if (this.pendingLogs.length > 0) {\n this.flushPromise = this.sendBatch();\n await this.flushPromise;\n this.flushPromise = null;\n }\n }\n\n /**\n * Closes the client, flushing any pending logs and stopping the batch timer.\n * After calling close(), no more logs will be accepted.\n */\n async close(): Promise<void> {\n if (this.isClosed) {\n return;\n }\n\n this.isClosed = true;\n\n // Flush remaining logs\n await this.flush();\n }\n}\n\n/**\n * Factory function to create a RemoteLogClient.\n * @param options - Configuration options\n * @returns A new RemoteLogClient instance\n * @example\n * ```typescript\n * const client = createRemoteLogClient({\n * serverUrl: \"http://localhost:9080\",\n * });\n * ```\n */\nexport function createRemoteLogClient(options: RemoteLogClientOptions): RemoteLogClient {\n return new RemoteLogClient(options);\n}\n","/**\n * ConsoleCaptureUI - Console capture with floating UI widget\n *\n * Intercepts console output (log, error, warn, info, debug) and provides\n * a floating button UI with copy, download, view, and clear functionality.\n *\n * Features:\n * - Floating button in top-right corner\n * - Menu with Copy, Download, Clear, and Show Logs options\n * - Works on mobile devices and in XR environments\n * - Global window.__console__ methods for programmatic access\n *\n * Usage:\n * import { initConsoleCaptureUI } from \"@graphty/remote-logger/ui\";\n * initConsoleCaptureUI();\n *\n * Or programmatically:\n * const ui = new ConsoleCaptureUI();\n * console.log(\"This is captured\");\n * ui.destroy(); // Clean up when done\n */\n\n// Extended window interface for global console methods\ndeclare global {\n interface Window {\n __console__?: {\n copy: () => Promise<void>;\n download: () => void;\n clear: () => void;\n get: () => string;\n logs: CapturedLogEntry[];\n };\n }\n}\n\n/** A single captured log entry */\ninterface CapturedLogEntry {\n type: string;\n args: unknown[];\n timestamp: string;\n}\n\n/** Console method names we intercept */\ntype ConsoleMethod = \"log\" | \"error\" | \"warn\" | \"info\" | \"debug\";\n\n// Get reference to the global console object\nconst globalConsole = globalThis.console;\n\n/**\n * ConsoleCaptureUI class - captures console output and provides floating UI widget\n */\nexport class ConsoleCaptureUI {\n private logs: CapturedLogEntry[] = [];\n private originalMethods: Record<ConsoleMethod, typeof globalConsole.log>;\n private buttonContainer: HTMLElement | null = null;\n\n /**\n * Creates a new ConsoleCaptureUI instance that intercepts console methods\n * and creates a floating UI widget\n */\n constructor() {\n // Store original methods at construction time\n this.originalMethods = {\n log: globalConsole.log.bind(globalConsole),\n error: globalConsole.error.bind(globalConsole),\n warn: globalConsole.warn.bind(globalConsole),\n info: globalConsole.info.bind(globalConsole),\n debug: globalConsole.debug.bind(globalConsole),\n };\n\n this.interceptConsole();\n this.createUI();\n this.setupGlobalMethods();\n }\n\n /**\n * Intercept all console methods to capture output\n */\n private interceptConsole(): void {\n const methods: ConsoleMethod[] = [\n \"log\",\n \"error\",\n \"warn\",\n \"info\",\n \"debug\",\n ];\n for (const method of methods) {\n const original = this.originalMethods[method];\n\n // Override the console method - this is intentional for this module\n globalConsole[method] = (...args: unknown[]): void => {\n // Capture the log entry\n this.logs.push({\n type: method,\n args: args,\n timestamp: new Date().toISOString(),\n });\n this.updateButtonBadge();\n // Still call the original method\n original.apply(globalConsole, args);\n };\n }\n }\n\n /**\n * Create the floating UI button and menu\n */\n private createUI(): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n // Create floating button container\n this.buttonContainer = document.createElement(\"div\");\n this.buttonContainer.id = \"console-capture-container\";\n this.buttonContainer.innerHTML = `\n <button id=\"console-capture-btn\" style=\"\n position: fixed;\n top: 20px;\n right: 20px;\n width: 32px;\n height: 32px;\n border-radius: 16px;\n background: rgba(128, 128, 128, 0.3);\n color: rgba(255, 255, 255, 0.8);\n border: 1px solid rgba(255, 255, 255, 0.2);\n cursor: pointer;\n box-shadow: 0 1px 4px rgba(0,0,0,0.1);\n z-index: 99999;\n font-size: 14px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n opacity: 0.6;\n \">📋</button>\n <div id=\"console-capture-menu\" style=\"\n position: fixed;\n top: 60px;\n right: 20px;\n background: white;\n border-radius: 8px;\n box-shadow: 0 2px 20px rgba(0,0,0,0.2);\n padding: 10px;\n z-index: 99998;\n display: none;\n \">\n <button id=\"cc-copy\" style=\"\n display: block;\n width: 100%;\n padding: 8px 16px;\n margin: 4px 0;\n border: none;\n background: #4CAF50;\n color: white;\n border-radius: 4px;\n cursor: pointer;\n \">📋 Copy Logs</button>\n <button id=\"cc-download\" style=\"\n display: block;\n width: 100%;\n padding: 8px 16px;\n margin: 4px 0;\n border: none;\n background: #FF9800;\n color: white;\n border-radius: 4px;\n cursor: pointer;\n \">💾 Download</button>\n <button id=\"cc-clear\" style=\"\n display: block;\n width: 100%;\n padding: 8px 16px;\n margin: 4px 0;\n border: none;\n background: #f44336;\n color: white;\n border-radius: 4px;\n cursor: pointer;\n \">🗑️ Clear</button>\n <button id=\"cc-show\" style=\"\n display: block;\n width: 100%;\n padding: 8px 16px;\n margin: 4px 0;\n border: none;\n background: #9C27B0;\n color: white;\n border-radius: 4px;\n cursor: pointer;\n \">👁️ Show Logs</button>\n <div style=\"\n margin-top: 10px;\n padding-top: 10px;\n border-top: 1px solid #ddd;\n font-size: 12px;\n color: #666;\n text-align: center;\n \">\n <div>Logs: <span id=\"cc-count\">0</span></div>\n </div>\n </div>\n `;\n\n document.body.appendChild(this.buttonContainer);\n\n // Add event listeners\n const btn = document.getElementById(\"console-capture-btn\");\n const menu = document.getElementById(\"console-capture-menu\");\n\n if (btn && menu) {\n // Add hover effect to make button more visible on hover\n btn.addEventListener(\"mouseenter\", () => {\n btn.style.opacity = \"1\";\n btn.style.background = \"rgba(128, 128, 128, 0.5)\";\n });\n\n btn.addEventListener(\"mouseleave\", () => {\n btn.style.opacity = \"0.6\";\n btn.style.background = \"rgba(128, 128, 128, 0.3)\";\n });\n\n btn.addEventListener(\"click\", () => {\n menu.style.display =\n menu.style.display === \"none\" ? \"block\" : \"none\";\n });\n\n const copyBtn = document.getElementById(\"cc-copy\");\n const downloadBtn = document.getElementById(\"cc-download\");\n const clearBtn = document.getElementById(\"cc-clear\");\n const showBtn = document.getElementById(\"cc-show\");\n\n if (copyBtn) {\n copyBtn.addEventListener(\"click\", () => {\n void this.copyLogs();\n menu.style.display = \"none\";\n });\n }\n\n if (downloadBtn) {\n downloadBtn.addEventListener(\"click\", () => {\n this.downloadLogs();\n menu.style.display = \"none\";\n });\n }\n\n if (clearBtn) {\n clearBtn.addEventListener(\"click\", () => {\n this.clearLogs();\n menu.style.display = \"none\";\n });\n }\n\n if (showBtn) {\n showBtn.addEventListener(\"click\", () => {\n this.showLogsModal();\n menu.style.display = \"none\";\n });\n }\n\n // Close menu when clicking outside\n document.addEventListener(\"click\", (e) => {\n if (\n this.buttonContainer &&\n !this.buttonContainer.contains(e.target as Node)\n ) {\n menu.style.display = \"none\";\n }\n });\n }\n }\n\n /**\n * Update the log count badge in the menu\n */\n private updateButtonBadge(): void {\n if (typeof document === \"undefined\") {\n return;\n }\n const count = document.getElementById(\"cc-count\");\n if (count) {\n count.textContent = String(this.logs.length);\n }\n }\n\n /**\n * Format a single log entry as a string\n * @param log - The log entry to format\n * @returns Formatted log string\n */\n private formatLog(log: CapturedLogEntry): string {\n const args = log.args\n .map((arg) => {\n if (typeof arg === \"string\") {\n return arg;\n }\n if (arg instanceof Error) {\n return `${arg.name}: ${arg.message}\\n${arg.stack ?? \"\"}`;\n }\n try {\n return JSON.stringify(arg, null, 2);\n } catch {\n return String(arg);\n }\n })\n .join(\" \");\n\n return `[${log.timestamp}] [${log.type.toUpperCase()}] ${args}`;\n }\n\n /**\n * Setup global window.__console__ methods for easy access\n */\n private setupGlobalMethods(): void {\n if (typeof window !== \"undefined\") {\n // Create a function that returns current logs to avoid stale reference\n const getCurrentLogs = (): CapturedLogEntry[] => [...this.logs];\n window.__console__ = {\n copy: () => this.copyLogs(),\n download: () => {\n this.downloadLogs();\n },\n clear: () => {\n this.clearLogs();\n },\n get: () => this.getLogs(),\n // Use getter to always return fresh copy of current logs\n get logs() {\n return getCurrentLogs();\n },\n };\n }\n }\n\n /**\n * Show success indicator on the button\n */\n private showCopySuccess(): void {\n if (typeof document === \"undefined\") {\n return;\n }\n const btn = document.getElementById(\"console-capture-btn\");\n if (btn) {\n btn.innerHTML = \"✅\";\n setTimeout(() => {\n btn.innerHTML = \"📋\";\n }, 1500);\n }\n globalConsole.log(\"📋 Console logs copied to clipboard!\");\n }\n\n /**\n * Show error indicator on the button and fallback message\n */\n private showCopyError(): void {\n if (typeof document === \"undefined\") {\n return;\n }\n const btn = document.getElementById(\"console-capture-btn\");\n if (btn) {\n btn.innerHTML = \"❌\";\n setTimeout(() => {\n btn.innerHTML = \"📋\";\n }, 1500);\n }\n\n // Show logs in console as fallback\n globalConsole.log(\n \"❌ Failed to copy to clipboard. Here are your logs:\"\n );\n globalConsole.log(\"═\".repeat(50));\n globalConsole.log(this.getLogs());\n globalConsole.log(\"═\".repeat(50));\n }\n\n /**\n * Fallback copy method using textarea (for mobile devices)\n * @param text - The text to copy\n */\n private copyUsingTextarea(text: string): void {\n if (typeof document === \"undefined\") {\n return;\n }\n // Create temporary textarea\n const textarea = document.createElement(\"textarea\");\n textarea.value = text;\n textarea.style.cssText =\n \"position: absolute; left: -9999px; top: -9999px;\";\n document.body.appendChild(textarea);\n\n // Select and copy\n textarea.select();\n textarea.setSelectionRange(0, 99999); // For mobile devices\n\n try {\n // execCommand is deprecated but still necessary as a fallback for:\n // - Older mobile browsers that don't support Clipboard API\n // - iOS Safari in certain contexts where Clipboard API fails\n // - XR/VR browsers with limited API support\n // This provides the best compatibility across all target platforms\n // eslint-disable-next-line @typescript-eslint/no-deprecated -- Required fallback for mobile/XR compatibility\n const success = document.execCommand(\"copy\");\n if (success) {\n this.showCopySuccess();\n } else {\n this.showCopyError();\n }\n } catch {\n this.showCopyError();\n } finally {\n document.body.removeChild(textarea);\n }\n }\n\n /**\n * Show a modal dialog with all captured logs\n */\n private showLogsModal(): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n // Remove existing modal if any\n const existing = document.getElementById(\"console-logs-modal\");\n if (existing) {\n existing.remove();\n }\n\n const modal = document.createElement(\"div\");\n modal.id = \"console-logs-modal\";\n modal.innerHTML = `\n <div style=\"\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0,0,0,0.5);\n z-index: 100001;\n display: flex;\n align-items: center;\n justify-content: center;\n \">\n <div style=\"\n background: white;\n border-radius: 8px;\n width: 90%;\n max-width: 800px;\n height: 85vh;\n max-height: 85vh;\n display: flex;\n flex-direction: column;\n box-shadow: 0 4px 20px rgba(0,0,0,0.3);\n \">\n <div style=\"\n padding: 16px;\n border-bottom: 1px solid #ddd;\n display: flex;\n justify-content: space-between;\n align-items: center;\n \">\n <h3 style=\"margin: 0; color: #333;\">Console Logs</h3>\n <button id=\"close-modal\" style=\"\n background: none;\n border: none;\n font-size: 24px;\n cursor: pointer;\n color: #666;\n \">×</button>\n </div>\n <textarea id=\"logs-textarea\" style=\"\n flex: 1;\n margin: 16px;\n padding: 12px;\n border: 1px solid #ddd;\n border-radius: 4px;\n font-family: monospace;\n font-size: 12px;\n resize: none;\n background: #f5f5f5;\n min-height: 50vh;\n overflow-y: auto;\n \" readonly>${this.getLogs()}</textarea>\n <div style=\"\n padding: 16px;\n border-top: 1px solid #ddd;\n text-align: center;\n \">\n <button id=\"select-all-logs\" style=\"\n padding: 8px 24px;\n background: #2196F3;\n color: white;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 14px;\n \">Select All</button>\n <span style=\"\n margin-left: 16px;\n color: #666;\n font-size: 14px;\n \">Press Ctrl+C (or Cmd+C) to copy</span>\n </div>\n </div>\n </div>\n `;\n\n document.body.appendChild(modal);\n\n // Event listeners\n const closeBtn = document.getElementById(\"close-modal\");\n if (closeBtn) {\n closeBtn.addEventListener(\"click\", () => {\n modal.remove();\n });\n }\n\n modal.addEventListener(\"click\", (e) => {\n if (e.target === modal.firstElementChild) {\n modal.remove();\n }\n });\n\n const textarea = document.getElementById(\n \"logs-textarea\"\n ) as HTMLTextAreaElement | null;\n const selectAllBtn = document.getElementById(\"select-all-logs\");\n\n if (selectAllBtn && textarea) {\n selectAllBtn.addEventListener(\"click\", () => {\n textarea.select();\n textarea.focus();\n });\n }\n\n // Auto-select on open\n if (textarea) {\n setTimeout(() => {\n textarea.select();\n textarea.focus();\n }, 100);\n }\n }\n\n /**\n * Get all captured logs as a formatted string\n * @returns Formatted log string with timestamps and levels\n */\n getLogs(): string {\n return this.logs.map((log) => this.formatLog(log)).join(\"\\n\");\n }\n\n /**\n * Clear all captured logs\n */\n clearLogs(): void {\n this.logs = [];\n this.updateButtonBadge();\n globalConsole.log(\"🗑️ Console logs cleared\");\n }\n\n /**\n * Copy logs to clipboard\n */\n async copyLogs(): Promise<void> {\n const text = this.getLogs();\n\n try {\n // Try modern clipboard API first\n if (\n typeof navigator !== \"undefined\" &&\n navigator.clipboard &&\n navigator.clipboard.writeText\n ) {\n await navigator.clipboard.writeText(text);\n this.showCopySuccess();\n } else {\n // Fallback method using textarea\n this.copyUsingTextarea(text);\n }\n } catch {\n // If modern API fails, try fallback\n globalConsole.warn(\"Clipboard API failed, using fallback\");\n this.copyUsingTextarea(text);\n }\n }\n\n /**\n * Download logs as a text file\n */\n downloadLogs(): void {\n if (typeof document === \"undefined\") {\n return;\n }\n\n const text = this.getLogs();\n const blob = new Blob([text], { type: \"text/plain\" });\n const url = URL.createObjectURL(blob);\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const filename = `console-logs-${timestamp}.txt`;\n\n const link = document.createElement(\"a\");\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n\n URL.revokeObjectURL(url);\n globalConsole.log(\"💾 Console logs downloaded!\");\n }\n\n /**\n * Restore original console methods and clean up UI\n */\n destroy(): void {\n // Restore original console methods\n globalConsole.log = this.originalMethods.log;\n globalConsole.error = this.originalMethods.error;\n globalConsole.warn = this.originalMethods.warn;\n globalConsole.info = this.originalMethods.info;\n globalConsole.debug = this.originalMethods.debug;\n\n // Remove UI elements\n if (\n typeof document !== \"undefined\" &&\n this.buttonContainer &&\n this.buttonContainer.parentNode\n ) {\n this.buttonContainer.parentNode.removeChild(this.buttonContainer);\n }\n\n // Remove modal if open\n if (typeof document !== \"undefined\") {\n const modal = document.getElementById(\"console-logs-modal\");\n if (modal) {\n modal.remove();\n }\n }\n\n // Remove global methods\n if (typeof window !== \"undefined\") {\n delete window.__console__;\n }\n }\n}\n\n/**\n * Convenience function to initialize ConsoleCaptureUI\n * @returns A new ConsoleCaptureUI instance\n */\nexport function initConsoleCaptureUI(): ConsoleCaptureUI {\n return new ConsoleCaptureUI();\n}\n","/**\n * Browser bundle entry point for the remote logger.\n *\n * When loaded as a script tag, this auto-initializes a RemoteLogClient\n * that intercepts console methods and forwards them to the server.\n *\n * Server URL detection priority:\n * 1. window.__REMOTE_LOG_SERVER_URL__ (injected by server when serving this file)\n * 2. document.currentScript.src (parse origin from script tag URL)\n * 3. window.location.origin (fallback)\n *\n * Exposes window.__remoteLogger__ for manual control.\n * @module bundle/browser-entry\n */\n\nimport { RemoteLogClient } from \"../client/RemoteLogClient.js\";\nimport { ConsoleCaptureUI } from \"../ui/ConsoleCaptureUI.js\";\n\ndeclare global {\n interface Window {\n __REMOTE_LOG_SERVER_URL__?: string;\n __remoteLogger__?: RemoteLoggerGlobal;\n }\n}\n\ntype ConsoleMethod = \"log\" | \"warn\" | \"error\" | \"info\" | \"debug\";\n\nconst CONSOLE_LEVEL_MAP: Record<ConsoleMethod, string> = {\n log: \"LOG\",\n warn: \"WARN\",\n error: \"ERROR\",\n info: \"INFO\",\n debug: \"DEBUG\",\n};\n\nconst INTERCEPTED_METHODS: ConsoleMethod[] = [\"log\", \"warn\", \"error\", \"info\", \"debug\"];\n\nexport interface RemoteLoggerGlobal {\n client: RemoteLogClient;\n ui?: ConsoleCaptureUI;\n destroy: () => void;\n}\n\nfunction detectServerUrl(): string | undefined {\n if (typeof window !== \"undefined\" && window.__REMOTE_LOG_SERVER_URL__) {\n return window.__REMOTE_LOG_SERVER_URL__;\n }\n\n if (typeof document !== \"undefined\" && document.currentScript) {\n try {\n const scriptUrl = new URL((document.currentScript as HTMLScriptElement).src);\n return scriptUrl.origin;\n } catch {\n // Invalid URL, fall through\n }\n }\n\n if (typeof window !== \"undefined\" && window.location) {\n return window.location.origin;\n }\n\n return undefined;\n}\n\nfunction shouldShowUI(): boolean {\n if (typeof document === \"undefined\" || !document.currentScript) {\n return false;\n }\n\n try {\n const {src} = (document.currentScript as HTMLScriptElement);\n if (!src) {return false;}\n const params = new URL(src).searchParams;\n return params.get(\"ui\") === \"true\";\n } catch {\n return false;\n }\n}\n\nfunction formatArg(arg: unknown): string {\n if (typeof arg === \"string\") {return arg;}\n if (arg instanceof Error) {return `${arg.name}: ${arg.message}`;}\n try {\n return JSON.stringify(arg);\n } catch {\n return String(arg);\n }\n}\n\nfunction formatArgs(args: unknown[]): string {\n return args.map(formatArg).join(\" \");\n}\n\n/**\n * Initialize the remote logger, intercepting console methods.\n * @returns The remote logger global object, or undefined if no server URL detected\n */\nexport function initRemoteLogger(): RemoteLoggerGlobal | undefined {\n const serverUrl = detectServerUrl();\n if (!serverUrl) {\n console.warn(\"[RemoteLogger] Could not detect server URL. Set window.__REMOTE_LOG_SERVER_URL__ before loading.\");\n return undefined;\n }\n\n const client = new RemoteLogClient({\n serverUrl,\n sessionPrefix: \"remote\",\n batchIntervalMs: 500,\n });\n\n const originalMethods: Record<ConsoleMethod, typeof console.log> = {} as Record<ConsoleMethod, typeof console.log>;\n\n for (const method of INTERCEPTED_METHODS) {\n // eslint-disable-next-line no-console\n originalMethods[method] = console[method];\n\n // eslint-disable-next-line no-console\n console[method] = (...args: unknown[]) => {\n originalMethods[method].apply(console, args);\n const message = formatArgs(args);\n client.log(CONSOLE_LEVEL_MAP[method], message);\n };\n }\n\n let ui: ConsoleCaptureUI | undefined;\n if (shouldShowUI()) {\n ui = new ConsoleCaptureUI();\n }\n\n const destroy = (): void => {\n for (const method of INTERCEPTED_METHODS) {\n // eslint-disable-next-line no-console\n console[method] = originalMethods[method];\n }\n void client.close();\n if (ui) {\n ui.destroy();\n }\n if (typeof window !== \"undefined\") {\n delete window.__remoteLogger__;\n }\n };\n\n const global: RemoteLoggerGlobal = { client, ui, destroy };\n\n if (typeof window !== \"undefined\") {\n window.__remoteLogger__ = global;\n }\n\n return global;\n}\n\n// Auto-initialize on load\ninitRemoteLogger();\n\n// Re-export for manual use via the IIFE global\nexport { ConsoleCaptureUI,RemoteLogClient };\n"],"names":["getGlobalValue","name","DEFAULT_BATCH_INTERVAL_MS","DEFAULT_MAX_RETRIES","DEFAULT_RETRY_DELAY_MS","DEFAULT_SESSION_PREFIX","DEFAULT_TIMEOUT_MS","generateSessionId","prefix","timestamp","random","RemoteLogClient","options","message","now","pattern","intervalMs","key","lastTime","level","data","entry","logsToSend","logs","lastError","attempt","error","delay","requestBody","controller","timeoutId","response","ms","resolve","globalConsole","ConsoleCaptureUI","methods","method","original","args","btn","menu","copyBtn","downloadBtn","clearBtn","showBtn","e","count","log","arg","getCurrentLogs","text","textarea","existing","modal","closeBtn","selectAllBtn","blob","url","filename","link","CONSOLE_LEVEL_MAP","INTERCEPTED_METHODS","detectServerUrl","shouldShowUI","src","formatArg","formatArgs","initRemoteLogger","serverUrl","client","originalMethods","ui","global"],"mappings":"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"}