@adonis-agora/telescope 0.8.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # @adonis-agora/telescope
2
2
 
3
+ ## 0.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#23](https://github.com/DavideCarvalho/adonis-agora-telescope/pull/23) [`7335b3f`](https://github.com/DavideCarvalho/adonis-agora-telescope/commit/7335b3f4ffe1c885b63c1f909e9d5f2af2e94679) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Publish a Node.js engine RANGE instead of one exact version. Both packages declared
8
+ `engines.node: "v26.7.0"` — a single pinned build, written by a renovate "pin dependencies" run
9
+ that treated a compatibility range as a version to pin. Every install
10
+ on any other Node emitted an engine warning, and an `engine-strict` install failed outright. Both
11
+ now declare `>=20.6.0`, the version the code actually requires, and renovate is configured to
12
+ leave `engines` alone so the fix survives the next cycle.
13
+
14
+ - [#23](https://github.com/DavideCarvalho/adonis-agora-telescope/pull/23) [`7335b3f`](https://github.com/DavideCarvalho/adonis-agora-telescope/commit/7335b3f4ffe1c885b63c1f909e9d5f2af2e94679) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Make the `logs` watcher safe to enable from both config files.
15
+
16
+ `watchers: ['logs']` can be set in `config/telescope.ts` (where it also accepts a `logs`
17
+ options block) and in `config/telescope_watchers.ts`. With both set, the second watcher to
18
+ boot silently did nothing — and then unteed the FIRST watcher's tap on shutdown, so the
19
+ logger was left half-instrumented. It now detects that the logger is already tapped, warns
20
+ once naming both config keys, and stays fully inert: it records nothing and its `stop()`
21
+ restores only what it teed itself.
22
+
23
+ - [#23](https://github.com/DavideCarvalho/adonis-agora-telescope/pull/23) [`7335b3f`](https://github.com/DavideCarvalho/adonis-agora-telescope/commit/7335b3f4ffe1c885b63c1f909e9d5f2af2e94679) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Report the real package version over MCP. The `initialize` handshake advertised a hardcoded
24
+ `0.4.0` regardless of the installed version; it now reads the package's own `VERSION`, which
25
+ the release pipeline keeps in lockstep with `package.json`.
26
+
27
+ - [#23](https://github.com/DavideCarvalho/adonis-agora-telescope/pull/23) [`7335b3f`](https://github.com/DavideCarvalho/adonis-agora-telescope/commit/7335b3f4ffe1c885b63c1f909e9d5f2af2e94679) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Restore the seven `config/*.stub` files, which shipped empty.
28
+
29
+ Every config stub the package publishes — `telescope.stub`, `telescope_watchers.stub`,
30
+ `telescope_ui.stub`, `telescope_ai.stub`, `telescope_alerts.stub`, `telescope_mcp.stub` and
31
+ `telescope_cpu_profiling.stub` — was a zero-byte file in the published tarball, so
32
+ `node ace add @adonis-agora/telescope` wrote an EMPTY `config/telescope.ts` (and an empty file
33
+ for each feature you selected) into your app. Only the migration stub had content.
34
+
35
+ The stubs are rebuilt from the current config surface, including everything that landed since
36
+ they were lost: the `logs` watcher and its `logs` block, `diagnostics.exclude` /
37
+ `diagnostics.recordClaimed`, `requestCapture`, `redact.perType`, `sampling`, `nPlusOne`, `pulse`,
38
+ `clientErrors`, `dashboardAuth`, `cpuProfiling.armEnabled`, `queueActions`, `queueManager`, the
39
+ `every-exception` and `metric-threshold` alert rules, `alerts.geoLookup`, and the whole
40
+ `telescope_cpu_profiling` config. A test now fails the build if any shipped stub is empty, lacks
41
+ its `exports(...)` header, or carries a backtick in its body — the defect that emptied them.
42
+
3
43
  ## 0.8.0
4
44
 
5
45
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"telescope_mcp_provider.d.ts","sourceRoot":"","sources":["../../providers/telescope_mcp_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAkB/D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,OAAO,OAAO,oBAAoB;IAC3B,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,OAAO,CAAC,OAAO;IAMT,IAAI;CAqFX"}
1
+ {"version":3,"file":"telescope_mcp_provider.d.ts","sourceRoot":"","sources":["../../providers/telescope_mcp_provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAmB/D;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,OAAO,OAAO,oBAAoB;IAC3B,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,OAAO,CAAC,OAAO;IAMT,IAAI;CAwFX"}
@@ -1,5 +1,6 @@
1
1
  import { resolveConfig as resolveTelescopeConfig } from '../src/define_config.js';
2
2
  import { resolveConfig, } from '../src/mcp/define_config.js';
3
+ import { VERSION } from '../src/mcp/index.js';
3
4
  import { TelescopeMcpServer } from '../src/mcp/server.js';
4
5
  import { MetricsService } from '../src/metrics/metrics_service.js';
5
6
  import { getTelescopeRuntime } from '../src/registry.js';
@@ -75,7 +76,10 @@ export default class TelescopeMcpProvider {
75
76
  : undefined;
76
77
  const server = new TelescopeMcpServer(service, metrics, {
77
78
  tools: config.tools,
78
- serverInfo: { name: 'adonis-telescope', version: '0.4.0' },
79
+ // Reported to the MCP client on `initialize`. Sourced from the package's own
80
+ // VERSION const (kept in lockstep with package.json by `scripts/sync-version.mjs`)
81
+ // so a release bump can never leave a stale version on the wire.
82
+ serverInfo: { name: 'adonis-telescope', version: VERSION },
79
83
  ...(diagnose !== undefined ? { diagnose } : {}),
80
84
  });
81
85
  const router = await this.app.container.make('router');
@@ -1 +1 @@
1
- {"version":3,"file":"telescope_mcp_provider.js","sourceRoot":"","sources":["../../providers/telescope_mcp_provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,IAAI,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAElF,OAAO,EAGL,aAAa,GACd,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACjB;IAAtB,YAAsB,GAAuB;QAAvB,QAAG,GAAH,GAAG,CAAoB;IAAG,CAAC;IAEzC,OAAO;QACb,OAAO,aAAa,CAClB,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAiC,eAAe,EAAE,SAAS,CAAC,CAChF,CAAC;IACJ,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,gEAAgE,SAAS,CAAC,GAAG,CAAC,EAAE,CACjF,CAAC;YACF,OAAO;QACT,CAAC;QACD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACnB,OAAO,CAAC,IAAI,CACV,6FAA6F;gBAC3F,8BAA8B,CACjC,CAAC;YACF,OAAO;QACT,CAAC;QAED,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAAC,KAAK,EAAE;YAC1C,QAAQ,EAAE,UAAU,CAAC,KAAK,CAAC,QAAQ;YACnC,IAAI,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI;YAC3B,OAAO,EAAE,UAAU,CAAC,KAAK,CAAC,OAAO;YACjC,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,WAAW;YACzC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK;YAC7B,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,UAAU,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7F,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,KAAK,EAAE;YACxC,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,UAAU,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC7F,CAAC,CAAC;QACH,+EAA+E;QAC/E,6EAA6E;QAC7E,8EAA8E;QAC9E,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC,oBAAoB,CAAC;QAC/D,MAAM,QAAQ,GAAsC,WAAW,EAAE,YAAY,EAAE;YAC7E,CAAC,CAAC,KAAK,EAAE,KAAY,EAAE,EAAE;gBACrB,oEAAoE;gBACpE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC1F,OAAO,WAAW,CAAC,gBAAgB,CAAC,KAAqC,EAAE;oBACzE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBAC9C,CAAC,CAAC;YACL,CAAC;YACH,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,MAAM,GAAG,IAAI,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE;YACtD,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,UAAU,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,OAAO,EAAE;YAC1D,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC;QAE/B,kFAAkF;QAClF,wEAAwE;QACxE,MAAM;aACH,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAe,EAAE,EAAE;YAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/C,MAAM,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,CAA4B,CAAC;YACrE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAClD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACzB,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC/B,CAAC;YACD,OAAO,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,CAAC,CAAC;aACD,EAAE,CAAC,mBAAmB,CAAC,CAAC;QAE3B,yEAAyE;QACzE,wEAAwE;QACxE,MAAM;aACH,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAe,EAAE,EAAE;YAC1C,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACzB,OAAO,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gDAAgD,EAAE,CAAC,CAAC;QACxF,CAAC,CAAC;aACD,EAAE,CAAC,mBAAmB,CAAC,CAAC;QAE3B,iFAAiF;QACjF,MAAM;aACH,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAe,EAAE,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;aAC3F,EAAE,CAAC,sBAAsB,CAAC,CAAC;IAChC,CAAC;CACF;AAUD,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"}
1
+ {"version":3,"file":"telescope_mcp_provider.js","sourceRoot":"","sources":["../../providers/telescope_mcp_provider.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export declare const VERSION = "0.8.0";
2
+ export declare const VERSION = "0.8.1";
3
3
  export { TelescopeAiDiagnoser } from './telescope_ai_diagnoser.js';
4
4
  export type { AnthropicMessagesClient, DiagnoseOptions, TelescopeAiDiagnoserOptions, } from './telescope_ai_diagnoser.js';
5
5
  export { normalizeConfidence, parseDiagnosis } from './diagnoser.js';
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export const VERSION = '0.8.0';
2
+ export const VERSION = '0.8.1';
3
3
  // — diagnoser —
4
4
  export { TelescopeAiDiagnoser } from './telescope_ai_diagnoser.js';
5
5
  // — diagnosis model + parsing —
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export declare const VERSION = "0.8.0";
2
+ export declare const VERSION = "0.8.1";
3
3
  export { consoleChannel, customChannel, slackChannel, webhookChannel, } from './alert_channel.js';
4
4
  export type { AlertChannel, ChannelFetch, ConsoleSink } from './alert_channel.js';
5
5
  export { formatSlackMessage } from './slack_format.js';
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export const VERSION = '0.8.0';
2
+ export const VERSION = '0.8.1';
3
3
  // — channels —
4
4
  export { consoleChannel, customChannel, slackChannel, webhookChannel, } from './alert_channel.js';
5
5
  // — slack formatting —
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export declare const VERSION = "0.8.0";
2
+ export declare const VERSION = "0.8.1";
3
3
  export { EntryType, isBatchOrigin } from './entry.js';
4
4
  export type { BatchOrigin, BuiltinEntryType, Entry, RecordInput } from './entry.js';
5
5
  export type { EntryQuery, TelescopeStore } from './store.js';
package/dist/src/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export const VERSION = '0.8.0';
2
+ export const VERSION = '0.8.1';
3
3
  // — entry model —
4
4
  export { EntryType, isBatchOrigin } from './entry.js';
5
5
  export { InMemoryTelescopeStore } from './stores/memory.js';
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export declare const VERSION = "0.8.0";
2
+ export declare const VERSION = "0.8.1";
3
3
  export { defineConfig, resolveConfig, MCP_TOOL_NAMES } from './define_config.js';
4
4
  export type { McpToolName, ResolvedTelescopeMcpConfig, TelescopeMcpConfig, } from './define_config.js';
5
5
  export { MCP_INTERNAL_ERROR, MCP_METHOD_NOT_FOUND, MCP_TOOLS, MCP_UNAUTHORIZED, TelescopeMcpServer, } from './server.js';
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export const VERSION = '0.8.0';
2
+ export const VERSION = '0.8.1';
3
3
  // — config —
4
4
  export { defineConfig, resolveConfig, MCP_TOOL_NAMES } from './define_config.js';
5
5
  // — server (plain, testable JSON-RPC surface) —
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export declare const VERSION = "0.8.0";
2
+ export declare const VERSION = "0.8.1";
3
3
  export { defineConfig, resolveConfig } from './define_config.js';
4
4
  export type { ResolvedTelescopeCpuProfilingConfig, TelescopeCpuProfilingConfig, } from './define_config.js';
5
5
  export { CPU_PROFILE_ENTRY_TYPE, ProfilerService, } from './profiler_service.js';
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export const VERSION = '0.8.0';
2
+ export const VERSION = '0.8.1';
3
3
  export { defineConfig, resolveConfig } from './define_config.js';
4
4
  export { CPU_PROFILE_ENTRY_TYPE, ProfilerService, } from './profiler_service.js';
5
5
  export { CpuProfiler, defaultSessionFactory } from './cpu-profiler.js';
@@ -99,7 +99,7 @@ export interface ReplayConfig {
99
99
  enabled?: boolean;
100
100
  /**
101
101
  * The local server port the replay targets (`127.0.0.1:<port>`). When omitted,
102
- * the `PORT` env var is used, falling back to 3000.
102
+ * the `PORT` env var is used, falling back to 3333 (the AdonisJS default).
103
103
  */
104
104
  port?: number;
105
105
  /** Per-call timeout in ms. Default 30000. */
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export declare const VERSION = "0.8.0";
2
+ export declare const VERSION = "0.8.1";
3
3
  export { defineConfig, resolveConfig, normalizePath, defaultAuthorize } from './define_config.js';
4
4
  export type { AuthorizeHook, ReplayConfig, ResolvedTelescopeUiConfig, TelescopeUiConfig, UiCredentials, } from './define_config.js';
5
5
  export { resolveDashboardAuth, performLogin, readSession, sanitizeReturnTo, decideDashboardAuth, SESSION_COOKIE_NAME, } from './auth.js';
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export const VERSION = '0.8.0';
2
+ export const VERSION = '0.8.1';
3
3
  // — config —
4
4
  export { defineConfig, resolveConfig, normalizePath, defaultAuthorize } from './define_config.js';
5
5
  // — built-in `dashboardAuth` login screen (optional; opt-in via `config/telescope_ui.ts`) —
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export declare const VERSION = "0.8.0";
2
+ export declare const VERSION = "0.8.1";
3
3
  export type { EmitterLike, Watcher } from './emitter.js';
4
4
  export { resolveStore, safeRecord } from './record.js';
5
5
  export { buildQueryEntry, DB_QUERY_EVENT, LucidQueryWatcher } from './lucid_query_watcher.js';
@@ -1,5 +1,5 @@
1
1
  /** Keep in sync with this package's `version` in package.json. */
2
- export const VERSION = '0.8.0';
2
+ export const VERSION = '0.8.1';
3
3
  // — runtime recording (advanced) —
4
4
  export { resolveStore, safeRecord } from './record.js';
5
5
  // — Lucid query watcher (the headline watcher) —
@@ -57,10 +57,26 @@ export declare class LogsWatcher {
57
57
  private readonly minLevelIndex;
58
58
  private readonly extraTags;
59
59
  private logger;
60
+ /** The levels THIS instance teed, so `stop()` never unwinds another watcher's tap. */
61
+ private readonly teedLevels;
60
62
  constructor(options?: LogsWatcherOptions);
61
- /** Tee the level methods on `logger`. Idempotent per instance. */
63
+ /**
64
+ * Tee the level methods on `logger`. Idempotent per instance AND per logger: a
65
+ * level already teed (by this watcher or another one) is left alone, so a logger
66
+ * is never wrapped twice and a line is never recorded twice.
67
+ *
68
+ * The `'logs'` watcher can be enabled from TWO places — `config/telescope.ts`
69
+ * (with `logs.minLevel` / `logs.tags`) and `config/telescope_watchers.ts` (with no
70
+ * options). Only the first one to boot owns the tap; the second finds the logger
71
+ * already teed, warns once naming both config keys, and becomes inert — including
72
+ * its `stop()`, which would otherwise untee the owner's tap on shutdown.
73
+ */
62
74
  start(logger: LoggerLike): void;
63
- /** Restore the original level methods on the tapped instance. */
75
+ /**
76
+ * Restore the level methods THIS watcher teed. A watcher that never took the tap
77
+ * (because another one already held it) restores nothing, so shutting it down
78
+ * leaves the owner's tap intact.
79
+ */
64
80
  stop(): void;
65
81
  /** Build + record a log entry from the level method's arguments. */
66
82
  private record;
@@ -1 +1 @@
1
- {"version":3,"file":"logs_watcher.d.ts","sourceRoot":"","sources":["../../../src/watchers/logs_watcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1D,iFAAiF;AACjF,eAAO,MAAM,UAAU,+DAAgE,CAAC;AACxF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD;;2CAE2C;AAC3C,KAAK,SAAS,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG;KACtB,KAAK,IAAI,QAAQ,CAAC,CAAC,EAAE,SAAS;CAChC,CAAC;AAEF,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,KAAK,EAAE,QAAQ,CAAC;IAChB,8EAA8E;IAC9E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxC,kDAAkD;IAClD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,uDAAuD;IACvD,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAkBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,WAAW;IACtB,QAAQ,CAAC,IAAI,QAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,MAAM,CAA2B;gBAE7B,OAAO,GAAE,kBAAuB;IAK5C,kEAAkE;IAClE,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAgC/B,iEAAiE;IACjE,IAAI,IAAI,IAAI;IAYZ,oEAAoE;IACpE,OAAO,CAAC,MAAM;CAGf;AAUD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG;IAC3C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACzC,CAQA;AAeD;kEACkE;AAClE,wBAAgB,aAAa,CAC3B,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,OAAO,EAAE,EACf,SAAS,GAAE,SAAS,MAAM,EAAO,GAChC,WAAW,CAAC,eAAe,CAAC,CAW9B"}
1
+ {"version":3,"file":"logs_watcher.d.ts","sourceRoot":"","sources":["../../../src/watchers/logs_watcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1D,iFAAiF;AACjF,eAAO,MAAM,UAAU,+DAAgE,CAAC;AACxF,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnD;;2CAE2C;AAC3C,KAAK,SAAS,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAAG;KACtB,KAAK,IAAI,QAAQ,CAAC,CAAC,EAAE,SAAS;CAChC,CAAC;AAEF,0CAA0C;AAC1C,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,KAAK,EAAE,QAAQ,CAAC;IAChB,8EAA8E;IAC9E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,oFAAoF;IACpF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACxC,kDAAkD;IAClD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,uDAAuD;IACvD,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAkBD;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,WAAW;IACtB,QAAQ,CAAC,IAAI,QAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,MAAM,CAA2B;IACzC,sFAAsF;IACtF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkB;gBAEjC,OAAO,GAAE,kBAAuB;IAK5C;;;;;;;;;;OAUG;IACH,KAAK,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAkD/B;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAYZ,oEAAoE;IACpE,OAAO,CAAC,MAAM;CAGf;AAUD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG;IAC3C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CACzC,CAQA;AAeD;kEACkE;AAClE,wBAAgB,aAAa,CAC3B,KAAK,EAAE,QAAQ,EACf,IAAI,EAAE,OAAO,EAAE,EACf,SAAS,GAAE,SAAS,MAAM,EAAO,GAChC,WAAW,CAAC,eAAe,CAAC,CAW9B"}
@@ -36,21 +36,37 @@ export class LogsWatcher {
36
36
  minLevelIndex;
37
37
  extraTags;
38
38
  logger = null;
39
+ /** The levels THIS instance teed, so `stop()` never unwinds another watcher's tap. */
40
+ teedLevels = [];
39
41
  constructor(options = {}) {
40
42
  this.minLevelIndex = LOG_LEVELS.indexOf(options.minLevel ?? 'trace');
41
43
  this.extraTags = options.tags ?? [];
42
44
  }
43
- /** Tee the level methods on `logger`. Idempotent per instance. */
45
+ /**
46
+ * Tee the level methods on `logger`. Idempotent per instance AND per logger: a
47
+ * level already teed (by this watcher or another one) is left alone, so a logger
48
+ * is never wrapped twice and a line is never recorded twice.
49
+ *
50
+ * The `'logs'` watcher can be enabled from TWO places — `config/telescope.ts`
51
+ * (with `logs.minLevel` / `logs.tags`) and `config/telescope_watchers.ts` (with no
52
+ * options). Only the first one to boot owns the tap; the second finds the logger
53
+ * already teed, warns once naming both config keys, and becomes inert — including
54
+ * its `stop()`, which would otherwise untee the owner's tap on shutdown.
55
+ */
44
56
  start(logger) {
45
57
  if (this.logger)
46
58
  return;
47
- this.logger = logger;
48
59
  const watcher = this;
60
+ let alreadyTeed = false;
49
61
  for (let index = 0; index < LOG_LEVELS.length; index++) {
50
62
  const level = LOG_LEVELS[index];
51
63
  const original = logger[level];
52
- if (typeof original !== 'function' || original[TEED])
64
+ if (typeof original !== 'function')
65
+ continue;
66
+ if (original[TEED]) {
67
+ alreadyTeed = true;
53
68
  continue;
69
+ }
54
70
  const teed = function teedLevel(...args) {
55
71
  // Nested log (e.g. our own failure logging) — call the original but
56
72
  // don't record, breaking the record→log→record loop.
@@ -72,15 +88,30 @@ export class LogsWatcher {
72
88
  teed[TEED] = true;
73
89
  teed.__telescopeOriginal__ = original;
74
90
  logger[level] = teed;
91
+ this.teedLevels.push(level);
75
92
  }
93
+ if (this.teedLevels.length === 0) {
94
+ if (alreadyTeed) {
95
+ console.warn("Telescope: the 'logs' watcher is already tapping this logger, so this second " +
96
+ 'one records nothing (its minLevel/tags are ignored). Enable it in ONE place: ' +
97
+ "either `watchers: ['logs']` in config/telescope.ts (which also accepts a `logs` " +
98
+ "options block) or `watchers: ['logs']` in config/telescope_watchers.ts.");
99
+ }
100
+ return;
101
+ }
102
+ this.logger = logger;
76
103
  }
77
- /** Restore the original level methods on the tapped instance. */
104
+ /**
105
+ * Restore the level methods THIS watcher teed. A watcher that never took the tap
106
+ * (because another one already held it) restores nothing, so shutting it down
107
+ * leaves the owner's tap intact.
108
+ */
78
109
  stop() {
79
110
  const logger = this.logger;
80
111
  if (!logger)
81
112
  return;
82
113
  this.logger = null;
83
- for (const level of LOG_LEVELS) {
114
+ for (const level of this.teedLevels.splice(0)) {
84
115
  const current = logger[level];
85
116
  if (current?.[TEED] && current.__telescopeOriginal__) {
86
117
  logger[level] = current.__telescopeOriginal__;
@@ -1 +1 @@
1
- {"version":3,"file":"logs_watcher.js","sourceRoot":"","sources":["../../../src/watchers/logs_watcher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"logs_watcher.js","sourceRoot":"","sources":["../../../src/watchers/logs_watcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,193 @@
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
8
+ * use the in-memory store with the 'request' and 'diagnostics' watchers enabled and
9
+ * a 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', run the
28
+ * migration this package publishes (or pass autoCreateTable: true), switch
29
+ * 'store' to 'lucid', and uncomment the lucid driver:
30
+ */
31
+ stores: {
32
+ memory: storage.memory({ limit: 1000 }),
33
+ // lucid: storage.lucid({ connection: 'pg' }),
34
+ },
35
+
36
+ /**
37
+ * Active watchers. Omit one to disable it.
38
+ * - 'request' — records each HTTP request (method, url, status, duration).
39
+ * - 'diagnostics' — records every diagnostics-bus publish from a sibling Agora lib.
40
+ * - 'logs' — tees the AdonisJS logger and records each line as a 'log' entry.
41
+ *
42
+ * Note: '@adonis-agora/telescope/watchers' can also start a logs watcher. Enable
43
+ * 'logs' in ONE place only — whichever provider boots first owns the tap, and the
44
+ * other one is ignored (with a warning) so nothing is recorded twice.
45
+ */
46
+ // watchers: ['request', 'diagnostics'],
47
+
48
+ /**
49
+ * Fine-tunes the 'diagnostics' watcher.
50
+ * - exclude — 'lib:event' keys to skip recording, e.g. 'media:upload.progress'.
51
+ * The events stay live on the bus for other subscribers.
52
+ * - recordClaimed — also record events a lib-specific watcher already claimed
53
+ * (and therefore already recorded as a typed entry). Default false.
54
+ */
55
+ // diagnostics: {
56
+ // exclude: ['media:upload.progress'],
57
+ // recordClaimed: false,
58
+ // },
59
+
60
+ /**
61
+ * Fine-tunes the 'logs' watcher.
62
+ * - minLevel — only record at/above this level ('trace' | 'debug' | 'info' |
63
+ * 'warn' | 'error' | 'fatal'). Default 'trace' (record everything).
64
+ * - tags — extra tags appended to every recorded log entry.
65
+ */
66
+ // logs: {
67
+ // minLevel: 'info',
68
+ // tags: ['app'],
69
+ // },
70
+
71
+ /**
72
+ * Request BODY capture. OFF by default — request entries carry no 'body' field
73
+ * until this block is present. Supplying an empty object turns it on with the
74
+ * safe defaults below; each gate runs BEFORE the synchronous redaction pass, so a
75
+ * huge or binary body is never walked (a gated-out body becomes a marker string).
76
+ * - maxBodyBytes — skip bodies over this size, measured in O(1) from
77
+ * content-length or a string/Buffer length. Default
78
+ * 131072 (128 KiB); false disables the size gate.
79
+ * - skipBodyContentTypes — content types never captured. A string matches as a
80
+ * case-insensitive prefix, a RegExp is tested. Defaults
81
+ * to application/octet-stream, application/offset+octet-stream
82
+ * and multipart/form-data.
83
+ * - skipBody — your own predicate; return true to skip this body.
84
+ */
85
+ // requestCapture: {
86
+ // maxBodyBytes: 131_072,
87
+ // skipBodyContentTypes: ['application/octet-stream', 'multipart/form-data'],
88
+ // skipBody: (request) => request.url.startsWith('/webhooks/'),
89
+ // },
90
+
91
+ /**
92
+ * Sensitive-data redaction. Every entry's content is scrubbed before it is
93
+ * persisted — a built-in set of sensitive keys ('authorization', 'cookie',
94
+ * 'password', 'token', 'api_key', 'secret', 'set-cookie', …) is masked with
95
+ * '[REDACTED]', case-insensitively, at any depth. ENABLED by default.
96
+ *
97
+ * 'perType' overrides the NUMERIC bounds for one entry type — useful to give
98
+ * exception stacks a bigger byte budget than high-volume request entries. Masking
99
+ * stays global.
100
+ */
101
+ // redact: {
102
+ // enabled: true,
103
+ // keys: ['ssn', 'credit_card'],
104
+ // perType: {
105
+ // exception: { maxContentBytes: 64_000, maxStringLength: 8_000 },
106
+ // },
107
+ // },
108
+
109
+ /**
110
+ * Tail-sampling on the WRITE path — a dropped entry is never persisted. Accepts
111
+ * a bare number (a uniform keep-rate for every type) or a per-type map whose
112
+ * reserved 'default' key covers the rest. A rule object keeps a fraction of the
113
+ * noise while always retaining what matters.
114
+ */
115
+ // sampling: {
116
+ // default: 1,
117
+ // query: { rate: 0.1, keepErrors: true, keepSlowMs: 500 },
118
+ // },
119
+
120
+ /**
121
+ * N+1 query-loop detection over stored entries (read-only analysis).
122
+ * 'threshold' is the minimum repetitions of one query template within a trace.
123
+ */
124
+ // nPlusOne: {
125
+ // enabled: true,
126
+ // threshold: 3,
127
+ // },
128
+
129
+ /**
130
+ * Pulse — the aggregated 'at a glance' health rollup computed on demand from
131
+ * stored entries. ENABLED by default over a trailing 1h window with every card.
132
+ */
133
+ // pulse: {
134
+ // enabled: true,
135
+ // windowMs: 3_600_000,
136
+ // topN: 5,
137
+ // buckets: 60,
138
+ // slowRouteMs: 1000,
139
+ // // cards: ['counts', 'slowest'],
140
+ // },
141
+
142
+ /**
143
+ * Live SSE streaming of new entries to the dashboard. ENABLED by default and
144
+ * zero-overhead while no dashboard is connected. Set enabled: false to turn
145
+ * the <telescope>/api/stream endpoint off entirely.
146
+ */
147
+ // stream: {
148
+ // enabled: true,
149
+ // },
150
+
151
+ /**
152
+ * Background retention. A pruner deletes stale entries on a timer so the store
153
+ * never grows without bound. OFF unless this block is present — supply it to
154
+ * delete entries older than 'after', optionally capping by count with 'keepLast'.
155
+ * - after — age cutoff: a ms number or '<int><ms|s|m|h|d>' (default '24h').
156
+ * - keepLast — keep at most the newest N of the entries a cycle would delete.
157
+ * - intervalMs — how often a scheduled cycle runs (default 60000).
158
+ */
159
+ // prune: {
160
+ // after: '24h',
161
+ // // keepLast: 10000,
162
+ // // intervalMs: 60_000,
163
+ // },
164
+
165
+ /**
166
+ * Overload protection. A guard samples the event-loop delay and PAUSES ingestion
167
+ * when the p99 lag crosses maxEventLoopLagMs, resuming once it recovers — so
168
+ * telescope can never amplify an incident. ENABLED by default at 200ms.
169
+ */
170
+ // overload: {
171
+ // enabled: true,
172
+ // maxEventLoopLagMs: 200,
173
+ // startupGraceMs: 5_000,
174
+ // },
175
+
176
+ /**
177
+ * Public front-end error ingestion: a POST endpoint browsers report client-side
178
+ * errors to, recorded as 'client_exception' entries. DISABLED by default — while
179
+ * off no route is registered at all, so a probe cannot tell it is wired.
180
+ * - path — where the endpoint mounts. Default '/telescope/client-errors'.
181
+ * - maxBodyBytes — hard cap on the accepted body, checked before validation.
182
+ * Default 32768 (32 KB).
183
+ * - rateLimit — per-IP token bucket, per process. Default 60 requests/minute.
184
+ * - authorize — runs first; return false to reject with 403.
185
+ */
186
+ // clientErrors: {
187
+ // enabled: true,
188
+ // path: '/telescope/client-errors',
189
+ // maxBodyBytes: 32_768,
190
+ // rateLimit: { perMinute: 60 },
191
+ // // authorize: (ctx) => ctx.request.header('x-app-key') === env.get('APP_KEY'),
192
+ // },
193
+ })
@@ -0,0 +1,57 @@
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
+ * Bring your OWN model client instead. Any object with a messages.create method
27
+ * matching the Anthropic Messages shape is accepted, and takes precedence over
28
+ * apiKey — telescope then never constructs the Anthropic SDK itself.
29
+ */
30
+ // client: myModelClient,
31
+
32
+ /**
33
+ * Claude model id. Defaults to 'claude-sonnet-4-6' (best speed/intelligence
34
+ * balance). Use 'claude-opus-4-8' for the most capable diagnosis, or
35
+ * 'claude-haiku-4-5-20251001' for the cheapest.
36
+ */
37
+ // model: 'claude-sonnet-4-6',
38
+
39
+ /**
40
+ * Hard cap on generated tokens per diagnosis. Default 1024.
41
+ */
42
+ // maxTokens: 1024,
43
+
44
+ /**
45
+ * How long a cached diagnosis stays fresh, in ms. An exception family is
46
+ * diagnosed once, then served from cache until this elapses. Defaults to 24h.
47
+ */
48
+ // cacheTtlMs: 24 * 60 * 60 * 1000,
49
+
50
+ /**
51
+ * Per-diagnosis wall-clock timeout, in ms, enforced by the diagnosis coordinator
52
+ * that backs the dashboard's Diagnose button, the MCP diagnose_exception tool and
53
+ * the alerter's 'Probable cause (AI)' section. A slower model call is abandoned
54
+ * (the caller proceeds without the AI note). Default 8000; 0 or less disables it.
55
+ */
56
+ // timeoutMs: 8000,
57
+ })
@@ -0,0 +1,78 @@
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
8
+ * the telescope store every 30s for brand-new exception families, and logs each
9
+ * alert 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).
32
+ * - { type: 'every-exception', window? } — page for EVERY exception, not just new
33
+ * families, still rate-limited per family by cooldown. The optional window only
34
+ * counts occurrences shown on the alert; it does not gate firing.
35
+ * - { type: 'exception-rate', window, threshold } — page when >= threshold
36
+ * exceptions are recorded in the trailing window.
37
+ * - { type: 'metric-threshold', metric, window, comparator, threshold, minSamples? }
38
+ * — page when a windowed metric crosses a threshold, and AUTO-RESOLVE when it
39
+ * clears. metric is one of 'request-p95-ms', 'request-p99-ms', 'query-p95-ms',
40
+ * 'query-p99-ms', 'cache-hit-rate', 'exception-count'; comparator is 'gte' or
41
+ * 'lte'. minSamples (default 1) guards a percentile rule against a single
42
+ * outlier on a quiet host, and is ignored for 'exception-count'.
43
+ *
44
+ * Only the FIRST rule of each type is evaluated — list one rule per type.
45
+ */
46
+ // rules: [
47
+ // { type: 'new-exception', window: '1h' },
48
+ // { type: 'metric-threshold', metric: 'request-p99-ms', window: '5m', comparator: 'gte', threshold: 800 },
49
+ // ],
50
+
51
+ /**
52
+ * External dashboard URL — when set, Slack alerts include a deep link to the entry.
53
+ */
54
+ // dashboardUrl: 'https://telescope.example.com/',
55
+
56
+ /**
57
+ * Poll cadence and re-notify cooldown (duration strings).
58
+ */
59
+ // every: '30s',
60
+ // cooldown: '15m',
61
+
62
+ /**
63
+ * Reporting instance identifier carried on every alert payload. Default 'telescope'.
64
+ */
65
+ // instanceId: 'api-eu-west-1',
66
+
67
+ /**
68
+ * Optional IP-to-geo resolver. Called ONLY when an exception alert fires and
69
+ * carries a client IP; the result renders as a coarse 'Location' field on channels
70
+ * that support it. Telescope ships no geo database — you own the lookup and any
71
+ * caching. Return null (or throw) to omit the field.
72
+ */
73
+ // geoLookup: async (ip) => {
74
+ // const res = await fetch('https://ipapi.example/' + ip)
75
+ // const body = await res.json()
76
+ // return { city: body.city, country: body.country, countryCode: body.country_code }
77
+ // },
78
+ })
@@ -0,0 +1,42 @@
1
+ {{{
2
+ exports({ to: app.configPath('telescope_cpu_profiling.ts') })
3
+ }}}
4
+ import { defineConfig } from '@adonis-agora/telescope/cpu_profiling'
5
+
6
+ /**
7
+ * Configuration for '@adonis-agora/telescope/cpu_profiling'. On-demand V8 CPU
8
+ * captures via node:inspector, rendered as a flamegraph in the dashboard.
9
+ *
10
+ * Profiling carries real overhead (a running sampling profiler slows the process it
11
+ * profiles), so it is OFF by default. While disabled the middleware hook is a single
12
+ * boolean check and node:inspector is never required.
13
+ */
14
+ export default defineConfig({
15
+ /**
16
+ * Master switch. Set to true to enable capture.
17
+ */
18
+ enabled: false,
19
+
20
+ /**
21
+ * Fraction (0-1) of requests captured automatically. 0 — the default — means
22
+ * captures only happen when explicitly armed from the dashboard, which itself
23
+ * requires cpuProfiling.armEnabled in config/telescope_ui.ts.
24
+ */
25
+ // sampleRate: 0,
26
+
27
+ /**
28
+ * Maximum concurrent captures, keeping overhead bounded under load. Default 2.
29
+ */
30
+ // maxConcurrent: 2,
31
+
32
+ /**
33
+ * Captures shorter than this many ms are discarded (not worth an entry). Default 5.
34
+ */
35
+ // minDurationMs: 5,
36
+
37
+ /**
38
+ * V8 sampling interval in microseconds — lower is finer-grained and costlier.
39
+ * Default 1000, floored at 100.
40
+ */
41
+ // samplingIntervalMicros: 1000,
42
+ })
@@ -0,0 +1,48 @@
1
+ {{{
2
+ exports({ to: app.configPath('telescope_mcp.ts') })
3
+ }}}
4
+ import { defineConfig } from '@adonis-agora/telescope/mcp'
5
+
6
+ /**
7
+ * Configuration for '@adonis-agora/telescope/mcp'. Exposes the captured telemetry to
8
+ * a coding agent (Claude Code, Cursor, …) over the Model Context Protocol as a
9
+ * JSON-RPC endpoint at 'POST /telescope/mcp'.
10
+ *
11
+ * Access reuses the SAME guard as the dashboard: allowed automatically outside
12
+ * production, and in production only when a token / basic credential — or a custom
13
+ * authorize hook — permits it. A denial is returned as a JSON-RPC -32001 error
14
+ * (MCP has no transport-level 401).
15
+ */
16
+ export default defineConfig({
17
+ /**
18
+ * Master switch. Set to false to register no routes at all.
19
+ */
20
+ // enabled: true,
21
+
22
+ /**
23
+ * URL the JSON-RPC endpoint mounts at.
24
+ */
25
+ // path: '/telescope/mcp',
26
+
27
+ /**
28
+ * Access-decision hook (identical to the UI/metrics guard). Return true to allow
29
+ * the request. Delegate to your own app auth here, e.g.:
30
+ */
31
+ // authorize: (ctx) => ctx.auth?.user?.isAdmin === true,
32
+
33
+ /**
34
+ * Built-in credentials for the default policy (ignored when authorize is set):
35
+ * - token: allow 'Authorization: Bearer <token>' or '?token=<token>'
36
+ * - basic: allow HTTP Basic auth
37
+ */
38
+ // credentials: {
39
+ // token: env.get('TELESCOPE_MCP_TOKEN'),
40
+ // },
41
+
42
+ /**
43
+ * Which tools to expose. Omit for all six ('list_entries', 'get_entry',
44
+ * 'get_trace', 'get_waterfall', 'get_health', 'diagnose_exception'). Restrict to
45
+ * a read-only surface, e.g.:
46
+ */
47
+ // tools: ['list_entries', 'get_entry', 'get_trace', 'get_waterfall', 'get_health'],
48
+ })
@@ -0,0 +1,92 @@
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 is
9
+ * denied unless you set a token / basic credential below, or supply your own
10
+ * 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
+ * Built-in login screen. When present, the provider mounts a server-rendered
43
+ * login page plus its submit and logout routes, and stamps a session guard on the
44
+ * dashboard: an unauthenticated page navigation is redirected to the login page
45
+ * and an unauthenticated API request gets a 401. The signed session cookie is
46
+ * minted only by your own login hook.
47
+ *
48
+ * This is ADDITIVE and composes WITH authorize (both must pass). Omit it entirely
49
+ * to keep the dashboard's default behavior. A missing secret or login hook fails
50
+ * closed at boot.
51
+ */
52
+ // dashboardAuth: {
53
+ // secret: env.get('TELESCOPE_DASHBOARD_SECRET'),
54
+ // ttl: '8h',
55
+ // login: async (username, password) => {
56
+ // const user = await User.verifyCredentials(username, password)
57
+ // return user.isAdmin ? { id: String(user.id), name: user.fullName } : null
58
+ // },
59
+ // },
60
+
61
+ /**
62
+ * Request REPLAY: re-issue a captured request from the dashboard against the
63
+ * LOCAL server. DISABLED BY DEFAULT because it re-runs a real request that may
64
+ * MUTATE state (a captured POST/DELETE runs again). It only ever targets
65
+ * 127.0.0.1:<port> (same-origin, never an arbitrary URL) and strips
66
+ * cookie/authorization/host headers. Enable it knowingly:
67
+ */
68
+ // replay: {
69
+ // enabled: true,
70
+ // // port: 3333, // defaults to the PORT env var, then 3333
71
+ // // timeoutMs: 30_000,
72
+ // },
73
+
74
+ /**
75
+ * The dashboard's 'arm a CPU profile' trigger. DISABLED BY DEFAULT, like replay —
76
+ * arming a capture runs a V8 sampling profiler over the next requests, which costs
77
+ * real CPU. READING captured profiles is unaffected; only the arm action is gated.
78
+ * Requires '@adonis-agora/telescope/cpu_profiling' to be installed and enabled.
79
+ */
80
+ // cpuProfiling: {
81
+ // armEnabled: true,
82
+ // },
83
+
84
+ /**
85
+ * The queue console's MUTATING actions (retry / enqueue). DISABLED BY DEFAULT,
86
+ * like replay — they act on real jobs. Reading the queue console is unaffected.
87
+ * Requires the 'queue-manager' watcher in config/telescope_watchers.ts.
88
+ */
89
+ // queueActions: {
90
+ // enabled: true,
91
+ // },
92
+ })
@@ -0,0 +1,120 @@
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 installed
9
+ * '@adonisjs/lucid' types. Every other watcher is 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 as 'log' entries. The CORE
24
+ * config can also start this watcher, with minLevel/tags
25
+ * options this one has no place for — enable it in ONE place
26
+ * only. Whichever provider boots first owns the tap; the other
27
+ * is ignored with a warning, so nothing is recorded twice.
28
+ * - 'queue' — records @adonisjs/queue job executions (optional peer). No-op
29
+ * when the peer is absent.
30
+ * - 'events' — records every event emitted through the core Emitter (onAny),
31
+ * with an ignore-list (db:query / mail:sent are excluded by default).
32
+ * - 'redis' — records @adonisjs/redis commands (optional peer; wraps the
33
+ * ioredis sendCommand). No-op when the peer is absent.
34
+ * - 'profiling' — publishes the opt-in profile()/startProfile() timing-span
35
+ * helpers. Wrap a code section to record its label, duration
36
+ * and in-span marks. Zero cost until enabled AND used.
37
+ * - 'schedule' — publishes the opt-in scheduleTask()/recordScheduledRun()
38
+ * helpers. AdonisJS ships no scheduler event to tap, so this
39
+ * is EXPLICIT integration: wrap the closure you hand your
40
+ * scheduler with scheduleTask('name', fn), or call
41
+ * recordScheduledRun(...) from your own scheduler callback.
42
+ * - 'queue-manager' — publishes the Live Queue Manager driver behind the queue
43
+ * console (list / inspect / retry / enqueue). This is a live
44
+ * control surface, not an entry watcher — configure it under
45
+ * 'queueManager' below.
46
+ */
47
+ // watchers: ['query'],
48
+
49
+ /**
50
+ * Tuning for the Lucid 'query' watcher (enabled by default). It records every
51
+ * SQL query Lucid emits on db:query, grouped by normalized SQL template so the
52
+ * Pulse slow-query and N+1 cards can roll up 'the same query'.
53
+ */
54
+ // query: {
55
+ // // Queries at/above this many ms get a 'slow' tag. Default 500.
56
+ // slowMs: 500,
57
+ // // Keep the raw bound VALUES. Off by default — bindings carry PII/secrets, so
58
+ // // they are redacted to '[REDACTED]' placeholders (arity preserved). Default false.
59
+ // captureBindings: false,
60
+ // // Connection names (case-insensitive) whose queries are NOT recorded.
61
+ // ignoreConnections: [],
62
+ // // Normalize SQL into the familyHash grouping key (collapse whitespace, replace
63
+ // // literals with '?'). Off hashes the raw SQL verbatim. Default true.
64
+ // normalize: true,
65
+ // },
66
+
67
+ /**
68
+ * Tuning for the 'http-client' (outbound) watcher. Outbound HTTP is OPT-IN:
69
+ * AdonisJS has no single built-in client, so nothing is monkey-patched. Wrap a
70
+ * fetch with instrumentFetch(fetch) (from '@adonis-agora/telescope/watchers')
71
+ * and hand it to your client — it inherits the settings below.
72
+ */
73
+ // httpClient: {
74
+ // // Outbound calls at/above this many ms get a 'slow' tag. Default 1000.
75
+ // slowMs: 1000,
76
+ // // Hosts (exact, case-insensitive; may include a port) whose calls are not recorded.
77
+ // ignoreHosts: [],
78
+ // // Record request/response body SIZES (bytes, never the bytes). Default false.
79
+ // captureBodies: false,
80
+ // },
81
+
82
+ /**
83
+ * Tuning for the 'profiling' watcher. Add 'profiling' to watchers, then wrap a
84
+ * code section with profile('label', fn) (or bracket it with startProfile) —
85
+ * both imported from '@adonis-agora/telescope/watchers'.
86
+ */
87
+ // profiling: {
88
+ // // Spans at/above this many ms get a 'slow' tag. Default 100.
89
+ // slowMs: 100,
90
+ // // Spans below this many ms are discarded (too short to keep). Default 0.
91
+ // minDurationMs: 0,
92
+ // },
93
+
94
+ /**
95
+ * Tuning for the 'schedule' watcher. Add 'schedule' to watchers, then wrap the
96
+ * closure you hand your scheduler with scheduleTask('name', fn) (or call
97
+ * recordScheduledRun(...)) — both from '@adonis-agora/telescope/watchers'.
98
+ */
99
+ // schedule: {
100
+ // // Runs at/above this many ms get a 'slow' tag. Default 1000.
101
+ // slowMs: 1000,
102
+ // },
103
+
104
+ /**
105
+ * Config for the 'queue-manager' capability — the driver behind the dashboard's
106
+ * live queue console. Add 'queue-manager' to watchers to publish it.
107
+ * - queues — REQUIRED to get anything. @adonisjs/queue has no queue-enumeration
108
+ * API (queue names only exist as strings at dispatch time), so there
109
+ * is nothing to auto-discover. Default [] (the console reports
110
+ * 'not configured').
111
+ * - adapter — which configured queue adapter to resolve. Omit for the default one.
112
+ *
113
+ * The console's MUTATING actions (retry / enqueue) are additionally gated by
114
+ * queueActions.enabled in config/telescope_ui.ts, and are off by default.
115
+ */
116
+ // queueManager: {
117
+ // queues: ['default', 'emails'],
118
+ // // adapter: 'redis',
119
+ // },
120
+ })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/telescope",
3
- "version": "0.8.0",
3
+ "version": "0.8.1",
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": {
@@ -143,7 +143,7 @@
143
143
  "vitest": "3.2.7"
144
144
  },
145
145
  "engines": {
146
- "node": "v26.7.0"
146
+ "node": ">=20.6.0"
147
147
  },
148
148
  "keywords": [
149
149
  "adonisjs",