@adonis-agora/telescope 0.1.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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -0
  3. package/dist/configure.d.ts +16 -0
  4. package/dist/configure.d.ts.map +1 -0
  5. package/dist/configure.js +75 -0
  6. package/dist/configure.js.map +1 -0
  7. package/dist/providers/telescope_ai_provider.d.ts +20 -0
  8. package/dist/providers/telescope_ai_provider.d.ts.map +1 -0
  9. package/dist/providers/telescope_ai_provider.js +45 -0
  10. package/dist/providers/telescope_ai_provider.js.map +1 -0
  11. package/dist/providers/telescope_alerts_provider.d.ts +23 -0
  12. package/dist/providers/telescope_alerts_provider.d.ts.map +1 -0
  13. package/dist/providers/telescope_alerts_provider.js +72 -0
  14. package/dist/providers/telescope_alerts_provider.js.map +1 -0
  15. package/dist/providers/telescope_provider.d.ts +43 -0
  16. package/dist/providers/telescope_provider.d.ts.map +1 -0
  17. package/dist/providers/telescope_provider.js +103 -0
  18. package/dist/providers/telescope_provider.js.map +1 -0
  19. package/dist/providers/telescope_ui_provider.d.ts +21 -0
  20. package/dist/providers/telescope_ui_provider.d.ts.map +1 -0
  21. package/dist/providers/telescope_ui_provider.js +119 -0
  22. package/dist/providers/telescope_ui_provider.js.map +1 -0
  23. package/dist/providers/telescope_watchers_provider.d.ts +31 -0
  24. package/dist/providers/telescope_watchers_provider.d.ts.map +1 -0
  25. package/dist/providers/telescope_watchers_provider.js +116 -0
  26. package/dist/providers/telescope_watchers_provider.js.map +1 -0
  27. package/dist/src/ai/define_config.d.ts +56 -0
  28. package/dist/src/ai/define_config.d.ts.map +1 -0
  29. package/dist/src/ai/define_config.js +39 -0
  30. package/dist/src/ai/define_config.js.map +1 -0
  31. package/dist/src/ai/diagnoser.d.ts +34 -0
  32. package/dist/src/ai/diagnoser.d.ts.map +1 -0
  33. package/dist/src/ai/diagnoser.js +74 -0
  34. package/dist/src/ai/diagnoser.js.map +1 -0
  35. package/dist/src/ai/diagnosis_cache.d.ts +43 -0
  36. package/dist/src/ai/diagnosis_cache.d.ts.map +1 -0
  37. package/dist/src/ai/diagnosis_cache.js +56 -0
  38. package/dist/src/ai/diagnosis_cache.js.map +1 -0
  39. package/dist/src/ai/factory.d.ts +15 -0
  40. package/dist/src/ai/factory.d.ts.map +1 -0
  41. package/dist/src/ai/factory.js +24 -0
  42. package/dist/src/ai/factory.js.map +1 -0
  43. package/dist/src/ai/index.d.ts +14 -0
  44. package/dist/src/ai/index.d.ts.map +1 -0
  45. package/dist/src/ai/index.js +15 -0
  46. package/dist/src/ai/index.js.map +1 -0
  47. package/dist/src/ai/prompt.d.ts +31 -0
  48. package/dist/src/ai/prompt.d.ts.map +1 -0
  49. package/dist/src/ai/prompt.js +66 -0
  50. package/dist/src/ai/prompt.js.map +1 -0
  51. package/dist/src/ai/telescope_ai_diagnoser.d.ts +79 -0
  52. package/dist/src/ai/telescope_ai_diagnoser.d.ts.map +1 -0
  53. package/dist/src/ai/telescope_ai_diagnoser.js +111 -0
  54. package/dist/src/ai/telescope_ai_diagnoser.js.map +1 -0
  55. package/dist/src/alerts/alert_channel.d.ts +69 -0
  56. package/dist/src/alerts/alert_channel.d.ts.map +1 -0
  57. package/dist/src/alerts/alert_channel.js +114 -0
  58. package/dist/src/alerts/alert_channel.js.map +1 -0
  59. package/dist/src/alerts/alert_rule.d.ts +86 -0
  60. package/dist/src/alerts/alert_rule.d.ts.map +1 -0
  61. package/dist/src/alerts/alert_rule.js +2 -0
  62. package/dist/src/alerts/alert_rule.js.map +1 -0
  63. package/dist/src/alerts/alerter.d.ts +72 -0
  64. package/dist/src/alerts/alerter.d.ts.map +1 -0
  65. package/dist/src/alerts/alerter.js +248 -0
  66. package/dist/src/alerts/alerter.js.map +1 -0
  67. package/dist/src/alerts/define_config.d.ts +68 -0
  68. package/dist/src/alerts/define_config.d.ts.map +1 -0
  69. package/dist/src/alerts/define_config.js +57 -0
  70. package/dist/src/alerts/define_config.js.map +1 -0
  71. package/dist/src/alerts/exception_source.d.ts +44 -0
  72. package/dist/src/alerts/exception_source.d.ts.map +1 -0
  73. package/dist/src/alerts/exception_source.js +79 -0
  74. package/dist/src/alerts/exception_source.js.map +1 -0
  75. package/dist/src/alerts/index.d.ts +16 -0
  76. package/dist/src/alerts/index.d.ts.map +1 -0
  77. package/dist/src/alerts/index.js +17 -0
  78. package/dist/src/alerts/index.js.map +1 -0
  79. package/dist/src/alerts/new_exception_tracker.d.ts +50 -0
  80. package/dist/src/alerts/new_exception_tracker.d.ts.map +1 -0
  81. package/dist/src/alerts/new_exception_tracker.js +74 -0
  82. package/dist/src/alerts/new_exception_tracker.js.map +1 -0
  83. package/dist/src/alerts/parse_duration.d.ts +10 -0
  84. package/dist/src/alerts/parse_duration.d.ts.map +1 -0
  85. package/dist/src/alerts/parse_duration.js +27 -0
  86. package/dist/src/alerts/parse_duration.js.map +1 -0
  87. package/dist/src/alerts/slack_format.d.ts +60 -0
  88. package/dist/src/alerts/slack_format.d.ts.map +1 -0
  89. package/dist/src/alerts/slack_format.js +122 -0
  90. package/dist/src/alerts/slack_format.js.map +1 -0
  91. package/dist/src/context_accessor.d.ts +30 -0
  92. package/dist/src/context_accessor.d.ts.map +1 -0
  93. package/dist/src/context_accessor.js +20 -0
  94. package/dist/src/context_accessor.js.map +1 -0
  95. package/dist/src/define_config.d.ts +109 -0
  96. package/dist/src/define_config.d.ts.map +1 -0
  97. package/dist/src/define_config.js +38 -0
  98. package/dist/src/define_config.js.map +1 -0
  99. package/dist/src/diagnostics_registry.d.ts +46 -0
  100. package/dist/src/diagnostics_registry.d.ts.map +1 -0
  101. package/dist/src/diagnostics_registry.js +34 -0
  102. package/dist/src/diagnostics_registry.js.map +1 -0
  103. package/dist/src/diagnostics_watcher.d.ts +72 -0
  104. package/dist/src/diagnostics_watcher.d.ts.map +1 -0
  105. package/dist/src/diagnostics_watcher.js +119 -0
  106. package/dist/src/diagnostics_watcher.js.map +1 -0
  107. package/dist/src/entry.d.ts +81 -0
  108. package/dist/src/entry.d.ts.map +1 -0
  109. package/dist/src/entry.js +34 -0
  110. package/dist/src/entry.js.map +1 -0
  111. package/dist/src/exception_family_hash.d.ts +29 -0
  112. package/dist/src/exception_family_hash.d.ts.map +1 -0
  113. package/dist/src/exception_family_hash.js +30 -0
  114. package/dist/src/exception_family_hash.js.map +1 -0
  115. package/dist/src/exception_watcher.d.ts +66 -0
  116. package/dist/src/exception_watcher.d.ts.map +1 -0
  117. package/dist/src/exception_watcher.js +94 -0
  118. package/dist/src/exception_watcher.js.map +1 -0
  119. package/dist/src/extension/registry.d.ts +17 -0
  120. package/dist/src/extension/registry.d.ts.map +1 -0
  121. package/dist/src/extension/registry.js +56 -0
  122. package/dist/src/extension/registry.js.map +1 -0
  123. package/dist/src/extension/types.d.ts +158 -0
  124. package/dist/src/extension/types.d.ts.map +1 -0
  125. package/dist/src/extension/types.js +5 -0
  126. package/dist/src/extension/types.js.map +1 -0
  127. package/dist/src/index.d.ts +36 -0
  128. package/dist/src/index.d.ts.map +1 -0
  129. package/dist/src/index.js +28 -0
  130. package/dist/src/index.js.map +1 -0
  131. package/dist/src/redaction/redact.d.ts +93 -0
  132. package/dist/src/redaction/redact.d.ts.map +1 -0
  133. package/dist/src/redaction/redact.js +184 -0
  134. package/dist/src/redaction/redact.js.map +1 -0
  135. package/dist/src/redaction/redacting_store.d.ts +28 -0
  136. package/dist/src/redaction/redacting_store.d.ts.map +1 -0
  137. package/dist/src/redaction/redacting_store.js +49 -0
  138. package/dist/src/redaction/redacting_store.js.map +1 -0
  139. package/dist/src/registry.d.ts +26 -0
  140. package/dist/src/registry.d.ts.map +1 -0
  141. package/dist/src/registry.js +28 -0
  142. package/dist/src/registry.js.map +1 -0
  143. package/dist/src/request_watcher.d.ts +44 -0
  144. package/dist/src/request_watcher.d.ts.map +1 -0
  145. package/dist/src/request_watcher.js +37 -0
  146. package/dist/src/request_watcher.js.map +1 -0
  147. package/dist/src/service.d.ts +36 -0
  148. package/dist/src/service.d.ts.map +1 -0
  149. package/dist/src/service.js +65 -0
  150. package/dist/src/service.js.map +1 -0
  151. package/dist/src/store.d.ts +56 -0
  152. package/dist/src/store.d.ts.map +1 -0
  153. package/dist/src/store.js +2 -0
  154. package/dist/src/store.js.map +1 -0
  155. package/dist/src/stores/factory.d.ts +61 -0
  156. package/dist/src/stores/factory.d.ts.map +1 -0
  157. package/dist/src/stores/factory.js +42 -0
  158. package/dist/src/stores/factory.js.map +1 -0
  159. package/dist/src/stores/lucid.d.ts +138 -0
  160. package/dist/src/stores/lucid.d.ts.map +1 -0
  161. package/dist/src/stores/lucid.js +257 -0
  162. package/dist/src/stores/lucid.js.map +1 -0
  163. package/dist/src/stores/memory.d.ts +31 -0
  164. package/dist/src/stores/memory.d.ts.map +1 -0
  165. package/dist/src/stores/memory.js +117 -0
  166. package/dist/src/stores/memory.js.map +1 -0
  167. package/dist/src/telescope_middleware.d.ts +19 -0
  168. package/dist/src/telescope_middleware.d.ts.map +1 -0
  169. package/dist/src/telescope_middleware.js +56 -0
  170. package/dist/src/telescope_middleware.js.map +1 -0
  171. package/dist/src/ui/api.d.ts +49 -0
  172. package/dist/src/ui/api.d.ts.map +1 -0
  173. package/dist/src/ui/api.js +155 -0
  174. package/dist/src/ui/api.js.map +1 -0
  175. package/dist/src/ui/dashboard.d.ts +8 -0
  176. package/dist/src/ui/dashboard.d.ts.map +1 -0
  177. package/dist/src/ui/dashboard.html +626 -0
  178. package/dist/src/ui/dashboard.js +29 -0
  179. package/dist/src/ui/dashboard.js.map +1 -0
  180. package/dist/src/ui/define_config.d.ts +87 -0
  181. package/dist/src/ui/define_config.d.ts.map +1 -0
  182. package/dist/src/ui/define_config.js +104 -0
  183. package/dist/src/ui/define_config.js.map +1 -0
  184. package/dist/src/ui/extension_api.d.ts +23 -0
  185. package/dist/src/ui/extension_api.d.ts.map +1 -0
  186. package/dist/src/ui/extension_api.js +50 -0
  187. package/dist/src/ui/extension_api.js.map +1 -0
  188. package/dist/src/ui/guard.d.ts +33 -0
  189. package/dist/src/ui/guard.d.ts.map +1 -0
  190. package/dist/src/ui/guard.js +47 -0
  191. package/dist/src/ui/guard.js.map +1 -0
  192. package/dist/src/ui/http.d.ts +47 -0
  193. package/dist/src/ui/http.d.ts.map +1 -0
  194. package/dist/src/ui/http.js +43 -0
  195. package/dist/src/ui/http.js.map +1 -0
  196. package/dist/src/ui/index.d.ts +12 -0
  197. package/dist/src/ui/index.d.ts.map +1 -0
  198. package/dist/src/ui/index.js +13 -0
  199. package/dist/src/ui/index.js.map +1 -0
  200. package/dist/src/watchers/cache_watcher.d.ts +60 -0
  201. package/dist/src/watchers/cache_watcher.d.ts.map +1 -0
  202. package/dist/src/watchers/cache_watcher.js +72 -0
  203. package/dist/src/watchers/cache_watcher.js.map +1 -0
  204. package/dist/src/watchers/define_config.d.ts +38 -0
  205. package/dist/src/watchers/define_config.d.ts.map +1 -0
  206. package/dist/src/watchers/define_config.js +17 -0
  207. package/dist/src/watchers/define_config.js.map +1 -0
  208. package/dist/src/watchers/emitter.d.ts +32 -0
  209. package/dist/src/watchers/emitter.d.ts.map +1 -0
  210. package/dist/src/watchers/emitter.js +2 -0
  211. package/dist/src/watchers/emitter.js.map +1 -0
  212. package/dist/src/watchers/http_client_watcher.d.ts +74 -0
  213. package/dist/src/watchers/http_client_watcher.d.ts.map +1 -0
  214. package/dist/src/watchers/http_client_watcher.js +168 -0
  215. package/dist/src/watchers/http_client_watcher.js.map +1 -0
  216. package/dist/src/watchers/index.d.ts +19 -0
  217. package/dist/src/watchers/index.d.ts.map +1 -0
  218. package/dist/src/watchers/index.js +19 -0
  219. package/dist/src/watchers/index.js.map +1 -0
  220. package/dist/src/watchers/logs_watcher.d.ts +82 -0
  221. package/dist/src/watchers/logs_watcher.d.ts.map +1 -0
  222. package/dist/src/watchers/logs_watcher.js +145 -0
  223. package/dist/src/watchers/logs_watcher.js.map +1 -0
  224. package/dist/src/watchers/lucid_query_watcher.d.ts +64 -0
  225. package/dist/src/watchers/lucid_query_watcher.d.ts.map +1 -0
  226. package/dist/src/watchers/lucid_query_watcher.js +84 -0
  227. package/dist/src/watchers/lucid_query_watcher.js.map +1 -0
  228. package/dist/src/watchers/mail_watcher.d.ts +51 -0
  229. package/dist/src/watchers/mail_watcher.d.ts.map +1 -0
  230. package/dist/src/watchers/mail_watcher.js +93 -0
  231. package/dist/src/watchers/mail_watcher.js.map +1 -0
  232. package/dist/src/watchers/normalize_http_target.d.ts +17 -0
  233. package/dist/src/watchers/normalize_http_target.d.ts.map +1 -0
  234. package/dist/src/watchers/normalize_http_target.js +41 -0
  235. package/dist/src/watchers/normalize_http_target.js.map +1 -0
  236. package/dist/src/watchers/query_family_hash.d.ts +8 -0
  237. package/dist/src/watchers/query_family_hash.d.ts.map +1 -0
  238. package/dist/src/watchers/query_family_hash.js +31 -0
  239. package/dist/src/watchers/query_family_hash.js.map +1 -0
  240. package/dist/src/watchers/record.d.ts +22 -0
  241. package/dist/src/watchers/record.d.ts.map +1 -0
  242. package/dist/src/watchers/record.js +48 -0
  243. package/dist/src/watchers/record.js.map +1 -0
  244. package/dist/stubs/config/telescope.stub +56 -0
  245. package/dist/stubs/config/telescope_ai.stub +36 -0
  246. package/dist/stubs/config/telescope_alerts.stub +47 -0
  247. package/dist/stubs/config/telescope_ui.stub +40 -0
  248. package/dist/stubs/config/telescope_watchers.stub +30 -0
  249. package/dist/stubs/database/migrations/create_telescope_entries_table.stub +39 -0
  250. package/dist/stubs/main.d.ts +6 -0
  251. package/dist/stubs/main.d.ts.map +1 -0
  252. package/dist/stubs/main.js +7 -0
  253. package/dist/stubs/main.js.map +1 -0
  254. package/package.json +140 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Davi Carvalho
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,26 @@
1
+ # `@adonis-agora/telescope`
2
+
3
+ Laravel Telescope-style **headless** observability for AdonisJS — records every
4
+ HTTP request and every `agora:<lib>:<event>` diagnostics publish as a queryable
5
+ entry.
6
+
7
+ ```sh
8
+ npm i @adonis-agora/telescope
9
+ node ace configure @adonis-agora/telescope
10
+ ```
11
+
12
+ ```ts
13
+ import { TelescopeService } from '@adonis-agora/telescope'
14
+
15
+ const telescope = await app.container.make(TelescopeService)
16
+ telescope.list({ type: 'request', limit: 50 })
17
+ telescope.byTrace('abc123')
18
+ telescope.topFamilies(10, 'diagnostic')
19
+ ```
20
+
21
+ See the [repo README](../../README.md) and [`DESIGN.md`](../../DESIGN.md) for the
22
+ full contract, the cross-repo decoupling design, and the deferred roadmap.
23
+
24
+ ## License
25
+
26
+ MIT © Davi Carvalho
@@ -0,0 +1,16 @@
1
+ import type Configure from '@adonisjs/core/commands/configure';
2
+ /**
3
+ * `node ace configure @adonis-agora/telescope` — auto-wires the package:
4
+ *
5
+ * 1. registers the core service provider in `adonisrc.ts`;
6
+ * 2. registers {@link TelescopeMiddleware} on the `server` middleware stack;
7
+ * 3. publishes `config/telescope.ts` and the `lucid` store migration (so switching
8
+ * `store: 'lucid'` only needs `node ace migration:run`; the `memory` default
9
+ * ignores it);
10
+ * 4. offers the optional features (watchers / ui / ai / alerts) — each is a subpath
11
+ * of this same package. The selected ones get their provider registered in
12
+ * `adonisrc.ts` (`@adonis-agora/telescope/<feature>_provider`) and their config stub
13
+ * published, folding in what used to be each sub-package's own `configure`.
14
+ */
15
+ export declare function configure(command: Configure): Promise<void>;
16
+ //# sourceMappingURL=configure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../configure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,mCAAmC,CAAC;AAoC/D;;;;;;;;;;;;GAYG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,SAAS,iBAwCjD"}
@@ -0,0 +1,75 @@
1
+ import { stubsRoot } from './stubs/main.js';
2
+ /**
3
+ * The opt-in features of `@adonis-agora/telescope`, each shipped as a subpath of this one
4
+ * package. `configure` always wires the core; these are offered on top.
5
+ */
6
+ const FEATURES = [
7
+ {
8
+ name: 'watchers',
9
+ message: 'Watchers — record Lucid queries, mail, cache, outbound HTTP and logs',
10
+ provider: '@adonis-agora/telescope/watchers_provider',
11
+ configStub: 'config/telescope_watchers.stub',
12
+ },
13
+ {
14
+ name: 'ui',
15
+ message: 'UI — web dashboard + JSON API at /telescope',
16
+ provider: '@adonis-agora/telescope/ui_provider',
17
+ configStub: 'config/telescope_ui.stub',
18
+ },
19
+ {
20
+ name: 'ai',
21
+ message: 'AI — Claude-powered exception diagnosis',
22
+ provider: '@adonis-agora/telescope/ai_provider',
23
+ configStub: 'config/telescope_ai.stub',
24
+ },
25
+ {
26
+ name: 'alerts',
27
+ message: 'Alerts — notify Slack / webhook on new exception families',
28
+ provider: '@adonis-agora/telescope/alerts_provider',
29
+ configStub: 'config/telescope_alerts.stub',
30
+ },
31
+ ];
32
+ /**
33
+ * `node ace configure @adonis-agora/telescope` — auto-wires the package:
34
+ *
35
+ * 1. registers the core service provider in `adonisrc.ts`;
36
+ * 2. registers {@link TelescopeMiddleware} on the `server` middleware stack;
37
+ * 3. publishes `config/telescope.ts` and the `lucid` store migration (so switching
38
+ * `store: 'lucid'` only needs `node ace migration:run`; the `memory` default
39
+ * ignores it);
40
+ * 4. offers the optional features (watchers / ui / ai / alerts) — each is a subpath
41
+ * of this same package. The selected ones get their provider registered in
42
+ * `adonisrc.ts` (`@adonis-agora/telescope/<feature>_provider`) and their config stub
43
+ * published, folding in what used to be each sub-package's own `configure`.
44
+ */
45
+ export async function configure(command) {
46
+ const codemods = await command.createCodemods();
47
+ // — core —
48
+ await codemods.updateRcFile((rcFile) => {
49
+ rcFile.addProvider('@adonis-agora/telescope/telescope_provider');
50
+ });
51
+ await codemods.registerMiddleware('server', [
52
+ { path: '@adonis-agora/telescope/telescope_middleware' },
53
+ ]);
54
+ await codemods.makeUsingStub(stubsRoot, 'config/telescope.stub', {});
55
+ await codemods.makeUsingStub(stubsRoot, 'database/migrations/create_telescope_entries_table.stub', {});
56
+ // — optional features (subpaths of this same package) —
57
+ let selected;
58
+ try {
59
+ selected = await command.prompt.multiple('Select the optional telescope features to enable', FEATURES.map((feature) => ({ name: feature.name, message: feature.message })));
60
+ }
61
+ catch {
62
+ // Non-interactive runs (CI / --no-interactive) get the core only; features can be
63
+ // enabled later by re-running configure or wiring the providers by hand.
64
+ selected = [];
65
+ }
66
+ for (const feature of FEATURES) {
67
+ if (!selected.includes(feature.name))
68
+ continue;
69
+ await codemods.updateRcFile((rcFile) => {
70
+ rcFile.addProvider(feature.provider);
71
+ });
72
+ await codemods.makeUsingStub(stubsRoot, feature.configStub, {});
73
+ }
74
+ }
75
+ //# sourceMappingURL=configure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configure.js","sourceRoot":"","sources":["../configure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;GAGG;AACH,MAAM,QAAQ,GAAG;IACf;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,sEAAsE;QAC/E,QAAQ,EAAE,2CAA2C;QACrD,UAAU,EAAE,gCAAgC;KAC7C;IACD;QACE,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,6CAA6C;QACtD,QAAQ,EAAE,qCAAqC;QAC/C,UAAU,EAAE,0BAA0B;KACvC;IACD;QACE,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,yCAAyC;QAClD,QAAQ,EAAE,qCAAqC;QAC/C,UAAU,EAAE,0BAA0B;KACvC;IACD;QACE,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,2DAA2D;QACpE,QAAQ,EAAE,yCAAyC;QACnD,UAAU,EAAE,8BAA8B;KAC3C;CACO,CAAC;AAIX;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAkB;IAChD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC;IAEhD,WAAW;IACX,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,WAAW,CAAC,4CAA4C,CAAC,CAAC;IACnE,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,kBAAkB,CAAC,QAAQ,EAAE;QAC1C,EAAE,IAAI,EAAE,8CAA8C,EAAE;KACzD,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,uBAAuB,EAAE,EAAE,CAAC,CAAC;IACrE,MAAM,QAAQ,CAAC,aAAa,CAC1B,SAAS,EACT,yDAAyD,EACzD,EAAE,CACH,CAAC;IAEF,wDAAwD;IACxD,IAAI,QAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,QAAQ,CACtC,kDAAkD,EAClD,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAC9E,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,kFAAkF;QAClF,yEAAyE;QACzE,QAAQ,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;YAAE,SAAS;QAE/C,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,EAAE;YACrC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { ApplicationService } from '@adonisjs/core/types';
2
+ /**
3
+ * Wires `@adonis-agora/telescope/ai` into the AdonisJS application.
4
+ *
5
+ * - `register()` reads `config/telescope_ai.ts` (falling back to an `ai_config`
6
+ * key on `config/telescope.ts`), constructs a {@link TelescopeAiDiagnoser}
7
+ * backed by the Anthropic Claude API, and binds it into the container so
8
+ * controllers / the dashboard can `inject()` it. When AI is disabled or no API
9
+ * key resolved, a disabled diagnoser is bound (its `diagnose` is a no-op
10
+ * returning `null`), so consumers can inject unconditionally.
11
+ *
12
+ * Diagnosis never throws into the app: a model or parse failure resolves to `null`.
13
+ */
14
+ export default class TelescopeAiProvider {
15
+ protected app: ApplicationService;
16
+ constructor(app: ApplicationService);
17
+ private resolve;
18
+ register(): void;
19
+ }
20
+ //# sourceMappingURL=telescope_ai_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telescope_ai_provider.d.ts","sourceRoot":"","sources":["../../providers/telescope_ai_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAK/D;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAmB;IAC1B,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,OAAO,CAAC,OAAO;IAWf,QAAQ;CAeT"}
@@ -0,0 +1,45 @@
1
+ import { resolveConfig } from '../src/ai/define_config.js';
2
+ import { createDiagnoser } from '../src/ai/factory.js';
3
+ import { TelescopeAiDiagnoser } from '../src/ai/telescope_ai_diagnoser.js';
4
+ /**
5
+ * Wires `@adonis-agora/telescope/ai` into the AdonisJS application.
6
+ *
7
+ * - `register()` reads `config/telescope_ai.ts` (falling back to an `ai_config`
8
+ * key on `config/telescope.ts`), constructs a {@link TelescopeAiDiagnoser}
9
+ * backed by the Anthropic Claude API, and binds it into the container so
10
+ * controllers / the dashboard can `inject()` it. When AI is disabled or no API
11
+ * key resolved, a disabled diagnoser is bound (its `diagnose` is a no-op
12
+ * returning `null`), so consumers can inject unconditionally.
13
+ *
14
+ * Diagnosis never throws into the app: a model or parse failure resolves to `null`.
15
+ */
16
+ export default class TelescopeAiProvider {
17
+ app;
18
+ constructor(app) {
19
+ this.app = app;
20
+ }
21
+ resolve() {
22
+ const own = this.app.config.get('telescope_ai', undefined);
23
+ if (own !== undefined)
24
+ return resolveConfig(own);
25
+ const fromTelescope = this.app.config.get('telescope.ai_config', undefined);
26
+ return resolveConfig(fromTelescope);
27
+ }
28
+ register() {
29
+ const config = this.resolve();
30
+ this.app.container.singleton(TelescopeAiDiagnoser, () => {
31
+ const diagnoser = createDiagnoser(config);
32
+ if (diagnoser !== null)
33
+ return diagnoser;
34
+ // No key / disabled: bind a diagnoser whose `diagnose` is a no-op so
35
+ // consumers can `inject(TelescopeAiDiagnoser)` without a null check.
36
+ return new TelescopeAiDiagnoser({
37
+ client: { messages: { create: () => Promise.reject(new Error('disabled')) } },
38
+ model: config.model,
39
+ maxTokens: config.maxTokens,
40
+ enabled: false,
41
+ });
42
+ });
43
+ }
44
+ }
45
+ //# sourceMappingURL=telescope_ai_provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telescope_ai_provider.js","sourceRoot":"","sources":["../../providers/telescope_ai_provider.ts"],"names":[],"mappings":"AACA,OAAO,EAA0B,aAAa,EAAE,MAAM,4BAA4B,CAAC;AACnF,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAmB;IAChB;IAAtB,YAAsB,GAAuB;QAAvB,QAAG,GAAH,GAAG,CAAoB;IAAG,CAAC;IAEzC,OAAO;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAgC,cAAc,EAAE,SAAS,CAAC,CAAC;QAC1F,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;QAEjD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CACvC,qBAAqB,EACrB,SAAS,CACV,CAAC;QACF,OAAO,aAAa,CAAC,aAAa,CAAC,CAAC;IACtC,CAAC;IAED,QAAQ;QACN,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,oBAAoB,EAAE,GAAG,EAAE;YACtD,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;YAC1C,IAAI,SAAS,KAAK,IAAI;gBAAE,OAAO,SAAS,CAAC;YACzC,qEAAqE;YACrE,qEAAqE;YACrE,OAAO,IAAI,oBAAoB,CAAC;gBAC9B,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE;gBAC7E,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,OAAO,EAAE,KAAK;aACf,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,23 @@
1
+ import type { ApplicationService } from '@adonisjs/core/types';
2
+ /**
3
+ * Wires `@adonis-agora/telescope/alerts` into the AdonisJS application.
4
+ *
5
+ * - `boot()` reads `config/telescope_alerts.ts` (falling back to an
6
+ * `alerts_config` key on `config/telescope.ts`), resolves the live telescope
7
+ * store from the core's runtime slot (no DI — same handle the watchers record
8
+ * through), and starts an {@link ExceptionPoller} that feeds new exception
9
+ * entries to an {@link Alerter}.
10
+ * - `shutdown()` stops the poller.
11
+ *
12
+ * Alerting never throws into the app: a disabled config, a missing store, or a
13
+ * failing channel all degrade to doing nothing (failures are warn-logged).
14
+ */
15
+ export default class TelescopeAlertsProvider {
16
+ protected app: ApplicationService;
17
+ private poller;
18
+ constructor(app: ApplicationService);
19
+ private resolve;
20
+ boot(): Promise<void>;
21
+ shutdown(): Promise<void>;
22
+ }
23
+ //# sourceMappingURL=telescope_alerts_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telescope_alerts_provider.d.ts","sourceRoot":"","sources":["../../providers/telescope_alerts_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAO/D;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAG9B,SAAS,CAAC,GAAG,EAAE,kBAAkB;IAF7C,OAAO,CAAC,MAAM,CAAgC;gBAExB,GAAG,EAAE,kBAAkB;IAE7C,OAAO,CAAC,OAAO;IAcT,IAAI;IA6BJ,QAAQ;CAQf"}
@@ -0,0 +1,72 @@
1
+ import { Alerter } from '../src/alerts/alerter.js';
2
+ import { resolveConfig } from '../src/alerts/define_config.js';
3
+ import { ExceptionPoller } from '../src/alerts/exception_source.js';
4
+ import { getTelescopeRuntime } from '../src/registry.js';
5
+ /**
6
+ * Wires `@adonis-agora/telescope/alerts` into the AdonisJS application.
7
+ *
8
+ * - `boot()` reads `config/telescope_alerts.ts` (falling back to an
9
+ * `alerts_config` key on `config/telescope.ts`), resolves the live telescope
10
+ * store from the core's runtime slot (no DI — same handle the watchers record
11
+ * through), and starts an {@link ExceptionPoller} that feeds new exception
12
+ * entries to an {@link Alerter}.
13
+ * - `shutdown()` stops the poller.
14
+ *
15
+ * Alerting never throws into the app: a disabled config, a missing store, or a
16
+ * failing channel all degrade to doing nothing (failures are warn-logged).
17
+ */
18
+ export default class TelescopeAlertsProvider {
19
+ app;
20
+ poller = null;
21
+ constructor(app) {
22
+ this.app = app;
23
+ }
24
+ resolve() {
25
+ const own = this.app.config.get('telescope_alerts', undefined);
26
+ if (own !== undefined)
27
+ return resolveConfig(own);
28
+ const fromTelescope = this.app.config.get('telescope.alerts_config', undefined);
29
+ return resolveConfig(fromTelescope);
30
+ }
31
+ async boot() {
32
+ const config = this.resolve();
33
+ if (!config.enabled)
34
+ return;
35
+ let store;
36
+ try {
37
+ store = getTelescopeRuntime().store;
38
+ }
39
+ catch (err) {
40
+ console.error(`TelescopeAlertsProvider: could not resolve the telescope store: ${asMessage(err)}`);
41
+ return;
42
+ }
43
+ if (store === null)
44
+ return;
45
+ const alerter = new Alerter({ alerts: config });
46
+ this.poller = new ExceptionPoller({
47
+ store,
48
+ alerter,
49
+ intervalMs: config.intervalMs,
50
+ });
51
+ try {
52
+ this.poller.start();
53
+ }
54
+ catch (err) {
55
+ console.error(`TelescopeAlertsProvider: failed to start the alert poller: ${asMessage(err)}`);
56
+ this.poller = null;
57
+ }
58
+ }
59
+ async shutdown() {
60
+ try {
61
+ this.poller?.stop();
62
+ }
63
+ catch {
64
+ // never throw out of shutdown
65
+ }
66
+ this.poller = null;
67
+ }
68
+ }
69
+ function asMessage(err) {
70
+ return err instanceof Error ? err.message : String(err);
71
+ }
72
+ //# sourceMappingURL=telescope_alerts_provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telescope_alerts_provider.js","sourceRoot":"","sources":["../../providers/telescope_alerts_provider.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAA8B,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAGpB;IAFd,MAAM,GAA2B,IAAI,CAAC;IAE9C,YAAsB,GAAuB;QAAvB,QAAG,GAAH,GAAG,CAAoB;IAAG,CAAC;IAEzC,OAAO;QACb,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAC7B,kBAAkB,EAClB,SAAS,CACV,CAAC;QACF,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;QAEjD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CACvC,yBAAyB,EACzB,SAAS,CACV,CAAC;QACF,OAAO,aAAa,CAAC,aAAa,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,OAAO;YAAE,OAAO;QAE5B,IAAI,KAA4B,CAAC;QACjC,IAAI,CAAC;YACH,KAAK,GAAG,mBAAmB,EAAE,CAAC,KAAK,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CACX,mEAAmE,SAAS,CAAC,GAAG,CAAC,EAAE,CACpF,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO;QAE3B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAChD,IAAI,CAAC,MAAM,GAAG,IAAI,eAAe,CAAC;YAChC,KAAK;YACL,OAAO;YACP,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC;QACH,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QACtB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,8DAA8D,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC9F,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,IAAI,CAAC;YACH,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;QAChC,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;CACF;AAED,SAAS,SAAS,CAAC,GAAY;IAC7B,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,43 @@
1
+ import type { ApplicationService } from '@adonisjs/core/types';
2
+ /**
3
+ * Wires `@adonis-agora/telescope` into the AdonisJS application.
4
+ *
5
+ * - `register()` binds {@link TelescopeService} into the container, resolving against
6
+ * whichever store the provider builds at boot, so controllers can `inject()` it.
7
+ * - `boot()` reads `config/telescope.ts`, builds the configured store (a key of
8
+ * `config.stores`, the `'memory'` shorthand, or a supplied instance), publishes it on
9
+ * the global runtime slot (so the request middleware can reach it without DI), and
10
+ * starts the {@link DiagnosticsWatcher} when the `diagnostics` watcher is enabled.
11
+ * Building the store is async because a driver lazily imports its peer dependency
12
+ * (`@adonisjs/lucid` for `lucid`) only when it is the selected one.
13
+ * - `shutdown()` stops the watcher and clears the runtime slot.
14
+ *
15
+ * The request watcher itself runs as `server` middleware, which
16
+ * `node ace configure @adonis-agora/telescope` registers on the `server` stack.
17
+ */
18
+ export default class TelescopeProvider {
19
+ protected app: ApplicationService;
20
+ private store;
21
+ private diagnosticsWatcher;
22
+ constructor(app: ApplicationService);
23
+ register(): void;
24
+ boot(): Promise<void>;
25
+ /**
26
+ * Build the active store from config. A supplied {@link TelescopeStore} instance is used
27
+ * as-is; otherwise `config.store` names a driver in `config.stores`, built via its lazy
28
+ * thunk. The bare `'memory'` shorthand (no matching driver) falls back to the built-in
29
+ * ring buffer so `node ace configure`'s zero-config default just works.
30
+ */
31
+ private buildStore;
32
+ /**
33
+ * Wrap the built store with the CENTRAL redaction decorator so every entry's
34
+ * content is scrubbed before persistence — the single choke point every watcher
35
+ * records through (see {@link RedactingTelescopeStore}). Skipped only when
36
+ * `config.redact.enabled` is `false`.
37
+ */
38
+ private applyRedaction;
39
+ /** Construct the extension registry, giving each extension a context over the store + container. */
40
+ private buildExtensionRegistry;
41
+ shutdown(): Promise<void>;
42
+ }
43
+ //# sourceMappingURL=telescope_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telescope_provider.d.ts","sourceRoot":"","sources":["../../providers/telescope_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAmB/D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,OAAO,OAAO,iBAAiB;IAIxB,SAAS,CAAC,GAAG,EAAE,kBAAkB;IAH7C,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,kBAAkB,CAAmC;gBAEvC,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;IAUF,IAAI;IAuBV;;;;;OAKG;YACW,UAAU;IAexB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAKtB,oGAAoG;IACpG,OAAO,CAAC,sBAAsB;IAaxB,QAAQ;CAKf"}
@@ -0,0 +1,103 @@
1
+ import { resolveConfig, } from '../src/define_config.js';
2
+ import { DiagnosticsWatcher } from '../src/diagnostics_watcher.js';
3
+ import { ExtensionRegistry } from '../src/extension/registry.js';
4
+ import { RedactingTelescopeStore } from '../src/redaction/redacting_store.js';
5
+ import { resetTelescopeRuntime, setTelescopeExtensionRegistry, setTelescopeRuntime, } from '../src/registry.js';
6
+ import { TelescopeService } from '../src/service.js';
7
+ import { InMemoryTelescopeStore } from '../src/stores/memory.js';
8
+ /**
9
+ * Wires `@adonis-agora/telescope` into the AdonisJS application.
10
+ *
11
+ * - `register()` binds {@link TelescopeService} into the container, resolving against
12
+ * whichever store the provider builds at boot, so controllers can `inject()` it.
13
+ * - `boot()` reads `config/telescope.ts`, builds the configured store (a key of
14
+ * `config.stores`, the `'memory'` shorthand, or a supplied instance), publishes it on
15
+ * the global runtime slot (so the request middleware can reach it without DI), and
16
+ * starts the {@link DiagnosticsWatcher} when the `diagnostics` watcher is enabled.
17
+ * Building the store is async because a driver lazily imports its peer dependency
18
+ * (`@adonisjs/lucid` for `lucid`) only when it is the selected one.
19
+ * - `shutdown()` stops the watcher and clears the runtime slot.
20
+ *
21
+ * The request watcher itself runs as `server` middleware, which
22
+ * `node ace configure @adonis-agora/telescope` registers on the `server` stack.
23
+ */
24
+ export default class TelescopeProvider {
25
+ app;
26
+ store = null;
27
+ diagnosticsWatcher = null;
28
+ constructor(app) {
29
+ this.app = app;
30
+ }
31
+ register() {
32
+ // The store is built asynchronously at boot (a driver may lazily import its peer
33
+ // dep). Bind the service to resolve against the active store; `boot()` runs before
34
+ // any request, so the store is always set by the time a controller resolves it.
35
+ this.app.container.singleton(TelescopeService, () => {
36
+ const store = this.store ?? new InMemoryTelescopeStore();
37
+ return new TelescopeService(store);
38
+ });
39
+ }
40
+ async boot() {
41
+ const config = resolveConfig(this.app.config.get('telescope', {}));
42
+ const store = this.applyRedaction(await this.buildStore(config), config);
43
+ this.store = store;
44
+ if (!config.enabled) {
45
+ resetTelescopeRuntime();
46
+ return;
47
+ }
48
+ setTelescopeRuntime(store, config.watchers.has('request'));
49
+ if (config.watchers.has('diagnostics')) {
50
+ const watcher = new DiagnosticsWatcher(store);
51
+ watcher.start();
52
+ this.diagnosticsWatcher = watcher;
53
+ }
54
+ // Build the extension registry from `config.extensions` and publish it so the UI can serve each
55
+ // extension's dashboards + data providers. A collision (duplicate id/name) throws here, at boot.
56
+ setTelescopeExtensionRegistry(this.buildExtensionRegistry(config, store));
57
+ }
58
+ /**
59
+ * Build the active store from config. A supplied {@link TelescopeStore} instance is used
60
+ * as-is; otherwise `config.store` names a driver in `config.stores`, built via its lazy
61
+ * thunk. The bare `'memory'` shorthand (no matching driver) falls back to the built-in
62
+ * ring buffer so `node ace configure`'s zero-config default just works.
63
+ */
64
+ async buildStore(config) {
65
+ if (typeof config.store !== 'string')
66
+ return config.store;
67
+ const provider = config.stores[config.store];
68
+ if (provider)
69
+ return provider({ app: this.app });
70
+ if (config.store === 'memory') {
71
+ return new InMemoryTelescopeStore({ maxEntries: config.maxEntries });
72
+ }
73
+ throw new Error(`@adonis-agora/telescope: config.store is "${config.store}", but config.stores.${config.store} is not defined`);
74
+ }
75
+ /**
76
+ * Wrap the built store with the CENTRAL redaction decorator so every entry's
77
+ * content is scrubbed before persistence — the single choke point every watcher
78
+ * records through (see {@link RedactingTelescopeStore}). Skipped only when
79
+ * `config.redact.enabled` is `false`.
80
+ */
81
+ applyRedaction(store, config) {
82
+ if (!config.redact.enabled)
83
+ return store;
84
+ return new RedactingTelescopeStore(store, { keys: config.redact.keys });
85
+ }
86
+ /** Construct the extension registry, giving each extension a context over the store + container. */
87
+ buildExtensionRegistry(config, store) {
88
+ if (config.extensions.length === 0)
89
+ return null;
90
+ const ctx = {
91
+ store,
92
+ container: { make: (token) => this.app.container.make(token) },
93
+ config,
94
+ };
95
+ return new ExtensionRegistry(config.extensions, ctx);
96
+ }
97
+ async shutdown() {
98
+ this.diagnosticsWatcher?.stop();
99
+ this.diagnosticsWatcher = null;
100
+ resetTelescopeRuntime();
101
+ }
102
+ }
103
+ //# sourceMappingURL=telescope_provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telescope_provider.js","sourceRoot":"","sources":["../../providers/telescope_provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ApplicationService } from '@adonisjs/core/types';
2
+ /**
3
+ * Wires `@adonis-agora/telescope/ui` into the AdonisJS application.
4
+ *
5
+ * - `boot()` reads `config/telescope_ui.ts`, resolves the live telescope store
6
+ * from the core runtime slot (no DI — same handle the watchers record through),
7
+ * and registers routes under the configured prefix via the AdonisJS router:
8
+ * the dashboard page at the prefix root and the JSON API under `<path>/api/*`.
9
+ * Every route runs the configured `authorize` guard first.
10
+ *
11
+ * Failures degrade safely: a disabled config or a missing store registers no
12
+ * routes (warn-logged), so the dashboard simply does not exist rather than
13
+ * crashing the host.
14
+ */
15
+ export default class TelescopeUiProvider {
16
+ protected app: ApplicationService;
17
+ constructor(app: ApplicationService);
18
+ private resolve;
19
+ boot(): Promise<void>;
20
+ }
21
+ //# sourceMappingURL=telescope_ui_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telescope_ui_provider.d.ts","sourceRoot":"","sources":["../../providers/telescope_ui_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAiB/D;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAmB;IAC1B,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,OAAO,CAAC,OAAO;IAMT,IAAI;CA2FX"}
@@ -0,0 +1,119 @@
1
+ import { resolveConfig as resolveTelescopeConfig } from '../src/define_config.js';
2
+ import { getTelescopeRuntime } from '../src/registry.js';
3
+ import { TelescopeService } from '../src/service.js';
4
+ import { TelescopeApi } from '../src/ui/api.js';
5
+ import { renderDashboard } from '../src/ui/dashboard.js';
6
+ import { resolveConfig, } from '../src/ui/define_config.js';
7
+ import { ExtensionApi } from '../src/ui/extension_api.js';
8
+ import { enforceGuard } from '../src/ui/guard.js';
9
+ /**
10
+ * Wires `@adonis-agora/telescope/ui` into the AdonisJS application.
11
+ *
12
+ * - `boot()` reads `config/telescope_ui.ts`, resolves the live telescope store
13
+ * from the core runtime slot (no DI — same handle the watchers record through),
14
+ * and registers routes under the configured prefix via the AdonisJS router:
15
+ * the dashboard page at the prefix root and the JSON API under `<path>/api/*`.
16
+ * Every route runs the configured `authorize` guard first.
17
+ *
18
+ * Failures degrade safely: a disabled config or a missing store registers no
19
+ * routes (warn-logged), so the dashboard simply does not exist rather than
20
+ * crashing the host.
21
+ */
22
+ export default class TelescopeUiProvider {
23
+ app;
24
+ constructor(app) {
25
+ this.app = app;
26
+ }
27
+ resolve() {
28
+ return resolveConfig(this.app.config.get('telescope_ui', undefined));
29
+ }
30
+ async boot() {
31
+ const config = this.resolve();
32
+ if (!config.enabled)
33
+ return;
34
+ let store;
35
+ try {
36
+ store = getTelescopeRuntime().store;
37
+ }
38
+ catch (err) {
39
+ console.error(`TelescopeUiProvider: could not resolve the telescope store: ${asMessage(err)}`);
40
+ return;
41
+ }
42
+ if (store === null) {
43
+ console.warn('TelescopeUiProvider: telescope store is not booted (is @adonis-agora/telescope enabled?); ' +
44
+ 'dashboard routes not registered.');
45
+ return;
46
+ }
47
+ const service = new TelescopeService(store);
48
+ const api = new TelescopeApi(service);
49
+ const apiBase = `${config.path}/api`;
50
+ const router = await this.app.container.make('router');
51
+ const guard = config.authorize;
52
+ // Dashboard page (HTML).
53
+ router
54
+ .get(config.path, async (ctx) => {
55
+ if (!(await enforceGuard(ctx, guard)))
56
+ return;
57
+ ctx.response.header('content-type', 'text/html; charset=utf-8');
58
+ return ctx.response.send(renderDashboard(apiBase));
59
+ })
60
+ .as('telescope_ui.dashboard');
61
+ // JSON API.
62
+ router
63
+ .get(`${apiBase}/entries`, async (ctx) => {
64
+ if (!(await enforceGuard(ctx, guard)))
65
+ return;
66
+ return api.list(ctx);
67
+ })
68
+ .as('telescope_ui.entries');
69
+ router
70
+ .get(`${apiBase}/entries/:id`, async (ctx) => {
71
+ if (!(await enforceGuard(ctx, guard)))
72
+ return;
73
+ return api.show(ctx, String(ctx.params.id));
74
+ })
75
+ .as('telescope_ui.entry');
76
+ router
77
+ .get(`${apiBase}/trace/:traceId`, async (ctx) => {
78
+ if (!(await enforceGuard(ctx, guard)))
79
+ return;
80
+ return api.trace(ctx, String(ctx.params.traceId));
81
+ })
82
+ .as('telescope_ui.trace');
83
+ router
84
+ .get(`${apiBase}/stats`, async (ctx) => {
85
+ if (!(await enforceGuard(ctx, guard)))
86
+ return;
87
+ return api.stats(ctx);
88
+ })
89
+ .as('telescope_ui.stats');
90
+ // Extension SDK surface (only when at least one extension contributed a registry at boot).
91
+ const registry = getTelescopeRuntime().registry;
92
+ if (registry) {
93
+ const extCtx = {
94
+ store,
95
+ container: { make: (token) => this.app.container.make(token) },
96
+ config: resolveTelescopeConfig(this.app.config.get('telescope', {})),
97
+ };
98
+ const extApi = new ExtensionApi(registry, extCtx);
99
+ router
100
+ .get(`${apiBase}/meta`, async (ctx) => {
101
+ if (!(await enforceGuard(ctx, guard)))
102
+ return;
103
+ return extApi.meta(ctx);
104
+ })
105
+ .as('telescope_ui.meta');
106
+ router
107
+ .get(`${apiBase}/ext/:ext/data/:provider`, async (ctx) => {
108
+ if (!(await enforceGuard(ctx, guard)))
109
+ return;
110
+ return extApi.data(ctx, String(ctx.params.ext), String(ctx.params.provider));
111
+ })
112
+ .as('telescope_ui.ext_data');
113
+ }
114
+ }
115
+ }
116
+ function asMessage(err) {
117
+ return err instanceof Error ? err.message : String(err);
118
+ }
119
+ //# sourceMappingURL=telescope_ui_provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telescope_ui_provider.js","sourceRoot":"","sources":["../../providers/telescope_ui_provider.ts"],"names":[],"mappings":"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"}