@graphty/remote-logger 0.0.1 → 1.2.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 (138) hide show
  1. package/README.md +944 -28
  2. package/bin/remote-log-server.js +3 -0
  3. package/dist/client/RemoteLogClient.d.ts +116 -0
  4. package/dist/client/RemoteLogClient.d.ts.map +1 -0
  5. package/dist/client/RemoteLogClient.js +269 -0
  6. package/dist/client/RemoteLogClient.js.map +1 -0
  7. package/dist/client/index.d.ts +7 -0
  8. package/dist/client/index.d.ts.map +1 -0
  9. package/dist/client/index.js +6 -0
  10. package/dist/client/index.js.map +1 -0
  11. package/dist/client/types.d.ts +60 -0
  12. package/dist/client/types.d.ts.map +1 -0
  13. package/dist/client/types.js +6 -0
  14. package/dist/client/types.js.map +1 -0
  15. package/dist/index.d.ts +22 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +23 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/mcp/index.d.ts +9 -0
  20. package/dist/mcp/index.d.ts.map +1 -0
  21. package/dist/mcp/index.js +9 -0
  22. package/dist/mcp/index.js.map +1 -0
  23. package/dist/mcp/mcp-server.d.ts +32 -0
  24. package/dist/mcp/mcp-server.d.ts.map +1 -0
  25. package/dist/mcp/mcp-server.js +270 -0
  26. package/dist/mcp/mcp-server.js.map +1 -0
  27. package/dist/mcp/tools/index.d.ts +14 -0
  28. package/dist/mcp/tools/index.d.ts.map +1 -0
  29. package/dist/mcp/tools/index.js +14 -0
  30. package/dist/mcp/tools/index.js.map +1 -0
  31. package/dist/mcp/tools/logs-clear.d.ts +76 -0
  32. package/dist/mcp/tools/logs-clear.d.ts.map +1 -0
  33. package/dist/mcp/tools/logs-clear.js +58 -0
  34. package/dist/mcp/tools/logs-clear.js.map +1 -0
  35. package/dist/mcp/tools/logs-get-all.d.ts +60 -0
  36. package/dist/mcp/tools/logs-get-all.d.ts.map +1 -0
  37. package/dist/mcp/tools/logs-get-all.js +50 -0
  38. package/dist/mcp/tools/logs-get-all.js.map +1 -0
  39. package/dist/mcp/tools/logs-get-errors.d.ts +65 -0
  40. package/dist/mcp/tools/logs-get-errors.d.ts.map +1 -0
  41. package/dist/mcp/tools/logs-get-errors.js +46 -0
  42. package/dist/mcp/tools/logs-get-errors.js.map +1 -0
  43. package/dist/mcp/tools/logs-get-file-path.d.ts +75 -0
  44. package/dist/mcp/tools/logs-get-file-path.d.ts.map +1 -0
  45. package/dist/mcp/tools/logs-get-file-path.js +90 -0
  46. package/dist/mcp/tools/logs-get-file-path.js.map +1 -0
  47. package/dist/mcp/tools/logs-get-recent.d.ts +89 -0
  48. package/dist/mcp/tools/logs-get-recent.d.ts.map +1 -0
  49. package/dist/mcp/tools/logs-get-recent.js +74 -0
  50. package/dist/mcp/tools/logs-get-recent.js.map +1 -0
  51. package/dist/mcp/tools/logs-list-sessions.d.ts +64 -0
  52. package/dist/mcp/tools/logs-list-sessions.d.ts.map +1 -0
  53. package/dist/mcp/tools/logs-list-sessions.js +48 -0
  54. package/dist/mcp/tools/logs-list-sessions.js.map +1 -0
  55. package/dist/mcp/tools/logs-receive.d.ts +150 -0
  56. package/dist/mcp/tools/logs-receive.d.ts.map +1 -0
  57. package/dist/mcp/tools/logs-receive.js +68 -0
  58. package/dist/mcp/tools/logs-receive.js.map +1 -0
  59. package/dist/mcp/tools/logs-search.d.ts +91 -0
  60. package/dist/mcp/tools/logs-search.d.ts.map +1 -0
  61. package/dist/mcp/tools/logs-search.js +68 -0
  62. package/dist/mcp/tools/logs-search.js.map +1 -0
  63. package/dist/mcp/tools/logs-status.d.ts +45 -0
  64. package/dist/mcp/tools/logs-status.d.ts.map +1 -0
  65. package/dist/mcp/tools/logs-status.js +45 -0
  66. package/dist/mcp/tools/logs-status.js.map +1 -0
  67. package/dist/server/dual-server.d.ts +76 -0
  68. package/dist/server/dual-server.d.ts.map +1 -0
  69. package/dist/server/dual-server.js +214 -0
  70. package/dist/server/dual-server.js.map +1 -0
  71. package/dist/server/index.d.ts +12 -0
  72. package/dist/server/index.d.ts.map +1 -0
  73. package/dist/server/index.js +12 -0
  74. package/dist/server/index.js.map +1 -0
  75. package/dist/server/jsonl-writer.d.ts +93 -0
  76. package/dist/server/jsonl-writer.d.ts.map +1 -0
  77. package/dist/server/jsonl-writer.js +205 -0
  78. package/dist/server/jsonl-writer.js.map +1 -0
  79. package/dist/server/log-server.d.ts +126 -0
  80. package/dist/server/log-server.d.ts.map +1 -0
  81. package/dist/server/log-server.js +589 -0
  82. package/dist/server/log-server.js.map +1 -0
  83. package/dist/server/log-storage.d.ts +301 -0
  84. package/dist/server/log-storage.d.ts.map +1 -0
  85. package/dist/server/log-storage.js +408 -0
  86. package/dist/server/log-storage.js.map +1 -0
  87. package/dist/server/marker-utils.d.ts +69 -0
  88. package/dist/server/marker-utils.d.ts.map +1 -0
  89. package/dist/server/marker-utils.js +118 -0
  90. package/dist/server/marker-utils.js.map +1 -0
  91. package/dist/server/self-signed-cert.d.ts +30 -0
  92. package/dist/server/self-signed-cert.d.ts.map +1 -0
  93. package/dist/server/self-signed-cert.js +83 -0
  94. package/dist/server/self-signed-cert.js.map +1 -0
  95. package/dist/ui/ConsoleCaptureUI.d.ts +118 -0
  96. package/dist/ui/ConsoleCaptureUI.d.ts.map +1 -0
  97. package/dist/ui/ConsoleCaptureUI.js +571 -0
  98. package/dist/ui/ConsoleCaptureUI.js.map +1 -0
  99. package/dist/ui/index.d.ts +15 -0
  100. package/dist/ui/index.d.ts.map +1 -0
  101. package/dist/ui/index.js +15 -0
  102. package/dist/ui/index.js.map +1 -0
  103. package/dist/vite/index.d.ts +8 -0
  104. package/dist/vite/index.d.ts.map +1 -0
  105. package/dist/vite/index.js +8 -0
  106. package/dist/vite/index.js.map +1 -0
  107. package/dist/vite/plugin.d.ts +42 -0
  108. package/dist/vite/plugin.d.ts.map +1 -0
  109. package/dist/vite/plugin.js +46 -0
  110. package/dist/vite/plugin.js.map +1 -0
  111. package/package.json +90 -7
  112. package/src/client/RemoteLogClient.ts +328 -0
  113. package/src/client/index.ts +7 -0
  114. package/src/client/types.ts +62 -0
  115. package/src/index.ts +28 -0
  116. package/src/mcp/index.ts +25 -0
  117. package/src/mcp/mcp-server.ts +364 -0
  118. package/src/mcp/tools/index.ts +69 -0
  119. package/src/mcp/tools/logs-clear.ts +86 -0
  120. package/src/mcp/tools/logs-get-all.ts +78 -0
  121. package/src/mcp/tools/logs-get-errors.ts +71 -0
  122. package/src/mcp/tools/logs-get-file-path.ts +121 -0
  123. package/src/mcp/tools/logs-get-recent.ts +104 -0
  124. package/src/mcp/tools/logs-list-sessions.ts +71 -0
  125. package/src/mcp/tools/logs-receive.ts +96 -0
  126. package/src/mcp/tools/logs-search.ts +95 -0
  127. package/src/mcp/tools/logs-status.ts +69 -0
  128. package/src/server/dual-server.ts +308 -0
  129. package/src/server/index.ts +54 -0
  130. package/src/server/jsonl-writer.ts +277 -0
  131. package/src/server/log-server.ts +763 -0
  132. package/src/server/log-storage.ts +651 -0
  133. package/src/server/marker-utils.ts +144 -0
  134. package/src/server/self-signed-cert.ts +93 -0
  135. package/src/ui/ConsoleCaptureUI.ts +649 -0
  136. package/src/ui/index.ts +15 -0
  137. package/src/vite/index.ts +8 -0
  138. package/src/vite/plugin.ts +59 -0
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Server-side logging utilities.
3
+ * These are only meant to be run in Node.js, not in the browser.
4
+ * @module server
5
+ */
6
+ export { createDualServer, type DualServerOptions, type DualServerResult, } from "./dual-server.js";
7
+ export { type FileStats, type JsonlEntry, JsonlWriter, } from "./jsonl-writer.js";
8
+ export { clearLogs, createLogServer, type CreateLogServerOptions, type CreateLogServerResult, getJsonlWriter, getLogStorage, HELP_TEXT, type LogEntry, type LogServerOptions, main, parseArgs, type ParseArgsResult, setLogStorage, startLogServer, } from "./log-server.js";
9
+ export { type AddLogsOptions, type ClearFilter, type HealthStatus, type LogEntryWithSession, type LogFilter, LogStorage, type LogStorageOptions, type SearchOptions, type ServerConfig, type ServerMode, type ServerStatus, type SessionFilter, type SessionMetadata, } from "./log-storage.js";
10
+ export { extractMarkerFromPath, extractMarkerFromSessionId, type MarkerResolutionOptions, resolveProjectMarker, } from "./marker-utils.js";
11
+ export { certFilesExist, type GeneratedCert, generateSelfSignedCert, readCertFiles } from "./self-signed-cert.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACH,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACxB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACH,KAAK,SAAS,EACd,KAAK,UAAU,EACf,WAAW,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,SAAS,EACT,eAAe,EACf,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,cAAc,EACd,aAAa,EACb,SAAS,EACT,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,IAAI,EACJ,SAAS,EACT,KAAK,eAAe,EACpB,aAAa,EACb,cAAc,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACH,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,UAAU,EACV,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,eAAe,GACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACH,qBAAqB,EACrB,0BAA0B,EAC1B,KAAK,uBAAuB,EAC5B,oBAAoB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,KAAK,aAAa,EAAE,sBAAsB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Server-side logging utilities.
3
+ * These are only meant to be run in Node.js, not in the browser.
4
+ * @module server
5
+ */
6
+ export { createDualServer, } from "./dual-server.js";
7
+ export { JsonlWriter, } from "./jsonl-writer.js";
8
+ export { clearLogs, createLogServer, getJsonlWriter, getLogStorage, HELP_TEXT, main, parseArgs, setLogStorage, startLogServer, } from "./log-server.js";
9
+ export { LogStorage, } from "./log-storage.js";
10
+ export { extractMarkerFromPath, extractMarkerFromSessionId, resolveProjectMarker, } from "./marker-utils.js";
11
+ export { certFilesExist, generateSelfSignedCert, readCertFiles } from "./self-signed-cert.js";
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EACH,gBAAgB,GAGnB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAGH,WAAW,GACd,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACH,SAAS,EACT,eAAe,EAGf,cAAc,EACd,aAAa,EACb,SAAS,EAGT,IAAI,EACJ,SAAS,EAET,aAAa,EACb,cAAc,GACjB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAMH,UAAU,GAQb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACH,qBAAqB,EACrB,0BAA0B,EAE1B,oBAAoB,GACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAsB,sBAAsB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * JSONL file writer for streaming logs to disk.
3
+ *
4
+ * Organizes logs by project marker in the temp directory:
5
+ * {baseDir}/{marker}/logs.jsonl
6
+ * @module server/jsonl-writer
7
+ */
8
+ /**
9
+ * A JSONL log entry.
10
+ */
11
+ export interface JsonlEntry {
12
+ /** ISO 8601 timestamp when the log was created */
13
+ time: string;
14
+ /** Log level (e.g., "INFO", "DEBUG", "WARN", "ERROR") */
15
+ level: string;
16
+ /** The log message */
17
+ message: string;
18
+ /** Session ID this log belongs to */
19
+ sessionId: string;
20
+ /** Optional additional data */
21
+ data?: Record<string, unknown>;
22
+ }
23
+ /**
24
+ * File statistics.
25
+ */
26
+ export interface FileStats {
27
+ /** Whether the file exists */
28
+ exists: boolean;
29
+ /** File size in bytes */
30
+ size: number;
31
+ }
32
+ /**
33
+ * JSONL file writer that streams log entries to disk.
34
+ *
35
+ * Each project marker gets its own log file in the structure:
36
+ * {baseDir}/{marker}/logs.jsonl
37
+ */
38
+ export declare class JsonlWriter {
39
+ private readonly baseDir;
40
+ private readonly markerStates;
41
+ private closed;
42
+ /**
43
+ * Create a new JsonlWriter.
44
+ * @param baseDir - Base directory for log files (e.g., os.tmpdir()/remote-logger)
45
+ */
46
+ constructor(baseDir: string);
47
+ /**
48
+ * Get the file path for a project marker.
49
+ * @param projectMarker - The project marker
50
+ * @returns Full path to the JSONL file
51
+ */
52
+ getFilePath(projectMarker: string): string;
53
+ /**
54
+ * Get file statistics for a project marker's log file.
55
+ * @param projectMarker - The project marker
56
+ * @returns File stats or null if file doesn't exist
57
+ */
58
+ getFileStats(projectMarker: string): FileStats | null;
59
+ /**
60
+ * Write a log entry to the appropriate file.
61
+ * @param projectMarker - The project marker
62
+ * @param entry - The log entry to write
63
+ * @returns Promise that resolves when the write is queued
64
+ */
65
+ write(projectMarker: string, entry: JsonlEntry): Promise<void>;
66
+ /**
67
+ * Flush all pending writes to disk.
68
+ */
69
+ flush(): Promise<void>;
70
+ /**
71
+ * Close all file handles.
72
+ */
73
+ close(): Promise<void>;
74
+ /**
75
+ * Ensure the marker state exists, creating file if needed.
76
+ * @param projectMarker - The project marker
77
+ * @returns The marker state
78
+ */
79
+ private ensureMarkerState;
80
+ /**
81
+ * Flush the buffer for a marker state.
82
+ * @param state - The marker state to flush
83
+ */
84
+ private flushBuffer;
85
+ /**
86
+ * Clean up old project log files based on directory modification time.
87
+ * Removes entire project directories that haven't been modified within the retention period.
88
+ * @param retentionDays - Number of days to retain logs
89
+ * @returns Number of project directories removed
90
+ */
91
+ cleanupOldFiles(retentionDays: number): number;
92
+ }
93
+ //# sourceMappingURL=jsonl-writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-writer.d.ts","sourceRoot":"","sources":["../../src/server/jsonl-writer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;IACd,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACtB,8BAA8B;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;CAChB;AAcD;;;;;GAKG;AACH,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAkC;IAC/D,OAAO,CAAC,MAAM,CAAS;IAEvB;;;OAGG;gBACS,OAAO,EAAE,MAAM;IAI3B;;;;OAIG;IACH,WAAW,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM;IAI1C;;;;OAIG;IACH,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAcrD;;;;;OAKG;IACH,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB9D;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB5B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB5B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAyBzB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAanB;;;;;OAKG;IACH,eAAe,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM;CAoDjD"}
@@ -0,0 +1,205 @@
1
+ /**
2
+ * JSONL file writer for streaming logs to disk.
3
+ *
4
+ * Organizes logs by project marker in the temp directory:
5
+ * {baseDir}/{marker}/logs.jsonl
6
+ * @module server/jsonl-writer
7
+ */
8
+ import * as fs from "fs";
9
+ import * as path from "path";
10
+ /**
11
+ * JSONL file writer that streams log entries to disk.
12
+ *
13
+ * Each project marker gets its own log file in the structure:
14
+ * {baseDir}/{marker}/logs.jsonl
15
+ */
16
+ export class JsonlWriter {
17
+ /**
18
+ * Create a new JsonlWriter.
19
+ * @param baseDir - Base directory for log files (e.g., os.tmpdir()/remote-logger)
20
+ */
21
+ constructor(baseDir) {
22
+ this.markerStates = new Map();
23
+ this.closed = false;
24
+ this.baseDir = baseDir;
25
+ }
26
+ /**
27
+ * Get the file path for a project marker.
28
+ * @param projectMarker - The project marker
29
+ * @returns Full path to the JSONL file
30
+ */
31
+ getFilePath(projectMarker) {
32
+ return path.join(this.baseDir, projectMarker, "logs.jsonl");
33
+ }
34
+ /**
35
+ * Get file statistics for a project marker's log file.
36
+ * @param projectMarker - The project marker
37
+ * @returns File stats or null if file doesn't exist
38
+ */
39
+ getFileStats(projectMarker) {
40
+ const filePath = this.getFilePath(projectMarker);
41
+ try {
42
+ const stats = fs.statSync(filePath);
43
+ return {
44
+ exists: true,
45
+ size: stats.size,
46
+ };
47
+ }
48
+ catch {
49
+ return null;
50
+ }
51
+ }
52
+ /**
53
+ * Write a log entry to the appropriate file.
54
+ * @param projectMarker - The project marker
55
+ * @param entry - The log entry to write
56
+ * @returns Promise that resolves when the write is queued
57
+ */
58
+ write(projectMarker, entry) {
59
+ if (this.closed) {
60
+ return Promise.resolve();
61
+ }
62
+ const state = this.ensureMarkerState(projectMarker);
63
+ const line = `${JSON.stringify(entry)}\n`;
64
+ // Add to buffer and trigger write
65
+ state.buffer.push(line);
66
+ // Chain the write to maintain order
67
+ state.writeLock = state.writeLock.then(() => {
68
+ this.flushBuffer(state);
69
+ });
70
+ return Promise.resolve();
71
+ }
72
+ /**
73
+ * Flush all pending writes to disk.
74
+ */
75
+ async flush() {
76
+ const flushPromises = [];
77
+ for (const state of this.markerStates.values()) {
78
+ // Wait for pending writes and flush buffer
79
+ flushPromises.push(state.writeLock.then(() => {
80
+ this.flushBuffer(state);
81
+ }));
82
+ }
83
+ await Promise.all(flushPromises);
84
+ // Sync all file descriptors
85
+ for (const state of this.markerStates.values()) {
86
+ try {
87
+ fs.fsyncSync(state.fd);
88
+ }
89
+ catch {
90
+ // Ignore sync errors
91
+ }
92
+ }
93
+ }
94
+ /**
95
+ * Close all file handles.
96
+ */
97
+ async close() {
98
+ if (this.closed) {
99
+ return;
100
+ }
101
+ this.closed = true;
102
+ // Flush all pending writes
103
+ await this.flush();
104
+ // Close all file handles
105
+ for (const state of this.markerStates.values()) {
106
+ try {
107
+ fs.closeSync(state.fd);
108
+ }
109
+ catch {
110
+ // Ignore close errors
111
+ }
112
+ }
113
+ this.markerStates.clear();
114
+ }
115
+ /**
116
+ * Ensure the marker state exists, creating file if needed.
117
+ * @param projectMarker - The project marker
118
+ * @returns The marker state
119
+ */
120
+ ensureMarkerState(projectMarker) {
121
+ let state = this.markerStates.get(projectMarker);
122
+ if (!state) {
123
+ const filePath = this.getFilePath(projectMarker);
124
+ const dir = path.dirname(filePath);
125
+ // Create directory if it doesn't exist
126
+ fs.mkdirSync(dir, { recursive: true });
127
+ // Open file for appending
128
+ const fd = fs.openSync(filePath, "a");
129
+ state = {
130
+ fd,
131
+ buffer: [],
132
+ writeLock: Promise.resolve(),
133
+ };
134
+ this.markerStates.set(projectMarker, state);
135
+ }
136
+ return state;
137
+ }
138
+ /**
139
+ * Flush the buffer for a marker state.
140
+ * @param state - The marker state to flush
141
+ */
142
+ flushBuffer(state) {
143
+ if (state.buffer.length === 0) {
144
+ return;
145
+ }
146
+ // Take all buffered entries
147
+ const toWrite = state.buffer.join("");
148
+ state.buffer = [];
149
+ // Write to file
150
+ fs.writeSync(state.fd, toWrite);
151
+ }
152
+ /**
153
+ * Clean up old project log files based on directory modification time.
154
+ * Removes entire project directories that haven't been modified within the retention period.
155
+ * @param retentionDays - Number of days to retain logs
156
+ * @returns Number of project directories removed
157
+ */
158
+ cleanupOldFiles(retentionDays) {
159
+ // Check if base directory exists
160
+ if (!fs.existsSync(this.baseDir)) {
161
+ return 0;
162
+ }
163
+ const cutoffTime = new Date();
164
+ cutoffTime.setDate(cutoffTime.getDate() - retentionDays);
165
+ const cutoffMs = cutoffTime.getTime();
166
+ let removed = 0;
167
+ try {
168
+ const entries = fs.readdirSync(this.baseDir, { withFileTypes: true });
169
+ for (const entry of entries) {
170
+ if (!entry.isDirectory()) {
171
+ continue;
172
+ }
173
+ const dirPath = path.join(this.baseDir, entry.name);
174
+ try {
175
+ const stats = fs.statSync(dirPath);
176
+ // Check if directory is older than retention period
177
+ if (stats.mtimeMs < cutoffMs) {
178
+ // Close file handle if we have one open for this marker
179
+ const state = this.markerStates.get(entry.name);
180
+ if (state) {
181
+ try {
182
+ fs.closeSync(state.fd);
183
+ }
184
+ catch {
185
+ // Ignore close errors
186
+ }
187
+ this.markerStates.delete(entry.name);
188
+ }
189
+ // Remove the directory
190
+ fs.rmSync(dirPath, { recursive: true, force: true });
191
+ removed++;
192
+ }
193
+ }
194
+ catch {
195
+ // Ignore errors for individual directories
196
+ }
197
+ }
198
+ }
199
+ catch {
200
+ // Ignore errors reading base directory
201
+ }
202
+ return removed;
203
+ }
204
+ }
205
+ //# sourceMappingURL=jsonl-writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonl-writer.js","sourceRoot":"","sources":["../../src/server/jsonl-writer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Remote Log Server - A standalone HTTP/HTTPS log server for remote debugging.
3
+ *
4
+ * Features:
5
+ * - HTTPS with auto-generated self-signed certs or custom certs
6
+ * - Receives logs from browser via POST /log
7
+ * - Pretty terminal output with colors
8
+ * - REST API for querying logs
9
+ * - Optional file logging for Claude Code to read
10
+ *
11
+ * Usage:
12
+ * npx remote-log-server --port 9080
13
+ * npx remote-log-server --cert /path/to/cert.crt --key /path/to/key.key
14
+ */
15
+ import * as http from "http";
16
+ import * as https from "https";
17
+ import { JsonlWriter } from "./jsonl-writer.js";
18
+ import { LogStorage } from "./log-storage.js";
19
+ /**
20
+ * Get the shared LogStorage instance, creating it if needed.
21
+ * Creates a JsonlWriter for JSONL file streaming by default.
22
+ * @returns The shared LogStorage instance
23
+ */
24
+ export declare function getLogStorage(): LogStorage;
25
+ /**
26
+ * Get the shared JsonlWriter instance.
27
+ * @returns The shared JsonlWriter instance or null if not initialized
28
+ */
29
+ export declare function getJsonlWriter(): JsonlWriter | null;
30
+ /**
31
+ * Set the shared LogStorage instance (for testing or external injection).
32
+ * @param storage - The LogStorage instance to use
33
+ */
34
+ export declare function setLogStorage(storage: LogStorage): void;
35
+ export interface LogServerOptions {
36
+ /** Port to listen on (default: 9080) */
37
+ port?: number;
38
+ /** Hostname to bind to (default: localhost) */
39
+ host?: string;
40
+ /** Path to SSL certificate file (HTTPS only used if both certPath and keyPath provided) */
41
+ certPath?: string;
42
+ /** Path to SSL private key file (HTTPS only used if both certPath and keyPath provided) */
43
+ keyPath?: string;
44
+ /** Path to file for writing logs (optional) */
45
+ logFile?: string;
46
+ /** Start in MCP server mode (default: false) @deprecated Use mcpOnly instead */
47
+ mcp?: boolean;
48
+ /** Start only MCP server (no HTTP) */
49
+ mcpOnly?: boolean;
50
+ /** Start only HTTP server (no MCP) - legacy mode */
51
+ httpOnly?: boolean;
52
+ /** Suppress startup banner (default: false) */
53
+ quiet?: boolean;
54
+ }
55
+ export type { LogEntry } from "./log-storage.js";
56
+ /**
57
+ * Clear all stored logs.
58
+ * Useful for testing.
59
+ */
60
+ export declare function clearLogs(): void;
61
+ /**
62
+ * Options for creating a log server without starting it.
63
+ */
64
+ export interface CreateLogServerOptions {
65
+ /** Port to listen on */
66
+ port: number;
67
+ /** Hostname to bind to */
68
+ host: string;
69
+ /** Shared log storage instance */
70
+ storage: LogStorage;
71
+ /** Suppress terminal output (default: false) */
72
+ quiet?: boolean;
73
+ /** Only serve /log POST and /health GET endpoints (default: false) */
74
+ logReceiveOnly?: boolean;
75
+ /** Path to SSL certificate file (HTTPS only used if both certPath and keyPath provided) */
76
+ certPath?: string;
77
+ /** Path to SSL private key file (HTTPS only used if both certPath and keyPath provided) */
78
+ keyPath?: string;
79
+ }
80
+ /**
81
+ * Result of creating a log server.
82
+ */
83
+ export interface CreateLogServerResult {
84
+ /** The HTTP or HTTPS server instance (not yet listening) */
85
+ server: http.Server | https.Server;
86
+ }
87
+ /**
88
+ * Create a log server with shared storage.
89
+ * The server is not started - call server.listen() to start it.
90
+ * @param options - Server configuration options
91
+ * @returns The server instance
92
+ */
93
+ export declare function createLogServer(options: CreateLogServerOptions): CreateLogServerResult;
94
+ /**
95
+ * Start the log server.
96
+ * @param options - Server configuration options
97
+ * @returns The HTTP or HTTPS server instance
98
+ */
99
+ export declare function startLogServer(options?: LogServerOptions): http.Server | https.Server;
100
+ /**
101
+ * Help text displayed when --help is passed.
102
+ */
103
+ export declare const HELP_TEXT = "\nRemote Log Server - Remote logging for browser debugging\n\nUsage:\n npx remote-log-server [options]\n npx @graphty/remote-logger [options]\n\nOptions:\n --port, -p <port> Port to listen on (default: 9080)\n --host, -h <host> Hostname to bind to (default: localhost)\n --cert, -c <path> Path to SSL certificate file (enables HTTPS)\n --key, -k <path> Path to SSL private key file (enables HTTPS)\n --log-file, -l <path> Write logs to file\n --mcp-only Start only MCP server (no HTTP)\n --http-only Start only HTTP server (legacy mode)\n --mcp Alias for --mcp-only (deprecated)\n --quiet, -q Suppress startup banner\n --help Show this help message\n\nProtocol:\n HTTP is used by default. To use HTTPS, provide both --cert and --key.\n\nModes:\n Default (no flags) Dual mode: HTTP + MCP running together\n --mcp-only MCP only: For Claude Code integration\n --http-only HTTP only: Legacy mode for browser debugging\n\nExamples:\n npx remote-log-server # Start dual mode (HTTP + MCP)\n npx remote-log-server --port 9085 # Custom port\n npx remote-log-server --mcp-only # MCP server only (for Claude Code)\n npx remote-log-server --http-only # HTTP server only (legacy)\n npx remote-log-server --cert cert.crt --key key.key # Use HTTPS with custom certs\n npx remote-log-server --log-file ./tmp/logs.jsonl # Also write to file\n";
104
+ /**
105
+ * Result of parsing command line arguments.
106
+ */
107
+ export interface ParseArgsResult {
108
+ /** Parsed options for the log server */
109
+ options: LogServerOptions;
110
+ /** Whether --help was requested */
111
+ showHelp: boolean;
112
+ /** Error message if parsing failed */
113
+ error?: string;
114
+ }
115
+ /**
116
+ * Parse command line arguments into LogServerOptions.
117
+ * This is separated from main() to enable testing.
118
+ * @param args - Array of command line arguments (excluding node and script name)
119
+ * @returns ParseArgsResult with options, help flag, or error
120
+ */
121
+ export declare function parseArgs(args: string[]): ParseArgsResult;
122
+ /**
123
+ * Parse command line arguments and start the server.
124
+ */
125
+ export declare function main(): Promise<void>;
126
+ //# sourceMappingURL=log-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-server.d.ts","sourceRoot":"","sources":["../../src/server/log-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAK/B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAiB,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAQ7D;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,UAAU,CAU1C;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAEnD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAEvD;AAkBD,MAAM,WAAW,gBAAgB;IAC7B,wCAAwC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,sCAAsC;IACtC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB;AAGD,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAajD;;;GAGG;AACH,wBAAgB,SAAS,IAAI,IAAI,CAEhC;AAqRD;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACnC,wBAAwB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,OAAO,EAAE,UAAU,CAAC;IACpB,gDAAgD;IAChD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sEAAsE;IACtE,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,2FAA2F;IAC3F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2FAA2F;IAC3F,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,4DAA4D;IAC5D,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;CACtC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CAsCtF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,gBAAqB,GAAG,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAkEzF;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,siDAkCrB,CAAC;AAEF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,wCAAwC;IACxC,OAAO,EAAE,gBAAgB,CAAC;IAC1B,mCAAmC;IACnC,QAAQ,EAAE,OAAO,CAAC;IAClB,sCAAsC;IACtC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,eAAe,CAuDzD;AAED;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAoG1C"}