@geekmidas/telescope 9.0.2 → 10.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +14 -4
  2. package/dist/{http-D5kn3_Mt.d.mts → http-BiNtg85L.d.mts} +3 -3
  3. package/dist/{http-D5kn3_Mt.d.mts.map → http-BiNtg85L.d.mts.map} +1 -1
  4. package/dist/instrumentation/http.d.mts +1 -1
  5. package/dist/instrumentation/index.cjs +2 -2
  6. package/dist/instrumentation/index.d.cts +2 -2
  7. package/dist/instrumentation/index.d.mts +3 -3
  8. package/dist/instrumentation/index.mjs +2 -2
  9. package/dist/instrumentation/middleware.cjs +1 -1
  10. package/dist/instrumentation/middleware.d.cts +1 -1
  11. package/dist/instrumentation/middleware.d.mts +1 -1
  12. package/dist/instrumentation/middleware.mjs +1 -1
  13. package/dist/instrumentation/otel.cjs +1 -1
  14. package/dist/instrumentation/otel.d.cts +1 -1
  15. package/dist/instrumentation/otel.d.mts +1 -1
  16. package/dist/instrumentation/otel.mjs +1 -1
  17. package/dist/logger/console.d.cts.map +1 -1
  18. package/dist/logger/pino.d.mts +2 -2
  19. package/dist/{middleware-DqPQpcup.cjs → middleware-Bcq6XXGG.cjs} +2 -2
  20. package/dist/middleware-Bcq6XXGG.cjs.map +1 -0
  21. package/dist/{middleware-4-GrQlOT.mjs → middleware-D1XEHvyy.mjs} +2 -2
  22. package/dist/middleware-D1XEHvyy.mjs.map +1 -0
  23. package/dist/{middleware-CA84nsNN.d.cts → middleware-PeyS-9Ny.d.cts} +2 -2
  24. package/dist/{middleware-CA84nsNN.d.cts.map → middleware-PeyS-9Ny.d.cts.map} +1 -1
  25. package/dist/{middleware-DAceVpfw.d.mts → middleware-oHvo_ZgU.d.mts} +2 -2
  26. package/dist/{middleware-DAceVpfw.d.mts.map → middleware-oHvo_ZgU.d.mts.map} +1 -1
  27. package/dist/{otel-40udNP5g.mjs → otel-B9bNoeZ2.mjs} +3 -3
  28. package/dist/otel-B9bNoeZ2.mjs.map +1 -0
  29. package/dist/{otel-SBVoVEHr.d.cts → otel-Bk89b1lX.d.cts} +3 -3
  30. package/dist/{otel-1bJPb2Z7.d.mts.map → otel-Bk89b1lX.d.cts.map} +1 -1
  31. package/dist/{otel-COrpz_GZ.cjs → otel-BzjOtVxZ.cjs} +3 -3
  32. package/dist/otel-BzjOtVxZ.cjs.map +1 -0
  33. package/dist/{otel-1bJPb2Z7.d.mts → otel-lPMsM26e.d.mts} +3 -3
  34. package/dist/{otel-SBVoVEHr.d.cts.map → otel-lPMsM26e.d.mts.map} +1 -1
  35. package/dist/storage/kysely.cjs +48 -38
  36. package/dist/storage/kysely.cjs.map +1 -1
  37. package/dist/storage/kysely.d.cts +29 -9
  38. package/dist/storage/kysely.d.cts.map +1 -1
  39. package/dist/storage/kysely.d.mts +29 -9
  40. package/dist/storage/kysely.d.mts.map +1 -1
  41. package/dist/storage/kysely.mjs +48 -38
  42. package/dist/storage/kysely.mjs.map +1 -1
  43. package/dist/tracing-PnECEbEu.d.mts.map +1 -1
  44. package/package.json +6 -3
  45. package/CHANGELOG.md +0 -72
  46. package/dist/middleware-4-GrQlOT.mjs.map +0 -1
  47. package/dist/middleware-DqPQpcup.cjs.map +0 -1
  48. package/dist/otel-40udNP5g.mjs.map +0 -1
  49. package/dist/otel-COrpz_GZ.cjs.map +0 -1
  50. package/src/Telescope.ts +0 -561
  51. package/src/__tests__/Telescope.spec.ts +0 -438
  52. package/src/__tests__/pino-transport.spec.ts +0 -115
  53. package/src/__tests__/redact.spec.ts +0 -336
  54. package/src/adapters/__tests__/lambda.spec.ts +0 -318
  55. package/src/adapters/__tests__/middy.spec.ts +0 -741
  56. package/src/adapters/index.ts +0 -22
  57. package/src/adapters/lambda.ts +0 -432
  58. package/src/adapters/middy.ts +0 -402
  59. package/src/adapters/types.ts +0 -181
  60. package/src/core.ts +0 -51
  61. package/src/index.ts +0 -34
  62. package/src/instrumentation/__tests__/core.spec.ts +0 -248
  63. package/src/instrumentation/__tests__/hono.spec.ts +0 -348
  64. package/src/instrumentation/__tests__/middleware.spec.ts +0 -528
  65. package/src/instrumentation/__tests__/otel.spec.ts +0 -291
  66. package/src/instrumentation/__tests__/tracing.spec.ts +0 -208
  67. package/src/instrumentation/core.ts +0 -228
  68. package/src/instrumentation/hono.ts +0 -270
  69. package/src/instrumentation/http.ts +0 -306
  70. package/src/instrumentation/index.ts +0 -90
  71. package/src/instrumentation/middleware.ts +0 -297
  72. package/src/instrumentation/otel.ts +0 -271
  73. package/src/instrumentation/setup.ts +0 -246
  74. package/src/instrumentation/tracing.ts +0 -145
  75. package/src/logger/__tests__/console.spec.ts +0 -366
  76. package/src/logger/__tests__/pino.spec.ts +0 -217
  77. package/src/logger/console.ts +0 -230
  78. package/src/logger/pino.ts +0 -201
  79. package/src/metrics/MetricsAggregator.ts +0 -555
  80. package/src/metrics/__tests__/MetricsAggregator.spec.ts +0 -298
  81. package/src/metrics/index.ts +0 -2
  82. package/src/metrics/storage/InMemoryMetricsStorage.ts +0 -380
  83. package/src/metrics/storage/MetricsStorage.ts +0 -74
  84. package/src/metrics/storage/index.ts +0 -3
  85. package/src/metrics/storage/types.ts +0 -243
  86. package/src/otlp/__tests__/receiver.spec.ts +0 -367
  87. package/src/otlp/__tests__/transformer.spec.ts +0 -455
  88. package/src/otlp/hono.ts +0 -120
  89. package/src/otlp/index.ts +0 -22
  90. package/src/otlp/receiver.ts +0 -162
  91. package/src/otlp/transformer.ts +0 -367
  92. package/src/otlp/types.ts +0 -364
  93. package/src/redact.ts +0 -116
  94. package/src/server/__tests__/hono.spec.ts +0 -814
  95. package/src/server/hono.ts +0 -442
  96. package/src/storage/__tests__/kysely.spec.ts +0 -715
  97. package/src/storage/__tests__/memory.spec.ts +0 -694
  98. package/src/storage/kysely.ts +0 -599
  99. package/src/storage/memory.ts +0 -204
  100. package/src/types.ts +0 -447
  101. package/src/ui-assets.ts +0 -40
  102. package/tsconfig.json +0 -9
  103. package/ui/CHANGELOG.md +0 -7
  104. package/ui/index.html +0 -12
  105. package/ui/node_modules/.bin/tsc +0 -21
  106. package/ui/node_modules/.bin/tsserver +0 -21
  107. package/ui/node_modules/.bin/vite +0 -21
  108. package/ui/package.json +0 -24
  109. package/ui/src/App.tsx +0 -595
  110. package/ui/src/api.ts +0 -88
  111. package/ui/src/components/ExceptionDetail.tsx +0 -100
  112. package/ui/src/components/FilterBar.tsx +0 -162
  113. package/ui/src/components/LogDetail.tsx +0 -91
  114. package/ui/src/components/RequestDetail.tsx +0 -143
  115. package/ui/src/main.tsx +0 -10
  116. package/ui/src/styles.css +0 -11
  117. package/ui/src/types.ts +0 -63
  118. package/ui/src/vite-env.d.ts +0 -1
  119. package/ui/src/vite-plugin-gkm-config.ts +0 -54
  120. package/ui/tsconfig.json +0 -20
  121. package/ui/tsconfig.tsbuildinfo +0 -1
  122. package/ui/vite.config.ts +0 -13
