@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
@@ -0,0 +1,257 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { currentTraceId } from '../context_accessor.js';
3
+ import { isBatchOrigin } from '../entry.js';
4
+ /**
5
+ * The table {@link LucidTelescopeStore} reads and writes. Override via
6
+ * {@link LucidStoreOptions.tableName} when `telescope_entries` collides with an
7
+ * existing table.
8
+ */
9
+ export const DEFAULT_TABLE_NAME = 'telescope_entries';
10
+ /**
11
+ * `CREATE TABLE IF NOT EXISTS` DDL for the telescope entries table, plus the
12
+ * indexes `list` / `prune` / `topFamilies` lean on, as one statement per array
13
+ * element so each can be issued through Lucid's `rawQuery`.
14
+ *
15
+ * Portable across sqlite / Postgres / MySQL (quoted identifiers, no dialect-only
16
+ * column types). A real deployment should still prefer the bundled migration stub
17
+ * so the schema is versioned, but this lets a store stand itself up in tests and
18
+ * scripts without a migration runner.
19
+ */
20
+ export function createTableStatements(tableName = DEFAULT_TABLE_NAME) {
21
+ return [
22
+ `CREATE TABLE IF NOT EXISTS "${tableName}" (
23
+ "id" VARCHAR(255) PRIMARY KEY NOT NULL,
24
+ "type" VARCHAR(255) NOT NULL,
25
+ "family_hash" VARCHAR(255) NULL,
26
+ "content" TEXT NOT NULL,
27
+ "tags" TEXT NOT NULL,
28
+ "sequence" INTEGER NOT NULL,
29
+ "duration_ms" INTEGER NULL,
30
+ "origin" VARCHAR(255) NOT NULL,
31
+ "trace_id" VARCHAR(255) NULL,
32
+ "created_at" BIGINT NOT NULL
33
+ )`,
34
+ `CREATE INDEX IF NOT EXISTS "${tableName}_created_at_idx" ON "${tableName}" ("created_at")`,
35
+ `CREATE INDEX IF NOT EXISTS "${tableName}_type_idx" ON "${tableName}" ("type")`,
36
+ `CREATE INDEX IF NOT EXISTS "${tableName}_trace_id_idx" ON "${tableName}" ("trace_id")`,
37
+ `CREATE INDEX IF NOT EXISTS "${tableName}_family_hash_idx" ON "${tableName}" ("family_hash")`,
38
+ ];
39
+ }
40
+ /**
41
+ * A persistent, SQL-backed {@link TelescopeStore} on AdonisJS Lucid. Uses Lucid's
42
+ * **async** query builder directly, so it works on every dialect Lucid supports
43
+ * (sqlite / Postgres / MySQL) — no synchronous driver handle, no dialect lock-in.
44
+ *
45
+ * `content` and `tags` are stored as JSON text and round-tripped on read;
46
+ * `created_at` is epoch-ms so ordering and age-pruning are integer comparisons.
47
+ * `sequence` is seeded from `MAX(sequence)` on first use so it keeps climbing
48
+ * across process restarts.
49
+ *
50
+ * Usually you don't construct this directly: `config/telescope.ts` selects it via
51
+ * `storage.lucid({ ... })` and the provider builds it for you, lazily importing
52
+ * `@adonisjs/lucid` only when the `lucid` driver is the active one.
53
+ */
54
+ export class LucidTelescopeStore {
55
+ db;
56
+ tableName;
57
+ maxEntries;
58
+ autoCreateTable;
59
+ /** Lazily-resolved init (table creation + sequence seed), run at most once. */
60
+ ready = null;
61
+ sequence = 0;
62
+ constructor(db, options = {}) {
63
+ this.db = db;
64
+ this.tableName = options.tableName ?? DEFAULT_TABLE_NAME;
65
+ this.maxEntries =
66
+ options.maxEntries !== undefined && options.maxEntries > 0 ? options.maxEntries : null;
67
+ this.autoCreateTable = options.autoCreateTable ?? false;
68
+ }
69
+ async record(input) {
70
+ await this.init();
71
+ const traceId = input.traceId !== undefined ? input.traceId : currentTraceId();
72
+ const origin = isBatchOrigin(input.origin) ? input.origin : 'manual';
73
+ const entry = {
74
+ id: randomUUID(),
75
+ type: input.type,
76
+ familyHash: input.familyHash ?? null,
77
+ content: input.content,
78
+ tags: input.tags ?? [],
79
+ sequence: this.sequence++,
80
+ durationMs: input.durationMs ?? null,
81
+ origin,
82
+ traceId,
83
+ createdAt: new Date(),
84
+ };
85
+ const row = {
86
+ id: entry.id,
87
+ type: entry.type,
88
+ family_hash: entry.familyHash,
89
+ content: safeJson(entry.content),
90
+ tags: JSON.stringify(entry.tags),
91
+ sequence: entry.sequence,
92
+ duration_ms: entry.durationMs,
93
+ origin: entry.origin,
94
+ trace_id: entry.traceId,
95
+ created_at: entry.createdAt.getTime(),
96
+ };
97
+ await this.db.table(this.tableName).insert(row);
98
+ return entry;
99
+ }
100
+ async get(id) {
101
+ await this.init();
102
+ const row = await this.db.from(this.tableName).where('id', id).first();
103
+ return row ? hydrate(row) : null;
104
+ }
105
+ async list(query = {}) {
106
+ await this.init();
107
+ let builder = this.db.from(this.tableName);
108
+ if (query.type !== undefined)
109
+ builder = builder.where('type', query.type);
110
+ if (query.familyHash !== undefined)
111
+ builder = builder.where('family_hash', query.familyHash);
112
+ if (query.traceId !== undefined)
113
+ builder = builder.where('trace_id', query.traceId);
114
+ if (query.before !== undefined)
115
+ builder = builder.where('created_at', '<', query.before.getTime());
116
+ if (query.after !== undefined)
117
+ builder = builder.where('created_at', '>', query.after.getTime());
118
+ if (query.tag !== undefined) {
119
+ // A tag is one element of the JSON array text, e.g. `["lib:billing",...]`.
120
+ // Match the quoted token so `lib:bill` never matches `lib:billing`.
121
+ builder = builder.whereRaw(`"tags" LIKE ? ESCAPE '\\'`, [
122
+ `%${likeEscape(JSON.stringify(query.tag))}%`,
123
+ ]);
124
+ }
125
+ if (query.search !== undefined) {
126
+ const needle = `%${likeEscape(query.search.toLowerCase())}%`;
127
+ builder = builder.whereRaw(`(LOWER("content") LIKE ? ESCAPE '\\' OR LOWER("tags") LIKE ? ESCAPE '\\')`, [needle, needle]);
128
+ }
129
+ // Newest-first: created_at desc, sequence desc as a deterministic tiebreaker.
130
+ builder = builder.orderBy('created_at', 'desc').orderBy('sequence', 'desc');
131
+ if (query.limit !== undefined)
132
+ builder = builder.limit(query.limit);
133
+ const rows = await builder.select('*');
134
+ return rows.map((r) => hydrate(r));
135
+ }
136
+ async count() {
137
+ await this.init();
138
+ const rows = await this.db.from(this.tableName).count('*', 'total');
139
+ return toInt(rows[0]?.total);
140
+ }
141
+ async prune(olderThan, keepLast) {
142
+ await this.init();
143
+ const cutoff = olderThan.getTime();
144
+ if (keepLast === undefined) {
145
+ return this.db.from(this.tableName).where('created_at', '<', cutoff).delete();
146
+ }
147
+ // Keep the newest `keepLast` of the doomed (older-than-cutoff) entries: find
148
+ // their ids ordered newest-first, skip the first `keepLast`, delete the rest.
149
+ const doomed = await this.db
150
+ .from(this.tableName)
151
+ .where('created_at', '<', cutoff)
152
+ .orderBy('created_at', 'desc')
153
+ .orderBy('sequence', 'desc')
154
+ .select('id');
155
+ const toDelete = doomed.slice(keepLast).map((r) => String(r.id));
156
+ if (toDelete.length === 0)
157
+ return 0;
158
+ return this.db
159
+ .from(this.tableName)
160
+ .whereRaw(`"id" IN (${toDelete.map(() => '?').join(', ')})`, toDelete)
161
+ .delete();
162
+ }
163
+ async clear() {
164
+ await this.init();
165
+ await this.db.from(this.tableName).whereRaw('1 = 1').delete();
166
+ }
167
+ /** Cap enforcement helper for callers running a scheduled trim. */
168
+ get capacity() {
169
+ return this.maxEntries;
170
+ }
171
+ /** Run table creation (optional) + sequence seeding exactly once. */
172
+ init() {
173
+ if (!this.ready)
174
+ this.ready = this.doInit();
175
+ return this.ready;
176
+ }
177
+ async doInit() {
178
+ if (this.autoCreateTable) {
179
+ for (const stmt of createTableStatements(this.tableName)) {
180
+ await this.db.rawQuery(stmt);
181
+ }
182
+ }
183
+ // Seed the in-process counter from the persisted maximum so sequence keeps
184
+ // climbing monotonically across restarts.
185
+ const maxRow = await this.db
186
+ .from(this.tableName)
187
+ .orderBy('sequence', 'desc')
188
+ .limit(1)
189
+ .select('sequence');
190
+ const max = maxRow.length > 0 ? toInt(maxRow[0]?.sequence) : -1;
191
+ this.sequence = max + 1;
192
+ }
193
+ }
194
+ /**
195
+ * Stand up the telescope entries table (and its indexes) through Lucid's async
196
+ * query runner, idempotently (`CREATE TABLE IF NOT EXISTS`). Works on every Lucid
197
+ * dialect. Handy for tests, scripts and quick-starts where running a full
198
+ * migration is overkill.
199
+ *
200
+ * Production apps should prefer the bundled migration stub so the schema is
201
+ * versioned and runs through `node ace migration:run`.
202
+ */
203
+ export async function createTelescopeTable(db, options = {}) {
204
+ const tableName = options.tableName ?? DEFAULT_TABLE_NAME;
205
+ for (const stmt of createTableStatements(tableName)) {
206
+ await db.rawQuery(stmt);
207
+ }
208
+ }
209
+ /** Parse JSON text columns back into an {@link Entry}. */
210
+ function hydrate(row) {
211
+ return {
212
+ id: row.id,
213
+ type: row.type,
214
+ familyHash: row.family_hash ?? null,
215
+ content: parseJson(row.content),
216
+ tags: parseTags(row.tags),
217
+ sequence: toInt(row.sequence),
218
+ durationMs: row.duration_ms === null || row.duration_ms === undefined ? null : toInt(row.duration_ms),
219
+ origin: isBatchOrigin(row.origin) ? row.origin : 'manual',
220
+ traceId: row.trace_id ?? null,
221
+ createdAt: new Date(toInt(row.created_at)),
222
+ };
223
+ }
224
+ function safeJson(value) {
225
+ try {
226
+ return JSON.stringify(value) ?? 'null';
227
+ }
228
+ catch {
229
+ return 'null';
230
+ }
231
+ }
232
+ function parseJson(text) {
233
+ try {
234
+ return JSON.parse(text);
235
+ }
236
+ catch {
237
+ return null;
238
+ }
239
+ }
240
+ function parseTags(text) {
241
+ const parsed = parseJson(text);
242
+ return Array.isArray(parsed) ? parsed.filter((t) => typeof t === 'string') : [];
243
+ }
244
+ function toInt(value) {
245
+ if (typeof value === 'number')
246
+ return value;
247
+ if (typeof value === 'bigint')
248
+ return Number(value);
249
+ if (typeof value === 'string')
250
+ return Number.parseInt(value, 10) || 0;
251
+ return 0;
252
+ }
253
+ /** Escape LIKE wildcards so user input matches literally (escape char `\`). */
254
+ function likeEscape(value) {
255
+ return value.replace(/[\\%_]/g, (ch) => `\\${ch}`);
256
+ }
257
+ //# sourceMappingURL=lucid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lucid.js","sourceRoot":"","sources":["../../../src/stores/lucid.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { type Entry, type RecordInput } from '../entry.js';
2
+ import type { EntryQuery, TelescopeStore } from '../store.js';
3
+ /** Options for {@link InMemoryTelescopeStore}. */
4
+ export interface InMemoryStoreOptions {
5
+ /**
6
+ * Hard cap on retained entries. When exceeded, the oldest entries are evicted
7
+ * (ring-buffer semantics) so an unbounded process can never OOM. Default 1000.
8
+ */
9
+ maxEntries?: number;
10
+ }
11
+ /**
12
+ * The default, dependency-free {@link TelescopeStore}: a bounded in-process ring
13
+ * buffer. Ideal for development and tests; production deployments that need
14
+ * cross-process or durable storage swap in the `lucid` driver (or any store
15
+ * implementing the same contract).
16
+ */
17
+ export declare class InMemoryTelescopeStore implements TelescopeStore {
18
+ private readonly maxEntries;
19
+ private readonly entries;
20
+ private readonly byId;
21
+ private sequence;
22
+ constructor(options?: InMemoryStoreOptions);
23
+ record<TContent>(input: RecordInput<TContent>): Promise<Entry<TContent>>;
24
+ get(id: string): Promise<Entry | null>;
25
+ list(query?: EntryQuery): Promise<Entry[]>;
26
+ count(): Promise<number>;
27
+ prune(olderThan: Date, keepLast?: number): Promise<number>;
28
+ clear(): Promise<void>;
29
+ private evictOverflow;
30
+ }
31
+ //# sourceMappingURL=memory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../../src/stores/memory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,KAAK,EAAE,KAAK,WAAW,EAAiB,MAAM,aAAa,CAAC;AAC5F,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9D,kDAAkD;AAClD,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,qBAAa,sBAAuB,YAAW,cAAc;IAC3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAK;gBAET,OAAO,GAAE,oBAAyB;IAKxC,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAuBxE,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAItC,IAAI,CAAC,KAAK,GAAE,UAAe,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAkB9C,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAIxB,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,OAAO,CAAC,aAAa;CAMtB"}
@@ -0,0 +1,117 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { currentTraceId } from '../context_accessor.js';
3
+ import { isBatchOrigin } from '../entry.js';
4
+ /**
5
+ * The default, dependency-free {@link TelescopeStore}: a bounded in-process ring
6
+ * buffer. Ideal for development and tests; production deployments that need
7
+ * cross-process or durable storage swap in the `lucid` driver (or any store
8
+ * implementing the same contract).
9
+ */
10
+ export class InMemoryTelescopeStore {
11
+ maxEntries;
12
+ entries = [];
13
+ byId = new Map();
14
+ sequence = 0;
15
+ constructor(options = {}) {
16
+ const max = options.maxEntries ?? 1000;
17
+ this.maxEntries = max > 0 ? max : 1000;
18
+ }
19
+ async record(input) {
20
+ const traceId = input.traceId !== undefined ? input.traceId : currentTraceId();
21
+ const origin = isBatchOrigin(input.origin) ? input.origin : 'manual';
22
+ const entry = {
23
+ id: randomUUID(),
24
+ type: input.type,
25
+ familyHash: input.familyHash ?? null,
26
+ content: input.content,
27
+ tags: input.tags ?? [],
28
+ sequence: this.sequence++,
29
+ durationMs: input.durationMs ?? null,
30
+ origin,
31
+ traceId,
32
+ createdAt: new Date(),
33
+ };
34
+ // Newest-first ordering: unshift so index 0 is always the most recent.
35
+ this.entries.unshift(entry);
36
+ this.byId.set(entry.id, entry);
37
+ this.evictOverflow();
38
+ return entry;
39
+ }
40
+ async get(id) {
41
+ return this.byId.get(id) ?? null;
42
+ }
43
+ async list(query = {}) {
44
+ const search = query.search?.toLowerCase();
45
+ const results = [];
46
+ // `entries` is already newest-first.
47
+ for (const entry of this.entries) {
48
+ if (query.type !== undefined && entry.type !== query.type)
49
+ continue;
50
+ if (query.tag !== undefined && !entry.tags.includes(query.tag))
51
+ continue;
52
+ if (query.familyHash !== undefined && entry.familyHash !== query.familyHash)
53
+ continue;
54
+ if (query.traceId !== undefined && entry.traceId !== query.traceId)
55
+ continue;
56
+ if (query.before !== undefined && !(entry.createdAt < query.before))
57
+ continue;
58
+ if (query.after !== undefined && !(entry.createdAt > query.after))
59
+ continue;
60
+ if (search !== undefined && !matchesSearch(entry, search))
61
+ continue;
62
+ results.push(entry);
63
+ if (query.limit !== undefined && results.length >= query.limit)
64
+ break;
65
+ }
66
+ return results;
67
+ }
68
+ async count() {
69
+ return this.entries.length;
70
+ }
71
+ async prune(olderThan, keepLast) {
72
+ // Indices of the doomed entries (older than the cutoff), newest-first.
73
+ const doomed = [];
74
+ for (let i = 0; i < this.entries.length; i++) {
75
+ const entry = this.entries[i];
76
+ if (entry && entry.createdAt < olderThan)
77
+ doomed.push(i);
78
+ }
79
+ // Keep the newest N of the doomed set: since `entries` is newest-first, the
80
+ // first `keepLast` doomed indices are the newest doomed ones.
81
+ const toDelete = keepLast !== undefined ? doomed.slice(keepLast) : doomed;
82
+ if (toDelete.length === 0)
83
+ return 0;
84
+ // Delete from the back so earlier indices stay valid.
85
+ const ascending = [...toDelete].sort((a, b) => b - a);
86
+ for (const index of ascending) {
87
+ const [removed] = this.entries.splice(index, 1);
88
+ if (removed)
89
+ this.byId.delete(removed.id);
90
+ }
91
+ return toDelete.length;
92
+ }
93
+ async clear() {
94
+ this.entries.length = 0;
95
+ this.byId.clear();
96
+ }
97
+ evictOverflow() {
98
+ while (this.entries.length > this.maxEntries) {
99
+ const removed = this.entries.pop();
100
+ if (removed)
101
+ this.byId.delete(removed.id);
102
+ }
103
+ }
104
+ }
105
+ /** Substring match against the entry's JSON content and its tags. */
106
+ function matchesSearch(entry, needle) {
107
+ if (entry.tags.some((tag) => tag.toLowerCase().includes(needle)))
108
+ return true;
109
+ try {
110
+ return JSON.stringify(entry.content).toLowerCase().includes(needle);
111
+ }
112
+ catch {
113
+ // Content with a circular reference / BigInt — fall back to no match.
114
+ return false;
115
+ }
116
+ }
117
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../../src/stores/memory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { HttpContext } from '@adonisjs/core/http';
2
+ import type { NextFn } from '@adonisjs/core/types/http';
3
+ /**
4
+ * Records each inbound HTTP request as a `request` telescope entry (method, url,
5
+ * status, duration, traceId), and auto-captures any exception thrown by the
6
+ * downstream pipeline as an `exception` entry (message, name, stack, a stable
7
+ * family hash, traceId, method/url) BEFORE re-throwing — so HTTP exceptions are
8
+ * captured with zero app changes. Registered on the **server** middleware stack
9
+ * so it wraps the whole pipeline and observes the final response status.
10
+ *
11
+ * Reads the active store from the global runtime slot rather than via DI, so the
12
+ * middleware needs no constructor wiring and is a no-op (zero overhead) when
13
+ * telescope is disabled or not booted. Both recordings are wrapped so they can
14
+ * never break a request and never swallow the original error.
15
+ */
16
+ export default class TelescopeMiddleware {
17
+ handle(ctx: HttpContext, next: NextFn): Promise<any>;
18
+ }
19
+ //# sourceMappingURL=telescope_middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telescope_middleware.d.ts","sourceRoot":"","sources":["../../src/telescope_middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAKxD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAmB;IAChC,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM;CAkC5C"}
@@ -0,0 +1,56 @@
1
+ import { recordExceptionInStore } from './exception_watcher.js';
2
+ import { getTelescopeRuntime } from './registry.js';
3
+ import { recordRequest } from './request_watcher.js';
4
+ /**
5
+ * Records each inbound HTTP request as a `request` telescope entry (method, url,
6
+ * status, duration, traceId), and auto-captures any exception thrown by the
7
+ * downstream pipeline as an `exception` entry (message, name, stack, a stable
8
+ * family hash, traceId, method/url) BEFORE re-throwing — so HTTP exceptions are
9
+ * captured with zero app changes. Registered on the **server** middleware stack
10
+ * so it wraps the whole pipeline and observes the final response status.
11
+ *
12
+ * Reads the active store from the global runtime slot rather than via DI, so the
13
+ * middleware needs no constructor wiring and is a no-op (zero overhead) when
14
+ * telescope is disabled or not booted. Both recordings are wrapped so they can
15
+ * never break a request and never swallow the original error.
16
+ */
17
+ export default class TelescopeMiddleware {
18
+ async handle(ctx, next) {
19
+ const runtime = getTelescopeRuntime();
20
+ if (!runtime.store || !runtime.requestWatcherEnabled) {
21
+ return next();
22
+ }
23
+ const startedAt = Date.now();
24
+ const store = runtime.store;
25
+ try {
26
+ return await next();
27
+ }
28
+ catch (error) {
29
+ // Auto-capture the exception, then re-throw the ORIGINAL error untouched.
30
+ // Recording is wrapped so it can never mask the error it observes.
31
+ try {
32
+ const request = ctx.request;
33
+ await recordExceptionInStore(store, error, {
34
+ method: request.method(),
35
+ url: request.url(),
36
+ });
37
+ }
38
+ catch {
39
+ // Observability must never break the request it observes.
40
+ }
41
+ throw error;
42
+ }
43
+ finally {
44
+ // Post-response phase: record the now-complete request. Awaited so a slow
45
+ // store surfaces back-pressure here rather than leaking an unhandled
46
+ // rejection, but wrapped so observability can never break the request.
47
+ try {
48
+ await recordRequest(store, ctx, startedAt);
49
+ }
50
+ catch {
51
+ // Observability must never break the request it observes.
52
+ }
53
+ }
54
+ }
55
+ }
56
+ //# sourceMappingURL=telescope_middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telescope_middleware.js","sourceRoot":"","sources":["../../src/telescope_middleware.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAwB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE3E;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,OAAO,OAAO,mBAAmB;IACtC,KAAK,CAAC,MAAM,CAAC,GAAgB,EAAE,IAAY;QACzC,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;QACtC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;YACrD,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,EAAE,CAAC;QACtB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,0EAA0E;YAC1E,mEAAmE;YACnE,IAAI,CAAC;gBACH,MAAM,OAAO,GAAI,GAAkC,CAAC,OAAO,CAAC;gBAC5D,MAAM,sBAAsB,CAAC,KAAK,EAAE,KAAK,EAAE;oBACzC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE;oBACxB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;iBACnB,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,0DAA0D;YAC5D,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;gBAAS,CAAC;YACT,0EAA0E;YAC1E,qEAAqE;YACrE,uEAAuE;YACvE,IAAI,CAAC;gBACH,MAAM,aAAa,CAAC,KAAK,EAAE,GAAiC,EAAE,SAAS,CAAC,CAAC;YAC3E,CAAC;YAAC,MAAM,CAAC;gBACP,0DAA0D;YAC5D,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,49 @@
1
+ import type { Entry } from '../entry.js';
2
+ import type { TelescopeService } from '../service.js';
3
+ import type { EntryQuery } from '../store.js';
4
+ import type { UiHttpContext, UiRequest } from './http.js';
5
+ /**
6
+ * The JSON-API handler functions over a {@link TelescopeService}. Each takes the
7
+ * framework-light {@link UiHttpContext} (an Adonis `HttpContext` satisfies it) plus
8
+ * the service, reads query/route params off the request, and writes a JSON body to
9
+ * the response. No DI, no router — trivially unit-testable with a plain object.
10
+ */
11
+ export declare class TelescopeApi {
12
+ private readonly service;
13
+ constructor(service: TelescopeService);
14
+ /**
15
+ * `GET <path>/api/entries` — list entries newest-first, with optional filters:
16
+ * `?type=`, `?traceId=`, `?search=`, `?limit=` (capped), `?before=` (ISO date).
17
+ */
18
+ list(ctx: UiHttpContext): Promise<unknown>;
19
+ /** `GET <path>/api/entries/:id` — one entry with its full `content`, or 404. */
20
+ show(ctx: UiHttpContext, id: string): Promise<unknown>;
21
+ /** `GET <path>/api/trace/:traceId` — every entry under a trace, newest-first. */
22
+ trace(ctx: UiHttpContext, traceId: string): Promise<unknown>;
23
+ /**
24
+ * `GET <path>/api/stats` — dashboard aggregates: total count, top families, and
25
+ * top tags. `?limit=` caps each top-N list; `?type=` scopes `topFamilies`.
26
+ */
27
+ stats(ctx: UiHttpContext): Promise<unknown>;
28
+ }
29
+ /**
30
+ * A trimmed projection of an {@link Entry} for the list views — drops the
31
+ * potentially-large `content` (the detail endpoint serves that) and derives a
32
+ * short, human-readable `summary` line.
33
+ */
34
+ export interface EntrySummary {
35
+ id: string;
36
+ type: string;
37
+ familyHash: string | null;
38
+ tags: string[];
39
+ traceId: string | null;
40
+ durationMs: number | null;
41
+ sequence: number;
42
+ createdAt: string;
43
+ summary: string;
44
+ }
45
+ /** Project an entry to its {@link EntrySummary}. */
46
+ export declare function toSummary(entry: Entry): EntrySummary;
47
+ /** Build an {@link EntryQuery} from the request's query string. */
48
+ export declare function buildQuery(request: UiRequest): EntryQuery;
49
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/ui/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAO1D;;;;;GAKG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,gBAAgB;IAEtD;;;OAGG;IACG,IAAI,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;IAYhD,gFAAgF;IAC1E,IAAI,CAAC,GAAG,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAW5D,iFAAiF;IAC3E,KAAK,CAAC,GAAG,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQlE;;;OAGG;IACG,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC;CAalD;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,oDAAoD;AACpD,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,YAAY,CAapD;AAqBD,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,GAAG,UAAU,CAgBzD"}