@adonis-agora/telescope 0.3.3 → 0.5.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 (199) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/configure.d.ts.map +1 -1
  3. package/dist/configure.js +6 -0
  4. package/dist/configure.js.map +1 -1
  5. package/dist/providers/telescope_ai_provider.d.ts +9 -1
  6. package/dist/providers/telescope_ai_provider.d.ts.map +1 -1
  7. package/dist/providers/telescope_ai_provider.js +22 -2
  8. package/dist/providers/telescope_ai_provider.js.map +1 -1
  9. package/dist/providers/telescope_alerts_provider.d.ts +1 -0
  10. package/dist/providers/telescope_alerts_provider.d.ts.map +1 -1
  11. package/dist/providers/telescope_alerts_provider.js +37 -1
  12. package/dist/providers/telescope_alerts_provider.js.map +1 -1
  13. package/dist/providers/telescope_mcp_provider.d.ts +26 -0
  14. package/dist/providers/telescope_mcp_provider.d.ts.map +1 -0
  15. package/dist/providers/telescope_mcp_provider.js +114 -0
  16. package/dist/providers/telescope_mcp_provider.js.map +1 -0
  17. package/dist/providers/telescope_provider.d.ts +8 -0
  18. package/dist/providers/telescope_provider.d.ts.map +1 -1
  19. package/dist/providers/telescope_provider.js +56 -1
  20. package/dist/providers/telescope_provider.js.map +1 -1
  21. package/dist/providers/telescope_ui_provider.d.ts +2 -0
  22. package/dist/providers/telescope_ui_provider.d.ts.map +1 -1
  23. package/dist/providers/telescope_ui_provider.js +106 -22
  24. package/dist/providers/telescope_ui_provider.js.map +1 -1
  25. package/dist/providers/telescope_watchers_provider.d.ts +13 -2
  26. package/dist/providers/telescope_watchers_provider.d.ts.map +1 -1
  27. package/dist/providers/telescope_watchers_provider.js +57 -7
  28. package/dist/providers/telescope_watchers_provider.js.map +1 -1
  29. package/dist/src/ai/define_config.d.ts +39 -7
  30. package/dist/src/ai/define_config.d.ts.map +1 -1
  31. package/dist/src/ai/define_config.js +14 -4
  32. package/dist/src/ai/define_config.js.map +1 -1
  33. package/dist/src/ai/diagnosis_coordinator.d.ts +106 -0
  34. package/dist/src/ai/diagnosis_coordinator.d.ts.map +1 -0
  35. package/dist/src/ai/diagnosis_coordinator.js +143 -0
  36. package/dist/src/ai/diagnosis_coordinator.js.map +1 -0
  37. package/dist/src/ai/factory.d.ts +8 -5
  38. package/dist/src/ai/factory.d.ts.map +1 -1
  39. package/dist/src/ai/factory.js +20 -8
  40. package/dist/src/ai/factory.js.map +1 -1
  41. package/dist/src/ai/index.d.ts +3 -1
  42. package/dist/src/ai/index.d.ts.map +1 -1
  43. package/dist/src/ai/index.js +3 -1
  44. package/dist/src/ai/index.js.map +1 -1
  45. package/dist/src/alerts/alert_rule.d.ts +79 -11
  46. package/dist/src/alerts/alert_rule.d.ts.map +1 -1
  47. package/dist/src/alerts/alerter.d.ts +11 -1
  48. package/dist/src/alerts/alerter.d.ts.map +1 -1
  49. package/dist/src/alerts/alerter.js +21 -1
  50. package/dist/src/alerts/alerter.js.map +1 -1
  51. package/dist/src/alerts/alerter_service.d.ts +103 -0
  52. package/dist/src/alerts/alerter_service.d.ts.map +1 -0
  53. package/dist/src/alerts/alerter_service.js +215 -0
  54. package/dist/src/alerts/alerter_service.js.map +1 -0
  55. package/dist/src/alerts/index.d.ts +4 -2
  56. package/dist/src/alerts/index.d.ts.map +1 -1
  57. package/dist/src/alerts/index.js +4 -2
  58. package/dist/src/alerts/index.js.map +1 -1
  59. package/dist/src/alerts/slack_format.d.ts.map +1 -1
  60. package/dist/src/alerts/slack_format.js +35 -2
  61. package/dist/src/alerts/slack_format.js.map +1 -1
  62. package/dist/src/client_errors/config.d.ts +66 -0
  63. package/dist/src/client_errors/config.d.ts.map +1 -0
  64. package/dist/src/client_errors/config.js +17 -0
  65. package/dist/src/client_errors/config.js.map +1 -0
  66. package/dist/src/client_errors/index.d.ts +5 -0
  67. package/dist/src/client_errors/index.d.ts.map +1 -0
  68. package/dist/src/client_errors/index.js +5 -0
  69. package/dist/src/client_errors/index.js.map +1 -0
  70. package/dist/src/client_errors/ingestor.d.ts +87 -0
  71. package/dist/src/client_errors/ingestor.d.ts.map +1 -0
  72. package/dist/src/client_errors/ingestor.js +135 -0
  73. package/dist/src/client_errors/ingestor.js.map +1 -0
  74. package/dist/src/client_errors/rate_limiter.d.ts +53 -0
  75. package/dist/src/client_errors/rate_limiter.d.ts.map +1 -0
  76. package/dist/src/client_errors/rate_limiter.js +83 -0
  77. package/dist/src/client_errors/rate_limiter.js.map +1 -0
  78. package/dist/src/client_errors/validation.d.ts +62 -0
  79. package/dist/src/client_errors/validation.d.ts.map +1 -0
  80. package/dist/src/client_errors/validation.js +109 -0
  81. package/dist/src/client_errors/validation.js.map +1 -0
  82. package/dist/src/define_config.d.ts +120 -0
  83. package/dist/src/define_config.d.ts.map +1 -1
  84. package/dist/src/define_config.js +41 -0
  85. package/dist/src/define_config.js.map +1 -1
  86. package/dist/src/entry.d.ts +20 -0
  87. package/dist/src/entry.d.ts.map +1 -1
  88. package/dist/src/entry.js +20 -0
  89. package/dist/src/entry.js.map +1 -1
  90. package/dist/src/index.d.ts +17 -4
  91. package/dist/src/index.d.ts.map +1 -1
  92. package/dist/src/index.js +16 -3
  93. package/dist/src/index.js.map +1 -1
  94. package/dist/src/mcp/define_config.d.ts +57 -0
  95. package/dist/src/mcp/define_config.d.ts.map +1 -0
  96. package/dist/src/mcp/define_config.js +35 -0
  97. package/dist/src/mcp/define_config.js.map +1 -0
  98. package/dist/src/mcp/index.d.ts +7 -0
  99. package/dist/src/mcp/index.d.ts.map +1 -0
  100. package/dist/src/mcp/index.js +7 -0
  101. package/dist/src/mcp/index.js.map +1 -0
  102. package/dist/src/mcp/server.d.ts +89 -0
  103. package/dist/src/mcp/server.d.ts.map +1 -0
  104. package/dist/src/mcp/server.js +279 -0
  105. package/dist/src/mcp/server.js.map +1 -0
  106. package/dist/src/metrics/pulse.d.ts +158 -0
  107. package/dist/src/metrics/pulse.d.ts.map +1 -0
  108. package/dist/src/metrics/pulse.js +414 -0
  109. package/dist/src/metrics/pulse.js.map +1 -0
  110. package/dist/src/overload_guard.d.ts +77 -0
  111. package/dist/src/overload_guard.d.ts.map +1 -0
  112. package/dist/src/overload_guard.js +134 -0
  113. package/dist/src/overload_guard.js.map +1 -0
  114. package/dist/src/pruner.d.ts +93 -0
  115. package/dist/src/pruner.d.ts.map +1 -0
  116. package/dist/src/pruner.js +120 -0
  117. package/dist/src/pruner.js.map +1 -0
  118. package/dist/src/registry.d.ts +26 -0
  119. package/dist/src/registry.d.ts.map +1 -1
  120. package/dist/src/registry.js +19 -0
  121. package/dist/src/registry.js.map +1 -1
  122. package/dist/src/service.d.ts +16 -1
  123. package/dist/src/service.d.ts.map +1 -1
  124. package/dist/src/service.js +19 -1
  125. package/dist/src/service.js.map +1 -1
  126. package/dist/src/stores/lucid.d.ts +20 -0
  127. package/dist/src/stores/lucid.d.ts.map +1 -1
  128. package/dist/src/stores/lucid.js +89 -4
  129. package/dist/src/stores/lucid.js.map +1 -1
  130. package/dist/src/telescope_middleware.d.ts.map +1 -1
  131. package/dist/src/telescope_middleware.js +3 -1
  132. package/dist/src/telescope_middleware.js.map +1 -1
  133. package/dist/src/ui/api.d.ts +9 -1
  134. package/dist/src/ui/api.d.ts.map +1 -1
  135. package/dist/src/ui/api.js +23 -1
  136. package/dist/src/ui/api.js.map +1 -1
  137. package/dist/src/ui/auth.d.ts +112 -0
  138. package/dist/src/ui/auth.d.ts.map +1 -0
  139. package/dist/src/ui/auth.js +130 -0
  140. package/dist/src/ui/auth.js.map +1 -0
  141. package/dist/src/ui/dashboard_auth.d.ts +34 -0
  142. package/dist/src/ui/dashboard_auth.d.ts.map +1 -0
  143. package/dist/src/ui/dashboard_auth.js +57 -0
  144. package/dist/src/ui/dashboard_auth.js.map +1 -0
  145. package/dist/src/ui/define_config.d.ts +15 -0
  146. package/dist/src/ui/define_config.d.ts.map +1 -1
  147. package/dist/src/ui/define_config.js +4 -0
  148. package/dist/src/ui/define_config.js.map +1 -1
  149. package/dist/src/ui/index.d.ts +7 -1
  150. package/dist/src/ui/index.d.ts.map +1 -1
  151. package/dist/src/ui/index.js +6 -1
  152. package/dist/src/ui/index.js.map +1 -1
  153. package/dist/src/ui/login_page.d.ts +23 -0
  154. package/dist/src/ui/login_page.d.ts.map +1 -0
  155. package/dist/src/ui/login_page.js +170 -0
  156. package/dist/src/ui/login_page.js.map +1 -0
  157. package/dist/src/ui/session_cookie.d.ts +42 -0
  158. package/dist/src/ui/session_cookie.d.ts.map +1 -0
  159. package/dist/src/ui/session_cookie.js +97 -0
  160. package/dist/src/ui/session_cookie.js.map +1 -0
  161. package/dist/src/watchers/define_config.d.ts +115 -12
  162. package/dist/src/watchers/define_config.d.ts.map +1 -1
  163. package/dist/src/watchers/define_config.js +48 -11
  164. package/dist/src/watchers/define_config.js.map +1 -1
  165. package/dist/src/watchers/http_client_watcher.d.ts +91 -31
  166. package/dist/src/watchers/http_client_watcher.d.ts.map +1 -1
  167. package/dist/src/watchers/http_client_watcher.js +161 -53
  168. package/dist/src/watchers/http_client_watcher.js.map +1 -1
  169. package/dist/src/watchers/index.d.ts +9 -5
  170. package/dist/src/watchers/index.d.ts.map +1 -1
  171. package/dist/src/watchers/index.js +6 -2
  172. package/dist/src/watchers/index.js.map +1 -1
  173. package/dist/src/watchers/lucid_query_watcher.d.ts +20 -2
  174. package/dist/src/watchers/lucid_query_watcher.d.ts.map +1 -1
  175. package/dist/src/watchers/lucid_query_watcher.js +44 -10
  176. package/dist/src/watchers/lucid_query_watcher.js.map +1 -1
  177. package/dist/src/watchers/profiling_watcher.d.ts +144 -0
  178. package/dist/src/watchers/profiling_watcher.d.ts.map +1 -0
  179. package/dist/src/watchers/profiling_watcher.js +231 -0
  180. package/dist/src/watchers/profiling_watcher.js.map +1 -0
  181. package/dist/src/watchers/query_family_hash.d.ts +7 -2
  182. package/dist/src/watchers/query_family_hash.d.ts.map +1 -1
  183. package/dist/src/watchers/query_family_hash.js +8 -3
  184. package/dist/src/watchers/query_family_hash.js.map +1 -1
  185. package/dist/src/watchers/record.d.ts.map +1 -1
  186. package/dist/src/watchers/record.js +4 -0
  187. package/dist/src/watchers/record.js.map +1 -1
  188. package/dist/src/watchers/schedule_watcher.d.ts +143 -0
  189. package/dist/src/watchers/schedule_watcher.d.ts.map +1 -0
  190. package/dist/src/watchers/schedule_watcher.js +195 -0
  191. package/dist/src/watchers/schedule_watcher.js.map +1 -0
  192. package/dist/stubs/config/telescope.stub +0 -65
  193. package/dist/stubs/config/telescope_ai.stub +0 -36
  194. package/dist/stubs/config/telescope_alerts.stub +0 -47
  195. package/dist/stubs/config/telescope_mcp.stub +0 -0
  196. package/dist/stubs/config/telescope_ui.stub +0 -53
  197. package/dist/stubs/config/telescope_watchers.stub +0 -41
  198. package/dist/stubs/database/migrations/create_telescope_entries_table.stub +2 -2
  199. package/package.json +12 -2
