@ory/argus 0.13.9 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -45
- package/assets/commands/temporal-up.md +1 -1
- package/assets/skills/auth-setup/SKILL.md +1 -1
- package/assets/skills/local-dev/SKILL.md +17 -7
- package/assets/skills/ory-build-agent/SKILL.md +43 -97
- package/assets/skills/ory-e2b-sandbox/SKILL.md +18 -18
- package/assets/skills/ory-temporal-worker/SKILL.md +38 -42
- package/assets/skills/permissions-onboarding/SKILL.md +131 -104
- package/dist/adapters.d.ts +93 -30
- package/dist/adapters.js +464 -136
- package/dist/agent-auth.d.ts +258 -68
- package/dist/agent-auth.js +998 -202
- package/dist/auth-store.d.ts +37 -2
- package/dist/auth-store.js +37 -3
- package/dist/auth.d.ts +40 -4
- package/dist/auth.js +247 -19
- package/dist/bash-parser.d.ts +98 -0
- package/dist/bash-parser.js +396 -0
- package/dist/branding.d.ts +128 -0
- package/dist/branding.js +151 -0
- package/dist/build-info.json +4 -4
- package/dist/cli-invocation.d.ts +1 -1
- package/dist/cli-invocation.js +2 -1
- package/dist/cli.d.ts +20 -29
- package/dist/cli.js +271 -278
- package/dist/client.d.ts +175 -138
- package/dist/client.js +672 -391
- package/dist/config.d.ts +249 -57
- package/dist/config.js +486 -62
- package/dist/context.d.ts +10 -0
- package/dist/context.js +21 -0
- package/dist/contract-suite.d.ts +8 -8
- package/dist/contract-suite.js +88 -69
- package/dist/denial.d.ts +36 -3
- package/dist/denial.js +79 -10
- package/dist/event-reporter.d.ts +77 -0
- package/dist/event-reporter.js +776 -0
- package/dist/external-registrations-main.d.ts +10 -0
- package/dist/external-registrations-main.js +38 -0
- package/dist/external-registrations.d.ts +79 -0
- package/dist/external-registrations.js +188 -0
- package/dist/help-cli.d.ts +39 -0
- package/dist/help-cli.js +55 -0
- package/dist/hook-timeout.d.ts +64 -0
- package/dist/hook-timeout.js +88 -0
- package/dist/index.d.ts +31 -19
- package/dist/index.js +182 -31
- package/dist/lifecycle.d.ts +3 -3
- package/dist/lifecycle.js +38 -6
- package/dist/local/cli.js +11 -6
- package/dist/local/configs.d.ts +74 -18
- package/dist/local/configs.js +291 -84
- package/dist/local/health.d.ts +14 -0
- package/dist/local/health.js +50 -4
- package/dist/local/index.d.ts +2 -2
- package/dist/local/index.js +24 -10
- package/dist/local/manager.d.ts +20 -1
- package/dist/local/manager.js +160 -39
- package/dist/local/ports.d.ts +158 -0
- package/dist/local/ports.js +443 -0
- package/dist/local/seed.d.ts +22 -25
- package/dist/local/seed.js +88 -56
- package/dist/logger.d.ts +54 -25
- package/dist/logger.js +329 -63
- package/dist/mcp.d.ts +2 -2
- package/dist/mcp.js +10 -5
- package/dist/mirror-bootstrap.d.ts +48 -0
- package/dist/mirror-bootstrap.js +254 -0
- package/dist/opl.d.ts +289 -0
- package/dist/opl.js +446 -0
- package/dist/permission-mode.d.ts +87 -0
- package/dist/permission-mode.js +307 -0
- package/dist/permissions-cli.d.ts +13 -49
- package/dist/permissions-cli.js +154 -348
- package/dist/permissions.d.ts +148 -38
- package/dist/permissions.js +591 -45
- package/dist/post-install.d.ts +33 -0
- package/dist/post-install.js +127 -0
- package/dist/read-credential.d.ts +65 -0
- package/dist/read-credential.js +86 -0
- package/dist/registry/cli.js +5 -2
- package/dist/registry/config.d.ts +0 -17
- package/dist/registry/config.js +0 -23
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/index.js +2 -2
- package/dist/registry/manager.d.ts +4 -21
- package/dist/registry/manager.js +83 -55
- package/dist/runtime-credential.d.ts +140 -0
- package/dist/runtime-credential.js +572 -0
- package/dist/runtime.d.ts +408 -0
- package/dist/runtime.js +748 -0
- package/dist/setup.d.ts +23 -28
- package/dist/setup.js +57 -84
- package/dist/status-cli.d.ts +29 -13
- package/dist/status-cli.js +124 -144
- package/dist/status-data.d.ts +195 -0
- package/dist/status-data.js +333 -0
- package/dist/status-system.d.ts +24 -0
- package/dist/status-system.js +56 -0
- package/dist/subject.d.ts +126 -20
- package/dist/subject.js +215 -30
- package/dist/testing.d.ts +74 -38
- package/dist/testing.js +185 -68
- package/dist/tool-catalog.d.ts +53 -11
- package/dist/tool-catalog.js +164 -13
- package/dist/tool-metadata.d.ts +7 -6
- package/dist/tool-metadata.js +6 -5
- package/dist/types.d.ts +11 -1
- package/dist/uninstall.d.ts +74 -19
- package/dist/uninstall.js +224 -49
- package/dist/user-login.d.ts +22 -16
- package/dist/user-login.js +67 -96
- package/dist/watch-cli.d.ts +6 -0
- package/dist/watch-cli.js +217 -0
- package/package.json +3 -11
- package/dist/dev.d.ts +0 -103
- package/dist/dev.js +0 -584
- package/dist/interactive-setup.d.ts +0 -165
- package/dist/interactive-setup.js +0 -1546
- package/dist/local/jaeger-main.d.ts +0 -13
- package/dist/local/jaeger-main.js +0 -85
- package/dist/local/jaeger.d.ts +0 -50
- package/dist/local/jaeger.js +0 -162
- package/dist/otel/exporter.d.ts +0 -17
- package/dist/otel/exporter.js +0 -12
- package/dist/otel/index.d.ts +0 -2
- package/dist/otel/index.js +0 -8
- package/dist/otel/otlp.d.ts +0 -103
- package/dist/otel/otlp.js +0 -385
- package/dist/tracer.d.ts +0 -190
- package/dist/tracer.js +0 -481
- package/dist/watch-sandbox.d.ts +0 -9
- package/dist/watch-sandbox.js +0 -81
package/dist/otel/otlp.js
DELETED
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* OTLP exporter — SDK-backed.
|
|
4
|
-
*
|
|
5
|
-
* Bridges our internal `TraceSpan` records into the official OpenTelemetry
|
|
6
|
-
* SDK exporters from `@opentelemetry/exporter-trace-otlp-http` and
|
|
7
|
-
* `@opentelemetry/exporter-trace-otlp-proto`. Each completed `TraceSpan`
|
|
8
|
-
* is converted to a `ReadableSpan` shape and handed to the SDK exporter,
|
|
9
|
-
* which serializes (JSON or protobuf) and POSTs to an OTLP HTTP endpoint.
|
|
10
|
-
*
|
|
11
|
-
* Standard OTel env vars consumed by `otlpExporterFromEnv()`. Each one has
|
|
12
|
-
* an `ORY_OTLP_*`-prefixed alias that is consulted as a fallback when the
|
|
13
|
-
* standard name is unset. Some harnesses (notably Claude Code) sanitize the
|
|
14
|
-
* env passed to hook subprocesses and drop every `OTEL_*` var, so the dev
|
|
15
|
-
* launcher mirrors each setting under the Ory prefix to survive the strip.
|
|
16
|
-
*
|
|
17
|
-
* Standard name Ory-prefixed fallback
|
|
18
|
-
* ───────────────────────────────────── ─────────────────────────────────
|
|
19
|
-
* OTEL_EXPORTER_OTLP_ENDPOINT ORY_OTLP_ENDPOINT
|
|
20
|
-
* OTEL_EXPORTER_OTLP_TRACES_ENDPOINT ORY_OTLP_TRACES_ENDPOINT
|
|
21
|
-
* OTEL_EXPORTER_OTLP_HEADERS ORY_OTLP_HEADERS
|
|
22
|
-
* OTEL_EXPORTER_OTLP_TRACES_HEADERS ORY_OTLP_TRACES_HEADERS
|
|
23
|
-
* OTEL_EXPORTER_OTLP_PROTOCOL ORY_OTLP_PROTOCOL
|
|
24
|
-
* OTEL_EXPORTER_OTLP_TRACES_PROTOCOL ORY_OTLP_TRACES_PROTOCOL
|
|
25
|
-
* OTEL_SERVICE_NAME ORY_OTLP_SERVICE_NAME
|
|
26
|
-
* OTEL_RESOURCE_ATTRIBUTES ORY_OTLP_RESOURCE_ATTRIBUTES
|
|
27
|
-
*
|
|
28
|
-
* Failures are swallowed (callers receive a resolved Promise) so trace
|
|
29
|
-
* export can never break the agent session. Transport errors surface
|
|
30
|
-
* through the `onError` callback.
|
|
31
|
-
*/
|
|
32
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.OtlpExporter = void 0;
|
|
34
|
-
exports.otlpExporterFromEnv = otlpExporterFromEnv;
|
|
35
|
-
exports.readEnvWithAlias = readEnvWithAlias;
|
|
36
|
-
exports.parseKeyValueList = parseKeyValueList;
|
|
37
|
-
exports.toReadableSpan = toReadableSpan;
|
|
38
|
-
const api_1 = require("@opentelemetry/api");
|
|
39
|
-
const core_1 = require("@opentelemetry/core");
|
|
40
|
-
const resources_1 = require("@opentelemetry/resources");
|
|
41
|
-
const exporter_trace_otlp_http_1 = require("@opentelemetry/exporter-trace-otlp-http");
|
|
42
|
-
const exporter_trace_otlp_proto_1 = require("@opentelemetry/exporter-trace-otlp-proto");
|
|
43
|
-
const TRACES_PATH = "/v1/traces";
|
|
44
|
-
const SCOPE = {
|
|
45
|
-
name: "ory-agent-plugins",
|
|
46
|
-
};
|
|
47
|
-
/**
|
|
48
|
-
* OTLP exporter that delegates wire-format serialization and HTTP transport
|
|
49
|
-
* to the official `@opentelemetry/exporter-trace-otlp-*` SDK exporters.
|
|
50
|
-
*/
|
|
51
|
-
class OtlpExporter {
|
|
52
|
-
endpoint;
|
|
53
|
-
protocol;
|
|
54
|
-
headers;
|
|
55
|
-
resource;
|
|
56
|
-
delegate;
|
|
57
|
-
onError;
|
|
58
|
-
inFlight = new Set();
|
|
59
|
-
constructor(opts) {
|
|
60
|
-
this.endpoint = opts.endpoint;
|
|
61
|
-
this.protocol = opts.protocol ?? "http/protobuf";
|
|
62
|
-
this.headers = { ...(opts.headers ?? {}) };
|
|
63
|
-
this.resource = (0, resources_1.resourceFromAttributes)(stripUndefined(opts.resource ?? {}));
|
|
64
|
-
this.onError = opts.onError ?? (() => undefined);
|
|
65
|
-
this.delegate =
|
|
66
|
-
opts.sdkExporter ??
|
|
67
|
-
buildSdkExporter(this.endpoint, this.protocol, this.headers, opts.timeoutMs);
|
|
68
|
-
}
|
|
69
|
-
export(spans) {
|
|
70
|
-
if (spans.length === 0)
|
|
71
|
-
return Promise.resolve();
|
|
72
|
-
const readables = spans.map((s) => toReadableSpan(s, this.resource));
|
|
73
|
-
const promise = new Promise((resolve) => {
|
|
74
|
-
try {
|
|
75
|
-
this.delegate.export(readables, (result) => {
|
|
76
|
-
if (result.code !== core_1.ExportResultCode.SUCCESS) {
|
|
77
|
-
this.onError(result.error ?? new Error("OTLP export failed"));
|
|
78
|
-
}
|
|
79
|
-
resolve();
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
catch (err) {
|
|
83
|
-
// Defensive — SDK exporter contract says export() must not throw,
|
|
84
|
-
// but we honor our own contract regardless.
|
|
85
|
-
this.onError(err);
|
|
86
|
-
resolve();
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
this.inFlight.add(promise);
|
|
90
|
-
promise.finally(() => this.inFlight.delete(promise));
|
|
91
|
-
return promise;
|
|
92
|
-
}
|
|
93
|
-
async shutdown() {
|
|
94
|
-
// Drain in-flight exports first. Subprocess hooks (claude-code, codex,
|
|
95
|
-
// gemini-cli) call process.exit() the instant they hand back stdout —
|
|
96
|
-
// without this drain the underlying HTTP request is killed mid-flight
|
|
97
|
-
// and spans never reach the collector even though the NDJSON file
|
|
98
|
-
// already contains them.
|
|
99
|
-
if (this.inFlight.size > 0) {
|
|
100
|
-
await Promise.allSettled([...this.inFlight]);
|
|
101
|
-
}
|
|
102
|
-
try {
|
|
103
|
-
await this.delegate.shutdown();
|
|
104
|
-
}
|
|
105
|
-
catch (err) {
|
|
106
|
-
this.onError(err);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
exports.OtlpExporter = OtlpExporter;
|
|
111
|
-
function buildSdkExporter(endpoint, protocol, headers, timeoutMs) {
|
|
112
|
-
const config = {
|
|
113
|
-
url: endpoint,
|
|
114
|
-
headers,
|
|
115
|
-
timeoutMillis: timeoutMs ?? 5_000,
|
|
116
|
-
};
|
|
117
|
-
return protocol === "http/json"
|
|
118
|
-
? new exporter_trace_otlp_http_1.OTLPTraceExporter(config)
|
|
119
|
-
: new exporter_trace_otlp_proto_1.OTLPTraceExporter(config);
|
|
120
|
-
}
|
|
121
|
-
// ─── Factory ───────────────────────────────────────────────────────
|
|
122
|
-
/**
|
|
123
|
-
* Build an OtlpExporter from process env. Returns undefined when no
|
|
124
|
-
* endpoint is configured or the requested protocol is unsupported.
|
|
125
|
-
*/
|
|
126
|
-
function otlpExporterFromEnv(opts) {
|
|
127
|
-
const env = opts.env ?? process.env;
|
|
128
|
-
const endpoint = resolveEndpoint(env);
|
|
129
|
-
if (!endpoint)
|
|
130
|
-
return undefined;
|
|
131
|
-
const protocol = resolveProtocol(env, opts.onError);
|
|
132
|
-
if (!protocol)
|
|
133
|
-
return undefined;
|
|
134
|
-
const headers = mergeHeaders(parseKeyValueList(readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_HEADERS")), parseKeyValueList(readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_TRACES_HEADERS")));
|
|
135
|
-
const resource = {
|
|
136
|
-
"service.name": readEnvWithAlias(env, "OTEL_SERVICE_NAME") ??
|
|
137
|
-
`ory-agent-plugin-${opts.harness}`,
|
|
138
|
-
"service.namespace": "ory.agent_plugins",
|
|
139
|
-
"ory.harness": opts.harness,
|
|
140
|
-
"process.pid": process.pid,
|
|
141
|
-
"process.runtime.name": "nodejs",
|
|
142
|
-
"process.runtime.version": process.version,
|
|
143
|
-
};
|
|
144
|
-
if (opts.hostname)
|
|
145
|
-
resource["host.name"] = opts.hostname;
|
|
146
|
-
if (opts.user)
|
|
147
|
-
resource["host.user"] = opts.user;
|
|
148
|
-
if (opts.pluginVersion)
|
|
149
|
-
resource["service.version"] = opts.pluginVersion;
|
|
150
|
-
if (opts.cwd)
|
|
151
|
-
resource["process.cwd"] = opts.cwd;
|
|
152
|
-
if (opts.gitBranch)
|
|
153
|
-
resource["ory.git.branch"] = opts.gitBranch;
|
|
154
|
-
if (opts.gitCommit)
|
|
155
|
-
resource["ory.git.commit"] = opts.gitCommit;
|
|
156
|
-
for (const [k, v] of Object.entries(parseKeyValueList(readEnvWithAlias(env, "OTEL_RESOURCE_ATTRIBUTES")))) {
|
|
157
|
-
resource[k] = v;
|
|
158
|
-
}
|
|
159
|
-
return new OtlpExporter({
|
|
160
|
-
endpoint,
|
|
161
|
-
protocol,
|
|
162
|
-
headers,
|
|
163
|
-
resource,
|
|
164
|
-
onError: opts.onError,
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
function resolveEndpoint(env) {
|
|
168
|
-
// ORY_OTLP_*-prefixed aliases survive harnesses (e.g. Claude Code) that
|
|
169
|
-
// sanitize the env passed to hook subprocesses and drop OTEL_*-prefixed
|
|
170
|
-
// vars. The standard OTel name still wins when present.
|
|
171
|
-
const tracesUrl = readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT");
|
|
172
|
-
if (tracesUrl)
|
|
173
|
-
return tracesUrl;
|
|
174
|
-
const base = readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_ENDPOINT");
|
|
175
|
-
if (!base)
|
|
176
|
-
return undefined;
|
|
177
|
-
return base.replace(/\/+$/, "") + TRACES_PATH;
|
|
178
|
-
}
|
|
179
|
-
function resolveProtocol(env, onError) {
|
|
180
|
-
const raw = (readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL") ??
|
|
181
|
-
readEnvWithAlias(env, "OTEL_EXPORTER_OTLP_PROTOCOL") ??
|
|
182
|
-
"http/protobuf")
|
|
183
|
-
.trim()
|
|
184
|
-
.toLowerCase();
|
|
185
|
-
if (raw === "http/protobuf" || raw === "http/json")
|
|
186
|
-
return raw;
|
|
187
|
-
onError?.(new Error(`OTEL_EXPORTER_OTLP_PROTOCOL=${raw} not supported (only http/protobuf and http/json). Skipping OTel export.`));
|
|
188
|
-
return undefined;
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* Standard OTel env var name → Ory-prefixed fallback. Standard wins when set;
|
|
192
|
-
* the alias is consulted only when the standard name is empty/missing. The
|
|
193
|
-
* historical `ORY_OTLP_ENDPOINT` alias for `OTEL_EXPORTER_OTLP_ENDPOINT` is
|
|
194
|
-
* preserved verbatim for compatibility with existing dev-launcher envs.
|
|
195
|
-
*/
|
|
196
|
-
const ORY_ENV_ALIAS = {
|
|
197
|
-
OTEL_EXPORTER_OTLP_ENDPOINT: "ORY_OTLP_ENDPOINT",
|
|
198
|
-
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: "ORY_OTLP_TRACES_ENDPOINT",
|
|
199
|
-
OTEL_EXPORTER_OTLP_HEADERS: "ORY_OTLP_HEADERS",
|
|
200
|
-
OTEL_EXPORTER_OTLP_TRACES_HEADERS: "ORY_OTLP_TRACES_HEADERS",
|
|
201
|
-
OTEL_EXPORTER_OTLP_PROTOCOL: "ORY_OTLP_PROTOCOL",
|
|
202
|
-
OTEL_EXPORTER_OTLP_TRACES_PROTOCOL: "ORY_OTLP_TRACES_PROTOCOL",
|
|
203
|
-
OTEL_SERVICE_NAME: "ORY_OTLP_SERVICE_NAME",
|
|
204
|
-
OTEL_RESOURCE_ATTRIBUTES: "ORY_OTLP_RESOURCE_ATTRIBUTES",
|
|
205
|
-
};
|
|
206
|
-
/**
|
|
207
|
-
* Read an OTel env var, falling back to its `ORY_OTLP_*`-prefixed alias when
|
|
208
|
-
* the standard name is unset. Trims whitespace and treats empty strings as
|
|
209
|
-
* absent so a propagated-but-blank var doesn't shadow the alias.
|
|
210
|
-
*/
|
|
211
|
-
function readEnvWithAlias(env, standardName) {
|
|
212
|
-
const primary = env[standardName]?.trim();
|
|
213
|
-
if (primary)
|
|
214
|
-
return primary;
|
|
215
|
-
const aliasName = ORY_ENV_ALIAS[standardName];
|
|
216
|
-
if (!aliasName)
|
|
217
|
-
return undefined;
|
|
218
|
-
const alias = env[aliasName]?.trim();
|
|
219
|
-
return alias || undefined;
|
|
220
|
-
}
|
|
221
|
-
// ─── Env parsing helpers ───────────────────────────────────────────
|
|
222
|
-
/**
|
|
223
|
-
* Parse the OTel `k=v,k2=v2` env-var format. Values may be URL-encoded.
|
|
224
|
-
*/
|
|
225
|
-
function parseKeyValueList(raw) {
|
|
226
|
-
const out = {};
|
|
227
|
-
if (!raw)
|
|
228
|
-
return out;
|
|
229
|
-
for (const pair of raw.split(",")) {
|
|
230
|
-
const trimmed = pair.trim();
|
|
231
|
-
if (!trimmed)
|
|
232
|
-
continue;
|
|
233
|
-
const eq = trimmed.indexOf("=");
|
|
234
|
-
if (eq <= 0)
|
|
235
|
-
continue;
|
|
236
|
-
const key = trimmed.slice(0, eq).trim();
|
|
237
|
-
const value = trimmed.slice(eq + 1).trim();
|
|
238
|
-
if (!key)
|
|
239
|
-
continue;
|
|
240
|
-
out[key] = safeDecodeURIComponent(value);
|
|
241
|
-
}
|
|
242
|
-
return out;
|
|
243
|
-
}
|
|
244
|
-
function safeDecodeURIComponent(value) {
|
|
245
|
-
try {
|
|
246
|
-
return decodeURIComponent(value);
|
|
247
|
-
}
|
|
248
|
-
catch {
|
|
249
|
-
return value;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
function mergeHeaders(...sources) {
|
|
253
|
-
const out = {};
|
|
254
|
-
for (const src of sources) {
|
|
255
|
-
for (const [k, v] of Object.entries(src)) {
|
|
256
|
-
out[k.toLowerCase()] = v;
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return out;
|
|
260
|
-
}
|
|
261
|
-
// ─── TraceSpan → ReadableSpan conversion ───────────────────────────
|
|
262
|
-
/**
|
|
263
|
-
* Convert our internal `TraceSpan` record to an OTel SDK `ReadableSpan`.
|
|
264
|
-
* Exported for tests; the OTLP exporters consume this shape directly.
|
|
265
|
-
*/
|
|
266
|
-
function toReadableSpan(span, resource) {
|
|
267
|
-
// OTLP wire format expects 32-hex traceId / 16-hex spanId. Our internal
|
|
268
|
-
// IDs are shorter (hashed session prefix + random suffix), so pad with
|
|
269
|
-
// leading zeros to canonical width.
|
|
270
|
-
const traceId = padHex(span.traceId, 32);
|
|
271
|
-
const spanId = padHex(span.spanId, 16);
|
|
272
|
-
const ctx = {
|
|
273
|
-
traceId,
|
|
274
|
-
spanId,
|
|
275
|
-
traceFlags: 1, // sampled
|
|
276
|
-
isRemote: false,
|
|
277
|
-
};
|
|
278
|
-
const parentSpanContext = span.parentSpanId
|
|
279
|
-
? {
|
|
280
|
-
traceId,
|
|
281
|
-
spanId: padHex(span.parentSpanId, 16),
|
|
282
|
-
traceFlags: 1,
|
|
283
|
-
isRemote: false,
|
|
284
|
-
}
|
|
285
|
-
: undefined;
|
|
286
|
-
const startTime = isoToHrTime(span.startedAt);
|
|
287
|
-
const endTime = isoToHrTime(span.endedAt);
|
|
288
|
-
const attributes = {
|
|
289
|
-
"ory.event": span.event,
|
|
290
|
-
"ory.span.status": span.status,
|
|
291
|
-
"ory.duration_ms": span.durationMs,
|
|
292
|
-
};
|
|
293
|
-
if (span.sessionId)
|
|
294
|
-
attributes["ory.session_id"] = span.sessionId;
|
|
295
|
-
for (const [k, v] of Object.entries(flattenAttributes(span.attributes ?? {}))) {
|
|
296
|
-
attributes[k] = v;
|
|
297
|
-
}
|
|
298
|
-
return {
|
|
299
|
-
name: span.event,
|
|
300
|
-
kind: api_1.SpanKind.INTERNAL,
|
|
301
|
-
spanContext: () => ctx,
|
|
302
|
-
parentSpanContext,
|
|
303
|
-
startTime,
|
|
304
|
-
endTime,
|
|
305
|
-
status: toOtelStatus(span.status),
|
|
306
|
-
attributes,
|
|
307
|
-
links: [],
|
|
308
|
-
events: [],
|
|
309
|
-
duration: hrTimeSubtract(endTime, startTime),
|
|
310
|
-
ended: true,
|
|
311
|
-
resource,
|
|
312
|
-
instrumentationScope: SCOPE,
|
|
313
|
-
droppedAttributesCount: 0,
|
|
314
|
-
droppedEventsCount: 0,
|
|
315
|
-
droppedLinksCount: 0,
|
|
316
|
-
};
|
|
317
|
-
}
|
|
318
|
-
function toOtelStatus(status) {
|
|
319
|
-
switch (status) {
|
|
320
|
-
case "ok":
|
|
321
|
-
return { code: api_1.SpanStatusCode.OK };
|
|
322
|
-
case "error":
|
|
323
|
-
return { code: api_1.SpanStatusCode.ERROR, message: "error" };
|
|
324
|
-
case "denied":
|
|
325
|
-
return { code: api_1.SpanStatusCode.ERROR, message: "denied" };
|
|
326
|
-
case "skipped":
|
|
327
|
-
default:
|
|
328
|
-
return { code: api_1.SpanStatusCode.UNSET };
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
function isoToHrTime(iso) {
|
|
332
|
-
const ms = Date.parse(iso);
|
|
333
|
-
if (!Number.isFinite(ms))
|
|
334
|
-
return [0, 0];
|
|
335
|
-
const seconds = Math.trunc(ms / 1000);
|
|
336
|
-
const nanos = (ms - seconds * 1000) * 1_000_000;
|
|
337
|
-
return [seconds, nanos];
|
|
338
|
-
}
|
|
339
|
-
function hrTimeSubtract(a, b) {
|
|
340
|
-
let sec = a[0] - b[0];
|
|
341
|
-
let nanos = a[1] - b[1];
|
|
342
|
-
if (nanos < 0) {
|
|
343
|
-
sec -= 1;
|
|
344
|
-
nanos += 1_000_000_000;
|
|
345
|
-
}
|
|
346
|
-
if (sec < 0) {
|
|
347
|
-
return [0, 0];
|
|
348
|
-
}
|
|
349
|
-
return [sec, nanos];
|
|
350
|
-
}
|
|
351
|
-
function padHex(hex, length) {
|
|
352
|
-
const lower = hex.toLowerCase().replace(/[^0-9a-f]/g, "");
|
|
353
|
-
if (lower.length >= length)
|
|
354
|
-
return lower.slice(-length);
|
|
355
|
-
return lower.padStart(length, "0");
|
|
356
|
-
}
|
|
357
|
-
function flattenAttributes(attrs) {
|
|
358
|
-
const out = {};
|
|
359
|
-
for (const [key, value] of Object.entries(attrs)) {
|
|
360
|
-
if (value === null || value === undefined)
|
|
361
|
-
continue;
|
|
362
|
-
if (typeof value === "string" ||
|
|
363
|
-
typeof value === "number" ||
|
|
364
|
-
typeof value === "boolean") {
|
|
365
|
-
out[key] = value;
|
|
366
|
-
continue;
|
|
367
|
-
}
|
|
368
|
-
try {
|
|
369
|
-
out[key] = JSON.stringify(value);
|
|
370
|
-
}
|
|
371
|
-
catch {
|
|
372
|
-
/* skip un-serializable values */
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
return out;
|
|
376
|
-
}
|
|
377
|
-
function stripUndefined(source) {
|
|
378
|
-
const out = {};
|
|
379
|
-
for (const [k, v] of Object.entries(source)) {
|
|
380
|
-
if (v === undefined)
|
|
381
|
-
continue;
|
|
382
|
-
out[k] = v;
|
|
383
|
-
}
|
|
384
|
-
return out;
|
|
385
|
-
}
|
package/dist/tracer.d.ts
DELETED
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Distributed tracing for Ory agent plugin hooks.
|
|
3
|
-
*
|
|
4
|
-
* Replaces simple audit logging with structured, correlated trace spans.
|
|
5
|
-
* Every plugin resolves to the same unified TraceEvent classification —
|
|
6
|
-
* there is no plugin-specific output.
|
|
7
|
-
*
|
|
8
|
-
* Key concepts:
|
|
9
|
-
* - **TraceEvent**: A canonical event type (e.g. "tool.invoke", "permission.check").
|
|
10
|
-
* - **TraceSpan**: A completed unit of work with timing and status.
|
|
11
|
-
* - **ActiveSpan**: An in-flight span that must be `.end()`-ed.
|
|
12
|
-
* - **Tracer**: EventEmitter that collects spans, writes NDJSON, and
|
|
13
|
-
* supports live watching via the "span" event.
|
|
14
|
-
*
|
|
15
|
-
* Trace correlation: call `tracer.setContext()` with a traceId derived
|
|
16
|
-
* from the session ID so all spans within the same agent session share
|
|
17
|
-
* a single trace, even across separate hook process invocations.
|
|
18
|
-
*/
|
|
19
|
-
import { EventEmitter } from "node:events";
|
|
20
|
-
import type { SpanExporter } from "./otel/exporter.js";
|
|
21
|
-
export type TraceEvent = "session.start" | "session.end" | "session.verify" | "user.auth" | "user.prompt" | "user.interaction" | "agent.auth" | "oauth2.introspect" | "oauth2.login" | "oauth2.refresh" | "permission.check" | "permission.batch_check" | "permission.observe_deny" | "tool.invoke" | "tool.complete" | "tool.block" | "tool.fail" | "turn.stop" | "subagent.start" | "subagent.stop" | "notification" | "compaction" | "relationship.create" | "relationship.delete" | "relationship.patch" | "hook.receive" | "hook.passthrough" | "config.resolve";
|
|
22
|
-
export type SpanStatus = "ok" | "error" | "denied" | "skipped";
|
|
23
|
-
export interface TraceSpan {
|
|
24
|
-
traceId: string;
|
|
25
|
-
spanId: string;
|
|
26
|
-
parentSpanId?: string;
|
|
27
|
-
event: TraceEvent;
|
|
28
|
-
status: SpanStatus;
|
|
29
|
-
startedAt: string;
|
|
30
|
-
endedAt: string;
|
|
31
|
-
durationMs: number;
|
|
32
|
-
harness: string;
|
|
33
|
-
hostname: string;
|
|
34
|
-
user: string;
|
|
35
|
-
pid: number;
|
|
36
|
-
cwd: string;
|
|
37
|
-
pluginVersion: string;
|
|
38
|
-
nodeVersion: string;
|
|
39
|
-
/** Git branch of `cwd` if it is a git working tree. */
|
|
40
|
-
gitBranch?: string;
|
|
41
|
-
/** Short git SHA of HEAD in `cwd` if it is a git working tree. */
|
|
42
|
-
gitCommit?: string;
|
|
43
|
-
sessionId?: string;
|
|
44
|
-
attributes?: Record<string, unknown>;
|
|
45
|
-
}
|
|
46
|
-
export interface SpanOptions {
|
|
47
|
-
traceId?: string;
|
|
48
|
-
parentSpanId?: string;
|
|
49
|
-
sessionId?: string;
|
|
50
|
-
attributes?: Record<string, unknown>;
|
|
51
|
-
}
|
|
52
|
-
export declare class ActiveSpan {
|
|
53
|
-
readonly traceId: string;
|
|
54
|
-
readonly spanId: string;
|
|
55
|
-
readonly parentSpanId: string | undefined;
|
|
56
|
-
readonly event: TraceEvent;
|
|
57
|
-
readonly startedAt: string;
|
|
58
|
-
readonly sessionId: string | undefined;
|
|
59
|
-
private readonly startMs;
|
|
60
|
-
private _ended;
|
|
61
|
-
private readonly tracer;
|
|
62
|
-
private readonly baseAttributes;
|
|
63
|
-
/** @internal — use `tracer.startSpan()` instead. */
|
|
64
|
-
constructor(tracer: Tracer, event: TraceEvent, opts: SpanOptions & {
|
|
65
|
-
resolvedTraceId: string;
|
|
66
|
-
});
|
|
67
|
-
get ended(): boolean;
|
|
68
|
-
/**
|
|
69
|
-
* Complete the span. Returns the recorded TraceSpan.
|
|
70
|
-
*/
|
|
71
|
-
end(status: SpanStatus, attributes?: Record<string, unknown>): TraceSpan;
|
|
72
|
-
}
|
|
73
|
-
export interface TracerOptions {
|
|
74
|
-
harness: string;
|
|
75
|
-
traceFile?: string;
|
|
76
|
-
/**
|
|
77
|
-
* Optional span exporter (e.g. OTLP/HTTP). Each completed span is
|
|
78
|
-
* dispatched fire-and-forget; the tracer never awaits the export and
|
|
79
|
-
* exporter failures must not throw.
|
|
80
|
-
*/
|
|
81
|
-
exporter?: SpanExporter;
|
|
82
|
-
}
|
|
83
|
-
export interface TracerContext {
|
|
84
|
-
traceId?: string;
|
|
85
|
-
spanId?: string;
|
|
86
|
-
sessionId?: string;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Process-level metadata captured once per Tracer and emitted on every span.
|
|
90
|
-
* These values are constant for the lifetime of the process.
|
|
91
|
-
*/
|
|
92
|
-
export interface ProcessMetadata {
|
|
93
|
-
hostname: string;
|
|
94
|
-
user: string;
|
|
95
|
-
pid: number;
|
|
96
|
-
cwd: string;
|
|
97
|
-
pluginVersion: string;
|
|
98
|
-
nodeVersion: string;
|
|
99
|
-
gitBranch?: string;
|
|
100
|
-
gitCommit?: string;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Returns a record of attributes to merge into every span's attribute
|
|
104
|
-
* bag at span-end. Used by `OryAgentClient` to inject the current
|
|
105
|
-
* `userSubject` / `agentSubject` onto every span without each handler
|
|
106
|
-
* having to remember to attach them. Must not throw and should be cheap;
|
|
107
|
-
* it is invoked on every span.
|
|
108
|
-
*/
|
|
109
|
-
export type SpanAttributeEnricher = () => Record<string, unknown> | undefined;
|
|
110
|
-
export declare class Tracer extends EventEmitter {
|
|
111
|
-
readonly harness: string;
|
|
112
|
-
readonly processMetadata: ProcessMetadata;
|
|
113
|
-
private readonly traceFile;
|
|
114
|
-
private readonly _spans;
|
|
115
|
-
private _context;
|
|
116
|
-
private _exporter;
|
|
117
|
-
private _enricher;
|
|
118
|
-
constructor(opts: TracerOptions);
|
|
119
|
-
/** Backwards-compatible accessors for the most common metadata fields. */
|
|
120
|
-
get hostname(): string;
|
|
121
|
-
get user(): string;
|
|
122
|
-
/**
|
|
123
|
-
* Set the ambient context. Subsequent spans inherit traceId,
|
|
124
|
-
* parentSpanId, and sessionId from the context unless overridden.
|
|
125
|
-
*/
|
|
126
|
-
setContext(ctx: TracerContext): void;
|
|
127
|
-
clearContext(): void;
|
|
128
|
-
get context(): Readonly<TracerContext>;
|
|
129
|
-
/**
|
|
130
|
-
* Start a span that must be completed with `.end(status)`.
|
|
131
|
-
* Use this for operations with meaningful duration (API calls, etc.).
|
|
132
|
-
*/
|
|
133
|
-
startSpan(event: TraceEvent, opts?: SpanOptions): ActiveSpan;
|
|
134
|
-
/**
|
|
135
|
-
* Record a completed span in one call. Use this for instantaneous
|
|
136
|
-
* events (tool invoked, tool blocked, etc.).
|
|
137
|
-
*/
|
|
138
|
-
record(event: TraceEvent, status: SpanStatus, opts?: SpanOptions): TraceSpan;
|
|
139
|
-
/** All recorded spans in this process. */
|
|
140
|
-
spans(): ReadonlyArray<TraceSpan>;
|
|
141
|
-
/**
|
|
142
|
-
* Attach (or replace) the span exporter. Useful when constructing
|
|
143
|
-
* the tracer before env-driven configuration has resolved.
|
|
144
|
-
*/
|
|
145
|
-
setExporter(exporter: SpanExporter | null): void;
|
|
146
|
-
get exporter(): SpanExporter | null;
|
|
147
|
-
/**
|
|
148
|
-
* Install (or replace) an attribute enricher. The enricher is invoked
|
|
149
|
-
* on every span at end-time and its return value is merged into the
|
|
150
|
-
* span's attributes (with caller-supplied attributes taking precedence).
|
|
151
|
-
* Pass `null` to clear.
|
|
152
|
-
*/
|
|
153
|
-
setAttributeEnricher(enricher: SpanAttributeEnricher | null): void;
|
|
154
|
-
/** @internal — invoked by `ActiveSpan.end()`. Never throws. */
|
|
155
|
-
_callEnricher(): Record<string, unknown> | undefined;
|
|
156
|
-
/**
|
|
157
|
-
* Flush any pending exports. Call before the host process exits so
|
|
158
|
-
* the OTLP HTTP request has a chance to complete.
|
|
159
|
-
*/
|
|
160
|
-
shutdown(): Promise<void>;
|
|
161
|
-
/** @internal — called by ActiveSpan.end() */
|
|
162
|
-
_record(span: TraceSpan): void;
|
|
163
|
-
private dispatchExport;
|
|
164
|
-
private writeToFile;
|
|
165
|
-
}
|
|
166
|
-
/**
|
|
167
|
-
* Derive a stable trace ID from a session ID so all hook invocations
|
|
168
|
-
* within the same agent session correlate automatically.
|
|
169
|
-
*/
|
|
170
|
-
export declare function deriveTraceId(sessionId: string): string;
|
|
171
|
-
/**
|
|
172
|
-
* Parse a W3C traceparent header. Format:
|
|
173
|
-
* `<version>-<traceId 32hex>-<parentSpanId 16hex>-<flags 2hex>`
|
|
174
|
-
* Returns undefined for malformed or "all-zero" traceparents.
|
|
175
|
-
*/
|
|
176
|
-
export declare function parseTraceparent(raw: string | undefined): {
|
|
177
|
-
traceId: string;
|
|
178
|
-
parentSpanId: string;
|
|
179
|
-
} | undefined;
|
|
180
|
-
/**
|
|
181
|
-
* Format a single TraceSpan for terminal display.
|
|
182
|
-
*/
|
|
183
|
-
export declare function formatSpan(span: TraceSpan): string;
|
|
184
|
-
/**
|
|
185
|
-
* Watch a trace file for new spans and invoke `callback` for each one.
|
|
186
|
-
* Returns a cleanup function that stops watching.
|
|
187
|
-
*
|
|
188
|
-
* If the file does not yet exist, polling waits for it to appear.
|
|
189
|
-
*/
|
|
190
|
-
export declare function watchTraceFile(filePath: string, callback: (span: TraceSpan) => void): () => void;
|