@adonis-agora/telescope 0.8.0 → 0.8.2
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 +70 -0
- package/dist/providers/telescope_mcp_provider.d.ts.map +1 -1
- package/dist/providers/telescope_mcp_provider.js +5 -1
- package/dist/providers/telescope_mcp_provider.js.map +1 -1
- package/dist/src/ai/index.d.ts +1 -1
- package/dist/src/ai/index.js +1 -1
- package/dist/src/alerts/index.d.ts +1 -1
- package/dist/src/alerts/index.js +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/mcp/index.d.ts +1 -1
- package/dist/src/mcp/index.js +1 -1
- package/dist/src/profiling/index.d.ts +1 -1
- package/dist/src/profiling/index.js +1 -1
- package/dist/src/ui/define_config.d.ts +1 -1
- package/dist/src/ui/index.d.ts +1 -1
- package/dist/src/ui/index.js +1 -1
- package/dist/src/watchers/index.d.ts +1 -1
- package/dist/src/watchers/index.js +1 -1
- package/dist/src/watchers/logs_watcher.d.ts +18 -2
- package/dist/src/watchers/logs_watcher.d.ts.map +1 -1
- package/dist/src/watchers/logs_watcher.js +36 -5
- package/dist/src/watchers/logs_watcher.js.map +1 -1
- package/dist/stubs/config/telescope.stub +193 -0
- package/dist/stubs/config/telescope_ai.stub +57 -0
- package/dist/stubs/config/telescope_alerts.stub +78 -0
- package/dist/stubs/config/telescope_cpu_profiling.stub +42 -0
- package/dist/stubs/config/telescope_mcp.stub +48 -0
- package/dist/stubs/config/telescope_ui.stub +92 -0
- package/dist/stubs/config/telescope_watchers.stub +120 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,75 @@
|
|
|
1
1
|
# @adonis-agora/telescope
|
|
2
2
|
|
|
3
|
+
## 0.8.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#26](https://github.com/DavideCarvalho/adonis-agora-telescope/pull/26) [`c53ba37`](https://github.com/DavideCarvalho/adonis-agora-telescope/commit/c53ba37e54418504fd39f3608e91ac6e9c76567d) Thanks [@DavideCarvalho](https://github.com/DavideCarvalho)! - Stop pinning 0.x peers with a caret, which npm rejects outright.
|
|
8
|
+
|
|
9
|
+
Below 1.0 a caret does not cross a minor: `^0.32.0` means `>=0.32.0 <0.33.0`. pnpm downgrades an
|
|
10
|
+
unsatisfied peer to a warning, so a workspace never notices — but **npm answers `ERESOLVE` and
|
|
11
|
+
refuses to install**, and an optional peer that IS present must still match.
|
|
12
|
+
|
|
13
|
+
`@adonis-agora/telescope` declared `"@anthropic-ai/sdk": "^0.32.0"`, which was **already broken**:
|
|
14
|
+
installing it alongside any current SDK failed.
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
While resolving: @adonis-agora/telescope@0.8.1
|
|
18
|
+
Found: @anthropic-ai/sdk@0.116.0
|
|
19
|
+
Conflicting peer dependency: @anthropic-ai/sdk@0.32.1
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
It now declares `>=0.32.0 <1.0.0` — the same floor, verified to compile against every SDK minor
|
|
23
|
+
from 0.32.0 through 0.116.0, with an upper bound that stops excluding them.
|
|
24
|
+
|
|
25
|
+
`@adonis-agora/telescope-ui` declared `"@adonis-agora/telescope": "^0.8.0"`, the same defect one
|
|
26
|
+
release from biting: satisfied by telescope 0.8.1 today, unsatisfiable the moment telescope cuts
|
|
27
|
+
0.9.0. It now declares `>=0.7.0 <1.0.0`. The floor is 0.7.0 because that is the first release
|
|
28
|
+
serving every route this console calls — `/api/retention`, `/api/profiles*`, `/api/queues/live*`,
|
|
29
|
+
`/api/schedules/live` and `/api/exceptions/:id/diagnose` — not 0.5.0, which is merely where the
|
|
30
|
+
provider still type-checks and where the console's Profiles, Queues, Schedules and retention
|
|
31
|
+
sections would all 404.
|
|
32
|
+
|
|
33
|
+
## 0.8.1
|
|
34
|
+
|
|
35
|
+
### Patch Changes
|
|
36
|
+
|
|
37
|
+
- [#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
|
|
38
|
+
`engines.node: "v26.7.0"` — a single pinned build, written by a renovate "pin dependencies" run
|
|
39
|
+
that treated a compatibility range as a version to pin. Every install
|
|
40
|
+
on any other Node emitted an engine warning, and an `engine-strict` install failed outright. Both
|
|
41
|
+
now declare `>=20.6.0`, the version the code actually requires, and renovate is configured to
|
|
42
|
+
leave `engines` alone so the fix survives the next cycle.
|
|
43
|
+
|
|
44
|
+
- [#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.
|
|
45
|
+
|
|
46
|
+
`watchers: ['logs']` can be set in `config/telescope.ts` (where it also accepts a `logs`
|
|
47
|
+
options block) and in `config/telescope_watchers.ts`. With both set, the second watcher to
|
|
48
|
+
boot silently did nothing — and then unteed the FIRST watcher's tap on shutdown, so the
|
|
49
|
+
logger was left half-instrumented. It now detects that the logger is already tapped, warns
|
|
50
|
+
once naming both config keys, and stays fully inert: it records nothing and its `stop()`
|
|
51
|
+
restores only what it teed itself.
|
|
52
|
+
|
|
53
|
+
- [#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
|
|
54
|
+
`0.4.0` regardless of the installed version; it now reads the package's own `VERSION`, which
|
|
55
|
+
the release pipeline keeps in lockstep with `package.json`.
|
|
56
|
+
|
|
57
|
+
- [#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.
|
|
58
|
+
|
|
59
|
+
Every config stub the package publishes — `telescope.stub`, `telescope_watchers.stub`,
|
|
60
|
+
`telescope_ui.stub`, `telescope_ai.stub`, `telescope_alerts.stub`, `telescope_mcp.stub` and
|
|
61
|
+
`telescope_cpu_profiling.stub` — was a zero-byte file in the published tarball, so
|
|
62
|
+
`node ace add @adonis-agora/telescope` wrote an EMPTY `config/telescope.ts` (and an empty file
|
|
63
|
+
for each feature you selected) into your app. Only the migration stub had content.
|
|
64
|
+
|
|
65
|
+
The stubs are rebuilt from the current config surface, including everything that landed since
|
|
66
|
+
they were lost: the `logs` watcher and its `logs` block, `diagnostics.exclude` /
|
|
67
|
+
`diagnostics.recordClaimed`, `requestCapture`, `redact.perType`, `sampling`, `nPlusOne`, `pulse`,
|
|
68
|
+
`clientErrors`, `dashboardAuth`, `cpuProfiling.armEnabled`, `queueActions`, `queueManager`, the
|
|
69
|
+
`every-exception` and `metric-threshold` alert rules, `alerts.geoLookup`, and the whole
|
|
70
|
+
`telescope_cpu_profiling` config. A test now fails the build if any shipped stub is empty, lacks
|
|
71
|
+
its `exports(...)` header, or carries a backtick in its body — the defect that emptied them.
|
|
72
|
+
|
|
3
73
|
## 0.8.0
|
|
4
74
|
|
|
5
75
|
### 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;
|
|
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
|
-
|
|
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;
|
|
1
|
+
{"version":3,"file":"telescope_mcp_provider.js","sourceRoot":"","sources":["../../providers/telescope_mcp_provider.ts"],"names":[],"mappings":"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"}
|
package/dist/src/ai/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Keep in sync with this package's `version` in package.json. */
|
|
2
|
-
export declare const VERSION = "0.8.
|
|
2
|
+
export declare const VERSION = "0.8.2";
|
|
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';
|
package/dist/src/ai/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Keep in sync with this package's `version` in package.json. */
|
|
2
|
-
export declare const VERSION = "0.8.
|
|
2
|
+
export declare const VERSION = "0.8.2";
|
|
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';
|
package/dist/src/alerts/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.
|
|
2
|
+
export const VERSION = '0.8.2';
|
|
3
3
|
// — channels —
|
|
4
4
|
export { consoleChannel, customChannel, slackChannel, webhookChannel, } from './alert_channel.js';
|
|
5
5
|
// — slack formatting —
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Keep in sync with this package's `version` in package.json. */
|
|
2
|
-
export declare const VERSION = "0.8.
|
|
2
|
+
export declare const VERSION = "0.8.2";
|
|
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.
|
|
2
|
+
export const VERSION = '0.8.2';
|
|
3
3
|
// — entry model —
|
|
4
4
|
export { EntryType, isBatchOrigin } from './entry.js';
|
|
5
5
|
export { InMemoryTelescopeStore } from './stores/memory.js';
|
package/dist/src/mcp/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Keep in sync with this package's `version` in package.json. */
|
|
2
|
-
export declare const VERSION = "0.8.
|
|
2
|
+
export declare const VERSION = "0.8.2";
|
|
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';
|
package/dist/src/mcp/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.
|
|
2
|
+
export const VERSION = '0.8.2';
|
|
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.
|
|
2
|
+
export declare const VERSION = "0.8.2";
|
|
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.
|
|
2
|
+
export const VERSION = '0.8.2';
|
|
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
|
|
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. */
|
package/dist/src/ui/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Keep in sync with this package's `version` in package.json. */
|
|
2
|
-
export declare const VERSION = "0.8.
|
|
2
|
+
export declare const VERSION = "0.8.2";
|
|
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';
|
package/dist/src/ui/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.
|
|
2
|
+
export const VERSION = '0.8.2';
|
|
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.
|
|
2
|
+
export declare const VERSION = "0.8.2";
|
|
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.
|
|
2
|
+
export const VERSION = '0.8.2';
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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;
|
|
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
|
-
/**
|
|
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'
|
|
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
|
-
/**
|
|
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
|
|
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":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAoB,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,iFAAiF;AACjF,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAU,CAAC;AAsCxF;gDACgD;AAChD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;AAO1D;;;;GAIG;AACH,IAAI,SAAS,GAAG,KAAK,CAAC;AAEtB;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,OAAO,WAAW;IACb,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC;IACb,aAAa,CAAS;IACtB,SAAS,CAAoB;IACtC,MAAM,GAAsB,IAAI,CAAC;
|
|
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.
|
|
3
|
+
"version": "0.8.2",
|
|
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": {
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"@adonisjs/lucid": "^22.4.0",
|
|
110
110
|
"@adonisjs/mail": "^10.2.0",
|
|
111
111
|
"@adonisjs/cache": "^2.1.0",
|
|
112
|
-
"@anthropic-ai/sdk": "
|
|
112
|
+
"@anthropic-ai/sdk": ">=0.32.0 <1.0.0",
|
|
113
113
|
"cron-parser": "^4.0.0 || ^5.0.0"
|
|
114
114
|
},
|
|
115
115
|
"peerDependenciesMeta": {
|
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
"vitest": "3.2.7"
|
|
144
144
|
},
|
|
145
145
|
"engines": {
|
|
146
|
-
"node": "
|
|
146
|
+
"node": ">=20.6.0"
|
|
147
147
|
},
|
|
148
148
|
"keywords": [
|
|
149
149
|
"adonisjs",
|