@@ -0,0 +1,143 @@
1
+ import { type RecordInput } from '../entry.js';
2
+ /** The `type` of the entries this watcher records. */
3
+ export declare const SCHEDULED_TASK_ENTRY_TYPE: "scheduled_task";
4
+ /** The terminal outcome of a single scheduled-task run. */
5
+ export type ScheduleRunStatus = 'completed' | 'failed';
6
+ /** What kind of schedule triggered the run (best-effort, informational). */
7
+ export type ScheduleKind = 'cron' | 'interval' | 'custom';
8
+ /** The recorded body of a `scheduled_task` entry. */
9
+ export interface ScheduleEntryContent {
10
+ /** The task name, e.g. `'prune-sessions'`. */
11
+ name: string;
12
+ /** The cron/interval expression, or `null` when the caller did not supply one. */
13
+ schedule: string | null;
14
+ /** The schedule kind. */
15
+ kind: ScheduleKind;
16
+ /** Wall-clock duration of the run in milliseconds. */
17
+ durationMs: number;
18
+ /** The run outcome. */
19
+ status: ScheduleRunStatus;
20
+ /** How many attempts the run represents, or `null`. */
21
+ attempts: number | null;
22
+ /** The failure message when `status` is `'failed'`, else `null`. */
23
+ failureReason: string | null;
24
+ /** The active trace id at run time, or `null`. */
25
+ traceId: string | null;
26
+ }
27
+ /** A single scheduled-task run — the input to {@link buildScheduleEntry} and
28
+ * {@link recordScheduledRun}. */
29
+ export interface ScheduledRun {
30
+ /** The task name. */
31
+ name: string;
32
+ /** The run outcome. */
33
+ status: ScheduleRunStatus;
34
+ /** Wall-clock duration of the run in milliseconds. */
35
+ durationMs: number;
36
+ /** The cron/interval expression, when known. */
37
+ schedule?: string | null;
38
+ /** The schedule kind. Default `'cron'`. */
39
+ kind?: ScheduleKind;
40
+ /** How many attempts the run represents, when known. */
41
+ attempts?: number | null;
42
+ /** The error on a failed run (its message is stored). */
43
+ error?: unknown;
44
+ }
45
+ /** Options for {@link ScheduleWatcher} and {@link ScheduleWatcher.scheduleTask}. */
46
+ export interface ScheduleWatcherOptions {
47
+ /** Runs at/above this many ms get a `slow` tag. Default 1000. */
48
+ slowMs?: number;
49
+ /** Time source; injectable for tests. Default `Date.now`. */
50
+ clock?: {
51
+ now(): number;
52
+ };
53
+ }
54
+ /** Per-task metadata for the {@link ScheduleWatcher.scheduleTask} wrapper. */
55
+ export interface ScheduledTaskOptions {
56
+ /** The cron/interval expression, recorded on each run. */
57
+ schedule?: string | null;
58
+ /** The schedule kind. Default `'cron'`. */
59
+ kind?: ScheduleKind;
60
+ }
61
+ /**
62
+ * Records each scheduled-task run as a `scheduled_task` telescope entry — capturing
63
+ * the task name, cron/interval expression, duration and outcome
64
+ * (completed/failed), correlated to the active trace.
65
+ *
66
+ * ## Integration point — a wrapper, by design (not a fake event)
67
+ * The NestJS original wraps `@nestjs/schedule`'s `@Cron`/`@Interval`/`@Timeout`
68
+ * decorators via its `SchedulerRegistry`. AdonisJS ships NO first-party scheduler,
69
+ * and the community schedulers (`adonisjs-scheduler` et al.) emit nothing on the
70
+ * app emitter and expose no lifecycle hook — so there is no stable event to tap.
71
+ * Rather than fabricate one, this watcher's integration point is EXPLICIT and
72
+ * idiomatic:
73
+ *
74
+ * - wrap a scheduled closure with {@link scheduleTask} (it times the run and
75
+ * records completed/failed, always re-throwing), or
76
+ * - call {@link recordScheduledRun} yourself from an existing scheduler callback
77
+ * (e.g. an ace `scheduler:run` command, or a scheduler that DOES surface a
78
+ * run hook) with the outcome you already have.
79
+ *
80
+ * (In the Agora ecosystem, `@adonis-agora/durable` also bridges its scheduled/cron
81
+ * runs onto the diagnostics bus, which the diagnostics watcher records — this
82
+ * watcher covers plain application-level scheduled work.)
83
+ *
84
+ * Each entry carries `familyHash` (`schedule:<name>`) and `durationMs`, so repeated
85
+ * runs of the same task roll up and feed the slow-hotspot metrics cards. Recording
86
+ * is fire-and-forget and fully guarded: a telescope failure can never break (or
87
+ * delay) a scheduled task.
88
+ *
89
+ * Idiomatic Adonis: a plain class, no DI decorators. The provider constructs it
90
+ * from `config/telescope_watchers.ts` and calls {@link start} to publish it as the
91
+ * default backing the bare {@link scheduleTask} / {@link recordScheduledRun}
92
+ * helpers; {@link stop} unpublishes.
93
+ */
94
+ export declare class ScheduleWatcher {
95
+ readonly type: "scheduled_task";
96
+ private readonly slowMs;
97
+ private readonly clock;
98
+ constructor(options?: ScheduleWatcherOptions);
99
+ /** Publish this configured instance as the default the standalone helpers
100
+ * inherit. Does NOT patch any global. Named `start`/`stop` to match the other
101
+ * watchers' provider lifecycle. */
102
+ start(): void;
103
+ /** Unpublish this instance as the default (if it is). Never touches globals. */
104
+ stop(): void;
105
+ /** Record one already-completed scheduled run. Fire-and-forget; never throws. */
106
+ record(run: ScheduledRun): void;
107
+ /**
108
+ * Time `fn` as a scheduled run named `name`. Records `completed` on
109
+ * return/resolve and `failed` on throw/reject, always re-throwing so the
110
+ * scheduler's own error handling is unaffected. Works with sync and async `fn`.
111
+ *
112
+ * @example
113
+ * scheduler.call(() => scheduleTask('prune-sessions', () => Session.pruneExpired(), {
114
+ * schedule: '0 * * * *',
115
+ * })).hourly()
116
+ */
117
+ scheduleTask<T>(name: string, fn: () => T, options?: ScheduledTaskOptions): T;
118
+ }
119
+ /** Map a scheduled run to a telescope {@link RecordInput}. Exported so the entry
120
+ * shape can be unit-tested without a live watcher. */
121
+ export declare function buildScheduleEntry(run: ScheduledRun, slowMs?: number): RecordInput<ScheduleEntryContent>;
122
+ /**
123
+ * Record one scheduled-task run through the provider-published default watcher.
124
+ * A NO-OP when the schedule watcher is not enabled, so it is safe to call from a
125
+ * scheduler callback unconditionally.
126
+ *
127
+ * @example
128
+ * import { recordScheduledRun } from '@adonis-agora/telescope/watchers'
129
+ * recordScheduledRun({ name: 'prune-sessions', status: 'completed', durationMs: 42 })
130
+ */
131
+ export declare function recordScheduledRun(run: ScheduledRun): void;
132
+ /**
133
+ * Time `fn` as a scheduled run through the provider-published default watcher. A
134
+ * no-op passthrough (just runs `fn`) when the schedule watcher is not enabled.
135
+ * This is the recommended integration point: wrap the closure you hand your
136
+ * scheduler.
137
+ *
138
+ * @example
139
+ * import { scheduleTask } from '@adonis-agora/telescope/watchers'
140
+ * scheduler.call(() => scheduleTask('report', () => sendDailyReport())).daily()
141
+ */
142
+ export declare function scheduleTask<T>(name: string, fn: () => T, options?: ScheduledTaskOptions): T;
143
+ //# sourceMappingURL=schedule_watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule_watcher.d.ts","sourceRoot":"","sources":["../../../src/watchers/schedule_watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,195 @@
1
+ import { currentTraceId } from '../context_accessor.js';
2
+ import { EntryType } from '../entry.js';
3
+ import { safeRecord } from './record.js';
4
+ /** The `type` of the entries this watcher records. */
5
+ export const SCHEDULED_TASK_ENTRY_TYPE = EntryType.ScheduledTask;
6
+ /** Default slow-run threshold in milliseconds. */
7
+ const DEFAULT_SLOW_MS = 1000;
8
+ /**
9
+ * Cross-copy-stable slot holding the provider-configured default watcher, so the
10
+ * standalone {@link recordScheduledRun} / {@link scheduleTask} helpers inherit the
11
+ * app's configured `slowMs` — and are a NO-OP until the provider starts the watcher
12
+ * (schedule capture stays strictly opt-in). Mirrors the http-client / profiling
13
+ * watchers' default-slot stance.
14
+ */
15
+ const DEFAULT_SLOT = Symbol.for('@agora/telescope:defaultScheduleWatcher');
16
+ const slotHost = globalThis;
17
+ function setDefaultScheduleWatcher(watcher) {
18
+ slotHost[DEFAULT_SLOT] = watcher;
19
+ }
20
+ function getDefaultScheduleWatcher() {
21
+ return slotHost[DEFAULT_SLOT] ?? null;
22
+ }
23
+ /**
24
+ * Records each scheduled-task run as a `scheduled_task` telescope entry — capturing
25
+ * the task name, cron/interval expression, duration and outcome
26
+ * (completed/failed), correlated to the active trace.
27
+ *
28
+ * ## Integration point — a wrapper, by design (not a fake event)
29
+ * The NestJS original wraps `@nestjs/schedule`'s `@Cron`/`@Interval`/`@Timeout`
30
+ * decorators via its `SchedulerRegistry`. AdonisJS ships NO first-party scheduler,
31
+ * and the community schedulers (`adonisjs-scheduler` et al.) emit nothing on the
32
+ * app emitter and expose no lifecycle hook — so there is no stable event to tap.
33
+ * Rather than fabricate one, this watcher's integration point is EXPLICIT and
34
+ * idiomatic:
35
+ *
36
+ * - wrap a scheduled closure with {@link scheduleTask} (it times the run and
37
+ * records completed/failed, always re-throwing), or
38
+ * - call {@link recordScheduledRun} yourself from an existing scheduler callback
39
+ * (e.g. an ace `scheduler:run` command, or a scheduler that DOES surface a
40
+ * run hook) with the outcome you already have.
41
+ *
42
+ * (In the Agora ecosystem, `@adonis-agora/durable` also bridges its scheduled/cron
43
+ * runs onto the diagnostics bus, which the diagnostics watcher records — this
44
+ * watcher covers plain application-level scheduled work.)
45
+ *
46
+ * Each entry carries `familyHash` (`schedule:<name>`) and `durationMs`, so repeated
47
+ * runs of the same task roll up and feed the slow-hotspot metrics cards. Recording
48
+ * is fire-and-forget and fully guarded: a telescope failure can never break (or
49
+ * delay) a scheduled task.
50
+ *
51
+ * Idiomatic Adonis: a plain class, no DI decorators. The provider constructs it
52
+ * from `config/telescope_watchers.ts` and calls {@link start} to publish it as the
53
+ * default backing the bare {@link scheduleTask} / {@link recordScheduledRun}
54
+ * helpers; {@link stop} unpublishes.
55
+ */
56
+ export class ScheduleWatcher {
57
+ type = EntryType.ScheduledTask;
58
+ slowMs;
59
+ clock;
60
+ constructor(options = {}) {
61
+ this.slowMs = options.slowMs ?? DEFAULT_SLOW_MS;
62
+ this.clock = options.clock ?? { now: () => Date.now() };
63
+ }
64
+ /** Publish this configured instance as the default the standalone helpers
65
+ * inherit. Does NOT patch any global. Named `start`/`stop` to match the other
66
+ * watchers' provider lifecycle. */
67
+ start() {
68
+ setDefaultScheduleWatcher(this);
69
+ }
70
+ /** Unpublish this instance as the default (if it is). Never touches globals. */
71
+ stop() {
72
+ if (getDefaultScheduleWatcher() === this)
73
+ setDefaultScheduleWatcher(null);
74
+ }
75
+ /** Record one already-completed scheduled run. Fire-and-forget; never throws. */
76
+ record(run) {
77
+ safeRecord(buildScheduleEntry(run, this.slowMs), 'ScheduleWatcher');
78
+ }
79
+ /**
80
+ * Time `fn` as a scheduled run named `name`. Records `completed` on
81
+ * return/resolve and `failed` on throw/reject, always re-throwing so the
82
+ * scheduler's own error handling is unaffected. Works with sync and async `fn`.
83
+ *
84
+ * @example
85
+ * scheduler.call(() => scheduleTask('prune-sessions', () => Session.pruneExpired(), {
86
+ * schedule: '0 * * * *',
87
+ * })).hourly()
88
+ */
89
+ scheduleTask(name, fn, options = {}) {
90
+ const startedAt = this.clock.now();
91
+ const finish = (status, error) => {
92
+ this.record({
93
+ name,
94
+ status,
95
+ durationMs: Math.max(0, this.clock.now() - startedAt),
96
+ schedule: options.schedule ?? null,
97
+ kind: options.kind ?? 'cron',
98
+ error,
99
+ });
100
+ };
101
+ let result;
102
+ try {
103
+ result = fn();
104
+ }
105
+ catch (error) {
106
+ finish('failed', error);
107
+ throw error;
108
+ }
109
+ if (isPromiseLike(result)) {
110
+ return result.then((value) => {
111
+ finish('completed', undefined);
112
+ return value;
113
+ }, (error) => {
114
+ finish('failed', error);
115
+ throw error;
116
+ });
117
+ }
118
+ finish('completed', undefined);
119
+ return result;
120
+ }
121
+ }
122
+ /** Narrow a value to a thenable so async `fn`s are awaited without importing a Promise type. */
123
+ function isPromiseLike(value) {
124
+ return (typeof value === 'object' &&
125
+ value !== null &&
126
+ typeof value.then === 'function');
127
+ }
128
+ /** Map a scheduled run to a telescope {@link RecordInput}. Exported so the entry
129
+ * shape can be unit-tested without a live watcher. */
130
+ export function buildScheduleEntry(run, slowMs = DEFAULT_SLOW_MS) {
131
+ const durationMs = Math.max(0, run.durationMs);
132
+ const failed = run.status === 'failed';
133
+ const failureReason = failed && run.error !== undefined ? errorMessage(run.error) : null;
134
+ const kind = run.kind ?? 'cron';
135
+ const schedule = typeof run.schedule === 'string' ? run.schedule : null;
136
+ const attempts = typeof run.attempts === 'number' ? run.attempts : null;
137
+ const traceId = currentTraceId();
138
+ const content = {
139
+ name: run.name,
140
+ schedule,
141
+ kind,
142
+ durationMs,
143
+ status: run.status,
144
+ attempts,
145
+ failureReason,
146
+ traceId,
147
+ };
148
+ const tags = ['schedule', `schedule:${kind}`, `task:${run.name}`, `status:${run.status}`];
149
+ if (failed)
150
+ tags.push('failed');
151
+ if (durationMs >= slowMs)
152
+ tags.push('slow');
153
+ return {
154
+ type: EntryType.ScheduledTask,
155
+ // Group by task name so every run of the same task rolls up — the slow-hotspot key.
156
+ familyHash: `schedule:${run.name}`,
157
+ content,
158
+ durationMs,
159
+ origin: 'schedule',
160
+ traceId,
161
+ tags,
162
+ };
163
+ }
164
+ function errorMessage(error) {
165
+ return error instanceof Error ? error.message : String(error);
166
+ }
167
+ /**
168
+ * Record one scheduled-task run through the provider-published default watcher.
169
+ * A NO-OP when the schedule watcher is not enabled, so it is safe to call from a
170
+ * scheduler callback unconditionally.
171
+ *
172
+ * @example
173
+ * import { recordScheduledRun } from '@adonis-agora/telescope/watchers'
174
+ * recordScheduledRun({ name: 'prune-sessions', status: 'completed', durationMs: 42 })
175
+ */
176
+ export function recordScheduledRun(run) {
177
+ getDefaultScheduleWatcher()?.record(run);
178
+ }
179
+ /**
180
+ * Time `fn` as a scheduled run through the provider-published default watcher. A
181
+ * no-op passthrough (just runs `fn`) when the schedule watcher is not enabled.
182
+ * This is the recommended integration point: wrap the closure you hand your
183
+ * scheduler.
184
+ *
185
+ * @example
186
+ * import { scheduleTask } from '@adonis-agora/telescope/watchers'
187
+ * scheduler.call(() => scheduleTask('report', () => sendDailyReport())).daily()
188
+ */
189
+ export function scheduleTask(name, fn, options) {
190
+ const watcher = getDefaultScheduleWatcher();
191
+ if (watcher)
192
+ return watcher.scheduleTask(name, fn, options);
193
+ return fn();
194
+ }
195
+ //# sourceMappingURL=schedule_watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule_watcher.js","sourceRoot":"","sources":["../../../src/watchers/schedule_watcher.ts"],"names":[],"mappings":"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"}
@@ -1,65 +0,0 @@
1
- {{{
2
- exports({ to: app.configPath('telescope.ts') })
3
- }}}
4
- import { defineConfig, storage } from '@adonis-agora/telescope'
5
-
6
- /**
7
- * Configuration for `@adonis-agora/telescope`. Everything is optional — the defaults use
8
- * the in-memory store with both watchers (`request` + `diagnostics`) enabled and a
9
- * 1000-entry cap.
10
- */
11
- export default defineConfig({
12
- /**
13
- * Master switch. Set to `false` to disable all recording (zero overhead).
14
- */
15
- // enabled: true,
16
-
17
- /**
18
- * Which named store backs telescope. The active driver is selected by `store`
19
- * and built from the `stores` map below.
20
- */
21
- store: 'memory',
22
-
23
- /**
24
- * Named store drivers, built with the `storage` factory. Each is a lazy thunk —
25
- * its peer dependency is only imported when that driver is the active one.
26
- *
27
- * To persist entries across restarts, install `@adonisjs/lucid`, publish the
28
- * migration (`node ace make:migration create_telescope_entries_table`, copying the
29
- * body from this package's stub) or pass `autoCreateTable: true`, switch
30
- * `store` to `'lucid'`, and uncomment the lucid driver:
31
- */
32
- stores: {
33
- memory: storage.memory({ limit: 1000 }),
34
- // lucid: storage.lucid({ connection: 'pg' }),
35
- },
36
-
37
- /**
38
- * Active watchers. Omit one to disable it.
39
- * - 'request' — records each HTTP request (method, url, status, duration).
40
- * - 'diagnostics' — records every `agora:<lib>:<event>` diagnostics publish.
41
- */
42
- // watchers: ['request', 'diagnostics'],
43
-
44
- /**
45
- * Sensitive-data redaction. Every entry's content is scrubbed before it is
46
- * persisted — a built-in set of sensitive keys (`authorization`, `cookie`,
47
- * `password`, `token`, `api_key`, `secret`, `set-cookie`, …) is masked with
48
- * `[REDACTED]`, case-insensitively, at any depth. ENABLED by default.
49
- *
50
- * Add your own keys, or disable redaction entirely:
51
- */
52
- // redact: {
53
- // enabled: true,
54
- // keys: ['ssn', 'credit_card'],
55
- // },
56
-
57
- /**
58
- * Live SSE streaming of new entries to the dashboard. ENABLED by default and
59
- * zero-overhead while no dashboard is connected. Set `enabled: false` to turn
60
- * the `<telescope>/api/stream` endpoint off entirely.
61
- */
62
- // stream: {
63
- // enabled: true,
64
- // },
65
- })
@@ -1,36 +0,0 @@
1
- {{{
2
- exports({ to: app.configPath('telescope_ai.ts') })
3
- }}}
4
- import env from '#start/env'
5
- import { defineConfig } from '@adonis-agora/telescope/ai'
6
-
7
- /**
8
- * Configuration for `@adonis-agora/telescope/ai`. Diagnosis is on when an Anthropic API
9
- * key resolves from the environment; with no key the diagnoser is a safe no-op.
10
- *
11
- * Add `ANTHROPIC_API_KEY` to your `.env` and validate it in `start/env.ts`:
12
- * ANTHROPIC_API_KEY: Env.schema.string.optional()
13
- */
14
- export default defineConfig({
15
- /**
16
- * Master switch. Set to `false` to disable diagnosis entirely.
17
- */
18
- // enabled: true,
19
-
20
- /**
21
- * The Anthropic API key — sourced from the environment, never hardcoded.
22
- */
23
- apiKey: env.get('ANTHROPIC_API_KEY'),
24
-
25
- /**
26
- * Claude model id. Defaults to `claude-sonnet-4-6` (best speed/intelligence
27
- * balance). Use `claude-opus-4-8` for the most capable diagnosis, or
28
- * `claude-haiku-4-5-20251001` for the cheapest.
29
- */
30
- // model: 'claude-sonnet-4-6',
31
-
32
- /**
33
- * Hard cap on generated tokens per diagnosis. Default 1024.
34
- */
35
- // maxTokens: 1024,
36
- })
@@ -1,47 +0,0 @@
1
- {{{
2
- exports({ to: app.configPath('telescope_alerts.ts') })
3
- }}}
4
- import { defineConfig } from '@adonis-agora/telescope/alerts'
5
-
6
- /**
7
- * Configuration for `@adonis-agora/telescope/alerts`. By default alerting is on, polls the
8
- * telescope store every 30s for brand-new exception families, and logs each alert
9
- * to the console. Add a Slack or generic webhook channel to ship alerts off-box.
10
- */
11
- export default defineConfig({
12
- /**
13
- * Master switch. Set to `false` to disable alerting entirely.
14
- */
15
- // enabled: true,
16
-
17
- /**
18
- * Delivery destinations. Each fired alert is sent to every channel concurrently;
19
- * one channel failing never blocks the others. Accepts declarative specs or
20
- * pre-built channel objects (slackChannel/webhookChannel/customChannel).
21
- */
22
- // channels: [
23
- // { type: 'console' },
24
- // { type: 'slack', url: env.get('TELESCOPE_SLACK_WEBHOOK') },
25
- // { type: 'webhook', url: env.get('TELESCOPE_ALERT_WEBHOOK') },
26
- // ],
27
-
28
- /**
29
- * Rules to evaluate.
30
- * - { type: 'new-exception', window } — page the first time an exception family
31
- * is seen within `window` (and again after it elapses / on resolve).
32
- * - { type: 'exception-rate', window, threshold } — page when >= threshold
33
- * exceptions are recorded in the trailing `window`.
34
- */
35
- // rules: [{ type: 'new-exception', window: '1h' }],
36
-
37
- /**
38
- * External dashboard URL — when set, Slack alerts include a deep link to the entry.
39
- */
40
- // dashboardUrl: 'https://telescope.example.com/',
41
-
42
- /**
43
- * Poll cadence and re-notify cooldown (duration strings).
44
- */
45
- // every: '30s',
46
- // cooldown: '15m',
47
- })
File without changes
@@ -1,53 +0,0 @@
1
- {{{
2
- exports({ to: app.configPath('telescope_ui.ts') })
3
- }}}
4
- import { defineConfig } from '@adonis-agora/telescope/ui'
5
-
6
- /**
7
- * Configuration for `@adonis-agora/telescope/ui`. By default the dashboard mounts at
8
- * `/telescope` and is reachable automatically outside production. In production it
9
- * is denied unless you set a `token` / `basic` credential below, or supply your
10
- * own `authorize` hook delegating to your app's auth.
11
- */
12
- export default defineConfig({
13
- /**
14
- * Master switch. Set to `false` to register no routes at all.
15
- */
16
- // enabled: true,
17
-
18
- /**
19
- * URL prefix. The dashboard is served here; the JSON API lives at `<path>/api/*`.
20
- */
21
- // path: '/telescope',
22
-
23
- /**
24
- * Access-decision hook. Return `true` to allow the request, `false` to reject it
25
- * (the guard answers 401 when no credential was presented, 403 when one was and
26
- * was rejected). Delegate to your own app auth here, e.g.:
27
- */
28
- // authorize: (ctx) => ctx.auth?.user?.isAdmin === true,
29
-
30
- /**
31
- * Built-in credentials for the default policy (ignored when `authorize` is set).
32
- * Gate a production dashboard without writing a hook:
33
- * - token: allow `Authorization: Bearer <token>` or `?token=<token>`
34
- * - basic: allow HTTP Basic auth
35
- */
36
- // credentials: {
37
- // token: env.get('TELESCOPE_UI_TOKEN'),
38
- // basic: { username: 'admin', password: env.get('TELESCOPE_UI_PASSWORD') },
39
- // },
40
-
41
- /**
42
- * Request REPLAY: re-issue a captured request from the dashboard against the
43
- * LOCAL server. DISABLED BY DEFAULT because it re-runs a real request that may
44
- * MUTATE state (a captured POST/DELETE runs again). It only ever targets
45
- * `127.0.0.1:<port>` (same-origin, never an arbitrary URL) and strips
46
- * cookie/authorization/host headers. Enable it knowingly:
47
- */
48
- // replay: {
49
- // enabled: true,
50
- // // port: 3333, // defaults to PORT env or 3000
51
- // // timeoutMs: 30000,
52
- // },
53
- })
@@ -1,41 +0,0 @@
1
- {{{
2
- exports({ to: app.configPath('telescope_watchers.ts') })
3
- }}}
4
- import { defineConfig } from '@adonis-agora/telescope/watchers'
5
-
6
- /**
7
- * Configuration for `@adonis-agora/telescope/watchers`. By default only the Lucid
8
- * `query` watcher is enabled — its `db:query` event is verified against the
9
- * installed `@adonisjs/lucid` types. The `mail` and `cache` watchers are opt-in.
10
- */
11
- export default defineConfig({
12
- /**
13
- * Master switch. Set to `false` to start no per-technology watcher.
14
- */
15
- // enabled: true,
16
-
17
- /**
18
- * Active watchers. Omit one to disable it.
19
- * - 'query' — records every Lucid SQL query (sql, bindings, duration, connection).
20
- * - 'mail' — records every email sent (mail:sent).
21
- * - 'cache' — records @adonisjs/cache hit/miss/write/delete events.
22
- * - 'http-client' — records every outbound fetch call (method, url, status, duration).
23
- * - 'logs' — records AdonisJS logger output (level, message, structured fields).
24
- * - 'queue' — records @adonisjs/queue job executions (optional peer; engine
25
- * diagnostics-channel trace). No-op when the peer is absent.
26
- * - 'events' — records every event emitted through the core Emitter (onAny),
27
- * with an ignore-list (db:query / mail:sent are excluded by default).
28
- * - 'redis' — records @adonisjs/redis commands (optional peer; wraps the
29
- * ioredis sendCommand). No-op when the peer is absent.
30
- *
31
- * Note: the 'mail' / 'cache' / 'queue' / 'redis' event contracts are best-effort —
32
- * those packages are not present in this repo, so their event names/payloads could
33
- * not be verified against their types. See the package README.
34
- *
35
- * There is intentionally NO 'schedule' watcher: AdonisJS ships no first-party
36
- * scheduler and community schedulers expose no event/hook surface to tap. In the
37
- * Agora ecosystem, @adonis-agora/durable bridges scheduled/cron runs onto the
38
- * diagnostics bus, which the diagnostics watcher already records.
39
- */
40
- // watchers: ['query'],
41
- })
@@ -4,9 +4,9 @@
4
4
  import { BaseSchema } from '@adonisjs/lucid/schema'