@@ -1,100 +0,0 @@
1
- import type { ExceptionEntry } from '../types';
2
-
3
- interface ExceptionDetailProps {
4
- exception: ExceptionEntry;
5
- onClose: () => void;
6
- }
7
-
8
- export function ExceptionDetail({ exception, onClose }: ExceptionDetailProps) {
9
- return (
10
- <div className="fixed top-0 right-0 bottom-0 w-1/2 max-w-3xl bg-bg-secondary border-l border-border flex flex-col z-50 shadow-2xl">
11
- <div className="flex items-center justify-between p-4 border-b border-border">
12
- <h2 className="text-base font-semibold text-red-400">
13
- {exception.name}
14
- </h2>
15
- <button
16
- className="text-slate-400 hover:text-slate-100 p-2 text-xl leading-none"
17
- onClick={onClose}
18
- >
19
- &times;
20
- </button>
21
- </div>
22
-
23
- <div className="flex-1 overflow-y-auto p-4">
24
- <section className="mb-6">
25
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
26
- Overview
27
- </h3>
28
- <div className="space-y-2 text-sm">
29
- <div className="flex py-2 border-b border-border">
30
- <span className="text-slate-500 min-w-32">Message</span>
31
- <span className="wrap-break-word">{exception.message}</span>
32
- </div>
33
- <div className="flex py-2 border-b border-border">
34
- <span className="text-slate-500 min-w-32">Handled</span>
35
- <span>{exception.handled ? 'Yes' : 'No'}</span>
36
- </div>
37
- <div className="flex py-2 border-b border-border">
38
- <span className="text-slate-500 min-w-32">Timestamp</span>
39
- <span>{new Date(exception.timestamp).toLocaleString()}</span>
40
- </div>
41
- {exception.requestId && (
42
- <div className="flex py-2 border-b border-border">
43
- <span className="text-slate-500 min-w-32">Request ID</span>
44
- <span className="font-mono text-xs">{exception.requestId}</span>
45
- </div>
46
- )}
47
- {exception.tags && exception.tags.length > 0 && (
48
- <div className="flex py-2">
49
- <span className="text-slate-500 min-w-32">Tags</span>
50
- <span>{exception.tags.join(', ')}</span>
51
- </div>
52
- )}
53
- </div>
54
- </section>
55
-
56
- {exception.source && (
57
- <section className="mb-6">
58
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
59
- Source
60
- </h3>
61
- <div className="text-sm mb-2">
62
- <span className="text-slate-500">File: </span>
63
- <span>
64
- {exception.source.file}
65
- {exception.source.line && `:${exception.source.line}`}
66
- </span>
67
- </div>
68
- {exception.source.code && (
69
- <pre className="bg-bg-primary border border-border rounded-lg p-4 overflow-x-auto text-xs leading-relaxed">
70
- {exception.source.code}
71
- </pre>
72
- )}
73
- </section>
74
- )}
75
-
76
- <section className="mb-6">
77
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
78
- Stack Trace
79
- </h3>
80
- <div className="text-xs leading-relaxed space-y-1">
81
- {exception.stack.map((frame, index) => (
82
- <div key={index} className="text-slate-400">
83
- <span className="text-blue-400">
84
- {frame.function || '<anonymous>'}
85
- </span>
86
- {frame.file && (
87
- <span className="text-slate-500 ml-2">
88
- at {frame.file}
89
- {frame.line !== undefined && `:${frame.line}`}
90
- {frame.column !== undefined && `:${frame.column}`}
91
- </span>
92
- )}
93
- </div>
94
- ))}
95
- </div>
96
- </section>
97
- </div>
98
- </div>
99
- );
100
- }
@@ -1,162 +0,0 @@
1
- import type { Tab } from '../types';
2
-
3
- export interface RequestFilters {
4
- search: string;
5
- method: string;
6
- status: string;
7
- }
8
-
9
- export interface LogFilters {
10
- search: string;
11
- level: string;
12
- }
13
-
14
- export interface ExceptionFilters {
15
- search: string;
16
- }
17
-
18
- interface FilterBarProps {
19
- tab: Tab;
20
- requestFilters: RequestFilters;
21
- logFilters: LogFilters;
22
- exceptionFilters: ExceptionFilters;
23
- onRequestFiltersChange: (filters: RequestFilters) => void;
24
- onLogFiltersChange: (filters: LogFilters) => void;
25
- onExceptionFiltersChange: (filters: ExceptionFilters) => void;
26
- onClear: () => void;
27
- }
28
-
29
- const HTTP_METHODS = ['', 'GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
30
- const STATUS_RANGES = [
31
- { value: '', label: 'All Status' },
32
- { value: '2xx', label: '2xx Success' },
33
- { value: '3xx', label: '3xx Redirect' },
34
- { value: '4xx', label: '4xx Client Error' },
35
- { value: '5xx', label: '5xx Server Error' },
36
- ];
37
- const LOG_LEVELS = ['', 'debug', 'info', 'warn', 'error'];
38
-
39
- export function FilterBar({
40
- tab,
41
- requestFilters,
42
- logFilters,
43
- exceptionFilters,
44
- onRequestFiltersChange,
45
- onLogFiltersChange,
46
- onExceptionFiltersChange,
47
- onClear,
48
- }: FilterBarProps) {
49
- const hasActiveFilters =
50
- (tab === 'requests' &&
51
- (requestFilters.search ||
52
- requestFilters.method ||
53
- requestFilters.status)) ||
54
- (tab === 'logs' && (logFilters.search || logFilters.level)) ||
55
- (tab === 'exceptions' && exceptionFilters.search);
56
-
57
- return (
58
- <div className="bg-bg-secondary border-b border-border px-4 py-3 flex items-center gap-3">
59
- {tab === 'requests' && (
60
- <>
61
- <input
62
- type="text"
63
- placeholder="Search path..."
64
- value={requestFilters.search}
65
- onChange={(e) =>
66
- onRequestFiltersChange({
67
- ...requestFilters,
68
- search: e.target.value,
69
- })
70
- }
71
- className="bg-bg-tertiary border border-border rounded px-3 py-1.5 text-sm text-slate-100 placeholder-slate-500 focus:outline-none focus:border-blue-500 w-64"
72
- />
73
- <select
74
- value={requestFilters.method}
75
- onChange={(e) =>
76
- onRequestFiltersChange({
77
- ...requestFilters,
78
- method: e.target.value,
79
- })
80
- }
81
- className="bg-bg-tertiary border border-border rounded px-3 py-1.5 text-sm text-slate-100 focus:outline-none focus:border-blue-500"
82
- >
83
- <option value="">All Methods</option>
84
- {HTTP_METHODS.filter(Boolean).map((method) => (
85
- <option key={method} value={method}>
86
- {method}
87
- </option>
88
- ))}
89
- </select>
90
- <select
91
- value={requestFilters.status}
92
- onChange={(e) =>
93
- onRequestFiltersChange({
94
- ...requestFilters,
95
- status: e.target.value,
96
- })
97
- }
98
- className="bg-bg-tertiary border border-border rounded px-3 py-1.5 text-sm text-slate-100 focus:outline-none focus:border-blue-500"
99
- >
100
- {STATUS_RANGES.map((range) => (
101
- <option key={range.value} value={range.value}>
102
- {range.label}
103
- </option>
104
- ))}
105
- </select>
106
- </>
107
- )}
108
-
109
- {tab === 'logs' && (
110
- <>
111
- <input
112
- type="text"
113
- placeholder="Search message..."
114
- value={logFilters.search}
115
- onChange={(e) =>
116
- onLogFiltersChange({ ...logFilters, search: e.target.value })
117
- }
118
- className="bg-bg-tertiary border border-border rounded px-3 py-1.5 text-sm text-slate-100 placeholder-slate-500 focus:outline-none focus:border-blue-500 w-64"
119
- />
120
- <select
121
- value={logFilters.level}
122
- onChange={(e) =>
123
- onLogFiltersChange({ ...logFilters, level: e.target.value })
124
- }
125
- className="bg-bg-tertiary border border-border rounded px-3 py-1.5 text-sm text-slate-100 focus:outline-none focus:border-blue-500"
126
- >
127
- <option value="">All Levels</option>
128
- {LOG_LEVELS.filter(Boolean).map((level) => (
129
- <option key={level} value={level}>
130
- {level}
131
- </option>
132
- ))}
133
- </select>
134
- </>
135
- )}
136
-
137
- {tab === 'exceptions' && (
138
- <input
139
- type="text"
140
- placeholder="Search exception..."
141
- value={exceptionFilters.search}
142
- onChange={(e) =>
143
- onExceptionFiltersChange({
144
- ...exceptionFilters,
145
- search: e.target.value,
146
- })
147
- }
148
- className="bg-bg-tertiary border border-border rounded px-3 py-1.5 text-sm text-slate-100 placeholder-slate-500 focus:outline-none focus:border-blue-500 w-64"
149
- />
150
- )}
151
-
152
- {hasActiveFilters && (
153
- <button
154
- onClick={onClear}
155
- className="text-xs text-slate-400 hover:text-slate-200 px-2 py-1 rounded hover:bg-bg-tertiary transition-colors"
156
- >
157
- Clear filters
158
- </button>
159
- )}
160
- </div>
161
- );
162
- }
@@ -1,91 +0,0 @@
1
- import type { LogEntry } from '../types';
2
-
3
- interface LogDetailProps {
4
- log: LogEntry;
5
- onClose: () => void;
6
- }
7
-
8
- export function LogDetail({ log, onClose }: LogDetailProps) {
9
- const formatJson = (data: unknown) => {
10
- try {
11
- return JSON.stringify(data, null, 2);
12
- } catch {
13
- return String(data);
14
- }
15
- };
16
-
17
- const getLogLevelColor = (level: string) => {
18
- const colors: Record<string, string> = {
19
- debug: 'bg-slate-500/20 text-slate-400',
20
- info: 'bg-blue-500/20 text-blue-400',
21
- warn: 'bg-amber-500/20 text-amber-400',
22
- error: 'bg-red-500/20 text-red-400',
23
- };
24
- return colors[level] || 'bg-slate-500/20 text-slate-400';
25
- };
26
-
27
- return (
28
- <div className="fixed top-0 right-0 bottom-0 w-1/2 max-w-3xl bg-bg-secondary border-l border-border flex flex-col z-50 shadow-2xl">
29
- <div className="flex items-center justify-between p-4 border-b border-border">
30
- <h2 className="text-base font-semibold flex items-center gap-2">
31
- <span
32
- className={`px-2 py-1 rounded text-xs ${getLogLevelColor(log.level)}`}
33
- >
34
- {log.level}
35
- </span>
36
- Log Entry
37
- </h2>
38
- <button
39
- className="text-slate-400 hover:text-slate-100 p-2 text-xl leading-none"
40
- onClick={onClose}
41
- >
42
- &times;
43
- </button>
44
- </div>
45
-
46
- <div className="flex-1 overflow-y-auto p-4">
47
- <section className="mb-6">
48
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
49
- Overview
50
- </h3>
51
- <div className="space-y-2 text-sm">
52
- <div className="flex py-2 border-b border-border">
53
- <span className="text-slate-500 min-w-32">Level</span>
54
- <span>{log.level}</span>
55
- </div>
56
- <div className="flex py-2 border-b border-border">
57
- <span className="text-slate-500 min-w-32">Timestamp</span>
58
- <span>{new Date(log.timestamp).toLocaleString()}</span>
59
- </div>
60
- {log.requestId && (
61
- <div className="flex py-2">
62
- <span className="text-slate-500 min-w-32">Request ID</span>
63
- <span className="font-mono text-xs">{log.requestId}</span>
64
- </div>
65
- )}
66
- </div>
67
- </section>
68
-
69
- <section className="mb-6">
70
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
71
- Message
72
- </h3>
73
- <pre className="bg-bg-primary border border-border rounded-lg p-4 overflow-x-auto text-xs leading-relaxed whitespace-pre-wrap">
74
- {log.message}
75
- </pre>
76
- </section>
77
-
78
- {log.context && Object.keys(log.context).length > 0 && (
79
- <section className="mb-6">
80
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
81
- Context
82
- </h3>
83
- <pre className="bg-bg-primary border border-border rounded-lg p-4 overflow-x-auto text-xs leading-relaxed">
84
- {formatJson(log.context)}
85
- </pre>
86
- </section>
87
- )}
88
- </div>
89
- </div>
90
- );
91
- }
@@ -1,143 +0,0 @@
1
- import type { RequestEntry } from '../types';
2
-
3
- interface RequestDetailProps {
4
- request: RequestEntry;
5
- onClose: () => void;
6
- }
7
-
8
- export function RequestDetail({ request, onClose }: RequestDetailProps) {
9
- const formatJson = (data: unknown) => {
10
- try {
11
- return JSON.stringify(data, null, 2);
12
- } catch {
13
- return String(data);
14
- }
15
- };
16
-
17
- const getMethodColor = (method: string) => {
18
- const colors: Record<string, string> = {
19
- GET: 'bg-green-500/20 text-green-400',
20
- POST: 'bg-blue-500/20 text-blue-400',
21
- PUT: 'bg-amber-500/20 text-amber-400',
22
- PATCH: 'bg-purple-500/20 text-purple-400',
23
- DELETE: 'bg-red-500/20 text-red-400',
24
- };
25
- return colors[method] || 'bg-slate-500/20 text-slate-400';
26
- };
27
-
28
- return (
29
- <div className="fixed top-0 right-0 bottom-0 w-1/2 max-w-3xl bg-bg-secondary border-l border-border flex flex-col z-50 shadow-2xl">
30
- <div className="flex items-center justify-between p-4 border-b border-border">
31
- <h2 className="text-base font-semibold flex items-center gap-2">
32
- <span
33
- className={`px-2 py-1 rounded text-xs ${getMethodColor(request.method)}`}
34
- >
35
- {request.method}
36
- </span>
37
- <span className="truncate">{request.path}</span>
38
- </h2>
39
- <button
40
- className="text-slate-400 hover:text-slate-100 p-2 text-xl leading-none"
41
- onClick={onClose}
42
- >
43
- &times;
44
- </button>
45
- </div>
46
-
47
- <div className="flex-1 overflow-y-auto p-4">
48
- <section className="mb-6">
49
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
50
- Overview
51
- </h3>
52
- <div className="space-y-2 text-sm">
53
- <div className="flex py-2 border-b border-border">
54
- <span className="text-slate-500 min-w-32">Status</span>
55
- <span>{request.status}</span>
56
- </div>
57
- <div className="flex py-2 border-b border-border">
58
- <span className="text-slate-500 min-w-32">Duration</span>
59
- <span>{request.duration.toFixed(2)}ms</span>
60
- </div>
61
- <div className="flex py-2 border-b border-border">
62
- <span className="text-slate-500 min-w-32">URL</span>
63
- <span className="break-all">{request.url}</span>
64
- </div>
65
- <div className="flex py-2 border-b border-border">
66
- <span className="text-slate-500 min-w-32">Timestamp</span>
67
- <span>{new Date(request.timestamp).toLocaleString()}</span>
68
- </div>
69
- {request.ip && (
70
- <div className="flex py-2 border-b border-border">
71
- <span className="text-slate-500 min-w-32">IP</span>
72
- <span>{request.ip}</span>
73
- </div>
74
- )}
75
- {request.userId && (
76
- <div className="flex py-2 border-b border-border">
77
- <span className="text-slate-500 min-w-32">User ID</span>
78
- <span>{request.userId}</span>
79
- </div>
80
- )}
81
- {request.tags && request.tags.length > 0 && (
82
- <div className="flex py-2">
83
- <span className="text-slate-500 min-w-32">Tags</span>
84
- <span>{request.tags.join(', ')}</span>
85
- </div>
86
- )}
87
- </div>
88
- </section>
89
-
90
- <section className="mb-6">
91
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
92
- Request Headers
93
- </h3>
94
- <pre className="bg-bg-primary border border-border rounded-lg p-4 overflow-x-auto text-xs leading-relaxed">
95
- {formatJson(request.headers)}
96
- </pre>
97
- </section>
98
-
99
- {request.query && Object.keys(request.query).length > 0 && (
100
- <section className="mb-6">
101
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
102
- Query Parameters
103
- </h3>
104
- <pre className="bg-bg-primary border border-border rounded-lg p-4 overflow-x-auto text-xs leading-relaxed">
105
- {formatJson(request.query)}
106
- </pre>
107
- </section>
108
- )}
109
-
110
- {request.body !== undefined && (
111
- <section className="mb-6">
112
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
113
- Request Body
114
- </h3>
115
- <pre className="bg-bg-primary border border-border rounded-lg p-4 overflow-x-auto text-xs leading-relaxed">
116
- {formatJson(request.body)}
117
- </pre>
118
- </section>
119
- )}
120
-
121
- <section className="mb-6">
122
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
123
- Response Headers
124
- </h3>
125
- <pre className="bg-bg-primary border border-border rounded-lg p-4 overflow-x-auto text-xs leading-relaxed">
126
- {formatJson(request.responseHeaders)}
127
- </pre>
128
- </section>
129
-
130
- {request.responseBody !== undefined && (
131
- <section className="mb-6">
132
- <h3 className="text-xs font-semibold uppercase text-slate-500 mb-2">
133
- Response Body
134
- </h3>
135
- <pre className="bg-bg-primary border border-border rounded-lg p-4 overflow-x-auto text-xs leading-relaxed">
136
- {formatJson(request.responseBody)}
137
- </pre>
138
- </section>
139
- )}
140
- </div>
141
- </div>
142
- );
143
- }
package/ui/src/main.tsx DELETED
@@ -1,10 +0,0 @@
1
- import { StrictMode } from 'react';
2
- import { createRoot } from 'react-dom/client';
3
- import { App } from './App';
4
- import './styles.css';
5
-
6
- createRoot(document.getElementById('root')!).render(
7
- <StrictMode>
8
- <App />
9
- </StrictMode>,
10
- );
package/ui/src/styles.css DELETED
@@ -1,11 +0,0 @@
1
- @import "tailwindcss";
2
-
3
- @theme {
4
- --color-bg-primary: #0f172a;
5
- --color-bg-secondary: #1e293b;
6
- --color-bg-tertiary: #334155;
7
- --color-border: #334155;
8
- --font-family-mono:
9
- ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono",
10
- monospace;
11
- }
package/ui/src/types.ts DELETED
@@ -1,63 +0,0 @@
1
- export interface RequestEntry {
2
- id: string;
3
- method: string;
4
- path: string;
5
- url: string;
6
- headers: Record<string, string>;
7
- body?: unknown;
8
- query?: Record<string, string>;
9
- status: number;
10
- responseHeaders: Record<string, string>;
11
- responseBody?: unknown;
12
- duration: number;
13
- timestamp: string;
14
- ip?: string;
15
- userId?: string;
16
- tags?: string[];
17
- }
18
-
19
- export interface ExceptionEntry {
20
- id: string;
21
- name: string;
22
- message: string;
23
- stack: Array<{
24
- file?: string;
25
- line?: number;
26
- column?: number;
27
- function?: string;
28
- }>;
29
- source?: {
30
- file?: string;
31
- line?: number;
32
- code?: string;
33
- };
34
- requestId?: string;
35
- timestamp: string;
36
- handled: boolean;
37
- tags?: string[];
38
- }
39
-
40
- export interface LogEntry {
41
- id: string;
42
- level: 'debug' | 'info' | 'warn' | 'error';
43
- message: string;
44
- context?: Record<string, unknown>;
45
- requestId?: string;
46
- timestamp: string;
47
- }
48
-
49
- export interface TelescopeStats {
50
- requests: number;
51
- exceptions: number;
52
- logs: number;
53
- oldestEntry?: string;
54
- newestEntry?: string;
55
- }
56
-
57
- export type Tab = 'requests' | 'exceptions' | 'logs';
58
-
59
- export interface WebSocketMessage {
60
- type: 'request' | 'exception' | 'log' | 'connected';
61
- payload: unknown;
62
- timestamp: number;
63
- }
@@ -1 +0,0 @@
1
- /// <reference types="vite/client" />
@@ -1,54 +0,0 @@
1
- import { existsSync } from 'node:fs';
2
- import { resolve } from 'node:path';
3
- import type { Plugin } from 'vite';
4
-
5
- interface GkmConfig {
6
- server?: boolean | { port?: number };
7
- telescope?: { port?: number };
8
- }
9
-
10
- /**
11
- * Vite plugin that reads configuration from gkm.config.ts
12
- * to configure the dev server proxy.
13
- */
14
- export function gkmConfigPlugin(): Plugin {
15
- let serverPort = 3000;
16
-
17
- return {
18
- name: 'gkm-config',
19
- async config() {
20
- const cwd = process.cwd();
21
- const configPath = resolve(cwd, 'gkm.config.ts');
22
-
23
- if (existsSync(configPath)) {
24
- try {
25
- const config = (await import(configPath)).default as GkmConfig;
26
-
27
- // Check for telescope.port first, then server.port
28
- if (config.telescope?.port) {
29
- serverPort = config.telescope.port;
30
- } else if (typeof config.server === 'object' && config.server.port) {
31
- serverPort = config.server.port;
32
- }
33
- } catch {
34
- // Silently fall back to default port
35
- }
36
- }
37
-
38
- return {
39
- server: {
40
- proxy: {
41
- '/__telescope/api': {
42
- target: `http://localhost:${serverPort}`,
43
- changeOrigin: true,
44
- },
45
- '/__telescope/ws': {
46
- target: `ws://localhost:${serverPort}`,
47
- ws: true,
48
- },
49
- },
50
- },
51
- };
52
- },
53
- };
54
- }
package/ui/tsconfig.json DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
- "module": "ESNext",
6
- "skipLibCheck": true,
7
- "moduleResolution": "bundler",
8
- "allowImportingTsExtensions": true,
9
- "isolatedModules": true,
10
- "moduleDetection": "force",
11
- "noEmit": true,
12
- "jsx": "react-jsx",
13
- "strict": true,
14
- "noUnusedLocals": true,
15
- "noUnusedParameters": true,
16
- "noFallthroughCasesInSwitch": true,
17
- "noUncheckedSideEffectImports": true
18
- },
19
- "include": ["src"]
20
- }
@@ -1 +0,0 @@
1
- {"root":["./src/app.tsx","./src/api.ts","./src/main.tsx","./src/types.ts","./src/vite-env.d.ts","./src/vite-plugin-gkm-config.ts","./src/components/exceptiondetail.tsx","./src/components/filterbar.tsx","./src/components/logdetail.tsx","./src/components/requestdetail.tsx"],"version":"5.8.2"}
package/ui/vite.config.ts DELETED
@@ -1,13 +0,0 @@
1
- import tailwindcss from '@tailwindcss/vite';
2
- import react from '@vitejs/plugin-react';
3
- import { defineConfig } from 'vite';
4
- import { gkmConfigPlugin } from './src/vite-plugin-gkm-config';
5
-
6
- export default defineConfig({
7
- plugins: [react(), tailwindcss(), gkmConfigPlugin()],
8
- base: '/__telescope/',
9
- build: {
10
- outDir: '../dist/ui',
11
- emptyOutDir: true,
12
- },
13
- });