5
5
 
6
6
  /**
7
- * Creates the table the `lucid` telescope store persists entries into.
7
+ * Creates the table the 'lucid' telescope store persists entries into.
8
8
  *
9
- * `content` and `tags` are JSON text columns; `created_at` is stored as epoch
9
+ * 'content' and 'tags' are JSON text columns; 'created_at' is stored as epoch
10
10
  * milliseconds (a plain integer) so newest-first ordering and age-based pruning
11
11
  * are driver-agnostic integer comparisons across sqlite / Postgres / MySQL.
12
12
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/telescope",
3
- "version": "0.3.3",
3
+ "version": "0.5.0",
4
4
  "description": "Laravel Telescope-style headless observability for AdonisJS — records HTTP requests and every Agora diagnostics event as queryable entries, plus opt-in subpaths for per-technology watchers, a web dashboard, AI exception diagnosis, and alerting.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -63,6 +63,16 @@
63
63
  "import": "./dist/providers/telescope_ai_provider.js",
64
64
  "default": "./dist/providers/telescope_ai_provider.js"
65
65
  },
66
+ "./mcp": {
67
+ "types": "./dist/src/mcp/index.d.ts",
68
+ "import": "./dist/src/mcp/index.js",
69
+ "default": "./dist/src/mcp/index.js"
70
+ },
71
+ "./mcp_provider": {
72
+ "types": "./dist/providers/telescope_mcp_provider.d.ts",
73
+ "import": "./dist/providers/telescope_mcp_provider.js",
74
+ "default": "./dist/providers/telescope_mcp_provider.js"
75
+ },
66
76
  "./alerts": {
67
77
  "types": "./dist/src/alerts/index.d.ts",
68
78
  "import": "./dist/src/alerts/index.js",
@@ -131,7 +141,7 @@
131
141
  ],
132
142
  "scripts": {
133
143
  "build": "tsc -p tsconfig.json && pnpm run copy:stubs && pnpm run copy:assets",
134
- "copy:stubs": "mkdir -p dist/stubs/config dist/stubs/database/migrations && cp stubs/config/telescope.stub dist/stubs/config/telescope.stub && cp stubs/config/telescope_watchers.stub dist/stubs/config/telescope_watchers.stub && cp stubs/config/telescope_ui.stub dist/stubs/config/telescope_ui.stub && cp stubs/config/telescope_ai.stub dist/stubs/config/telescope_ai.stub && cp stubs/config/telescope_alerts.stub dist/stubs/config/telescope_alerts.stub && cp stubs/database/migrations/create_telescope_entries_table.stub dist/stubs/database/migrations/create_telescope_entries_table.stub",
144
+ "copy:stubs": "mkdir -p dist/stubs/config dist/stubs/database/migrations && cp stubs/config/telescope.stub dist/stubs/config/telescope.stub && cp stubs/config/telescope_watchers.stub dist/stubs/config/telescope_watchers.stub && cp stubs/config/telescope_ui.stub dist/stubs/config/telescope_ui.stub && cp stubs/config/telescope_ai.stub dist/stubs/config/telescope_ai.stub && cp stubs/config/telescope_alerts.stub dist/stubs/config/telescope_alerts.stub && cp stubs/config/telescope_mcp.stub dist/stubs/config/telescope_mcp.stub && cp stubs/database/migrations/create_telescope_entries_table.stub dist/stubs/database/migrations/create_telescope_entries_table.stub",
135
145
  "copy:assets": "mkdir -p dist/src/ui && cp src/ui/dashboard.html dist/src/ui/dashboard.html",
136
146
  "test": "vitest run --passWithNoTests",
137
147
  "test:watch": "vitest",