agentglow 0.3.1 → 0.4.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/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import "./style.css";
3
- import { A as E, T as s, a as T } from "./chunks/index-D_pLQJb9.js";
3
+ import { A as E, T as s, a as T } from "./chunks/index-CxdQEVoW.js";
4
4
  export {
5
5
  E as AgentScene,
6
6
  s as THEMES,
package/dist/node.js ADDED
@@ -0,0 +1,193 @@
1
+ var E = Object.defineProperty;
2
+ var w = (t, e, s) => e in t ? E(t, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : t[e] = s;
3
+ var g = (t, e, s) => w(t, typeof e != "symbol" ? e + "" : e, s);
4
+ import { createRequire as x } from "node:module";
5
+ import { randomUUID as z } from "node:crypto";
6
+ import { trace as k } from "@opentelemetry/api";
7
+ import { BatchSpanProcessor as I, NodeTracerProvider as R } from "@opentelemetry/sdk-trace-node";
8
+ import { resourceFromAttributes as $ } from "@opentelemetry/resources";
9
+ import { OTLPTraceExporter as P } from "@opentelemetry/exporter-trace-otlp-http";
10
+ import { registerInstrumentations as T } from "@opentelemetry/instrumentation";
11
+ import { HttpInstrumentation as S } from "@opentelemetry/instrumentation-http";
12
+ import { UndiciInstrumentation as Z } from "@opentelemetry/instrumentation-undici";
13
+ const N = ["internal", "server", "client", "producer", "consumer"], O = /* @__PURE__ */ new Set([
14
+ "http.request.method",
15
+ "http.method",
16
+ "http.route",
17
+ "http.response.status_code",
18
+ "http.status_code",
19
+ "server.address",
20
+ "server.port",
21
+ "net.peer.name",
22
+ "net.peer.port",
23
+ "url.scheme",
24
+ "http.scheme",
25
+ "network.protocol.name",
26
+ "network.protocol.version",
27
+ "http.flavor",
28
+ "error.type",
29
+ "rpc.system",
30
+ "rpc.service",
31
+ "rpc.method",
32
+ "rpc.grpc.status_code",
33
+ "messaging.system",
34
+ "messaging.destination.name",
35
+ "messaging.destination_publish.name",
36
+ "messaging.operation",
37
+ "messaging.operation.type",
38
+ "messaging.operation.name",
39
+ "db.system",
40
+ "db.system.name",
41
+ "db.name",
42
+ "db.namespace",
43
+ "db.operation",
44
+ "db.operation.name",
45
+ "next.route",
46
+ "next.span_type",
47
+ "gen_ai.system",
48
+ "gen_ai.operation.name",
49
+ "gen_ai.request.model",
50
+ "gen_ai.response.model",
51
+ "gen_ai.usage.input_tokens",
52
+ "gen_ai.usage.output_tokens",
53
+ "gen_ai.tool.name"
54
+ ]), y = /header|body|cookie|authorization|query|user|email|password|token(?!s$)|secret|session|^url\.full$|^http\.url$|^http\.target$|^url\.path$|^url\.original$|^client\.|^net\.sock|^network\.peer|^net\.peer\.ip|^http\.client_ip|^db\.statement$|^db\.query\.text$|^exception\./i, L = ["url.full", "http.url"], U = ["http.target", "url.path", "url.full", "http.url"], q = /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g, D = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi, j = /(?:\+\d{1,3}[\s.-]?)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}\b|\+\d{8,15}\b/g, G = /\b(?=[A-Za-z0-9_-]*\d)[A-Za-z0-9_-]{20,}\b|\b[0-9a-f]{16,}\b|\b\d{6,}\b/gi, K = /sk-ant-[A-Za-z0-9_-]{8,}|sk-(?:proj-|svcacct-)?[A-Za-z0-9_-]{16,}|npm_[A-Za-z0-9]{20,}|AIza[0-9A-Za-z_-]{20,}|gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|xox[abposr]-[A-Za-z0-9-]{10,}|AKIA[0-9A-Z]{16}|\bBearer\s+[A-Za-z0-9._~+/=-]{8,}/gi;
55
+ function A(t) {
56
+ return t.replace(K, "[redacted]").replace(/(\/\/)[^/@\s]+@/g, "$1").replace(/\?[^\s#]*/g, "").replace(q, "[email]").replace(D, ":id").replace(j, "[phone]").replace(G, ":id");
57
+ }
58
+ function b(t) {
59
+ let e = String(t ?? "");
60
+ const s = /^[a-z][a-z0-9+.-]*:\/\/[^/?#]*(.*)$/i.exec(e);
61
+ return s && (e = s[1] || "/"), e = e.split(/[?#]/)[0] || "/", e.split("/").map((o) => {
62
+ if (!o || /^[:[{*]/.test(o)) return o;
63
+ let a = o;
64
+ try {
65
+ a = decodeURIComponent(o);
66
+ } catch {
67
+ }
68
+ return /^\d+$/.test(a) || /\d{4,}/.test(a) || a.includes("@") || a.length >= 20 || /^[0-9a-f-]{8,}$/i.test(a) && /\d/.test(a) || /^(?=.*\d)(?=.*[A-Za-z])[A-Za-z0-9_-]{12,}$/.test(a) ? ":id" : a;
69
+ }).join("/").slice(0, 120) || "/";
70
+ }
71
+ function F(t) {
72
+ try {
73
+ const e = new URL(t);
74
+ return { host: e.hostname, port: e.port ? Number(e.port) : void 0 };
75
+ } catch {
76
+ return {};
77
+ }
78
+ }
79
+ function v(t) {
80
+ return typeof t == "string" ? A(t).slice(0, 200) : Array.isArray(t) ? t.map(v) : t;
81
+ }
82
+ function M(t, e, s, p = "strict", o) {
83
+ const a = s || {}, l = String(a["http.request.method"] ?? a["http.method"] ?? ""), m = U.map((r) => a[r]).find((r) => typeof r == "string"), n = {};
84
+ for (const [r, i] of Object.entries(a))
85
+ if (r.startsWith("agentglow.")) n[r] = i;
86
+ else {
87
+ if (y.test(r)) continue;
88
+ (p === "standard" || O.has(r)) && (n[r] = i);
89
+ }
90
+ if (l && e === "client" && !n["server.address"] && !n["net.peer.name"]) {
91
+ const r = L.map((f) => a[f]).find((f) => typeof f == "string"), { host: i, port: h } = r ? F(r) : {};
92
+ i && (n["server.address"] = i), h && (n["server.port"] = h);
93
+ }
94
+ let u = t;
95
+ if (l && (e === "server" || n["http.route"])) {
96
+ let r = b(String(n["http.route"] ?? n["next.route"] ?? m ?? "/"));
97
+ n["next.route"] && r.endsWith("/route") && (r = r.slice(0, -6) || "/"), n["http.route"] = r, u = `${l} ${r}`;
98
+ } else
99
+ u = t.replace(/([a-z][a-z0-9+.-]*:\/\/[^\s/?#]+)?(\/[^\s]*)/gi, (r, i, h) => (i ? i.replace(/\/\/[^/@]*@/, "//") : "") + b(h));
100
+ n["next.route"] && (n["next.route"] = b(String(n["next.route"])));
101
+ let c = n;
102
+ if (o)
103
+ try {
104
+ c = o(n, { name: u, kind: e }) ?? n;
105
+ } catch {
106
+ c = n;
107
+ }
108
+ for (const r of Object.keys(c)) c[r] = v(c[r]);
109
+ return { name: A(u).slice(0, 120), attributes: c };
110
+ }
111
+ class W {
112
+ constructor(e, s, p) {
113
+ g(this, "inner");
114
+ g(this, "privacy");
115
+ g(this, "hook");
116
+ this.inner = e, this.privacy = s, this.hook = p;
117
+ }
118
+ export(e, s) {
119
+ const p = e.map((o) => {
120
+ const { name: a, attributes: l } = M(o.name, N[o.kind] ?? "internal", o.attributes, this.privacy, this.hook), m = this.privacy === "strict" ? [] : o.events.map((n) => ({ ...n, attributes: Object.fromEntries(
121
+ Object.entries(n.attributes ?? {}).filter(([u]) => !y.test(u)).map(([u, c]) => [u, v(c)])
122
+ ) }));
123
+ return Object.create(o, {
124
+ name: { value: a },
125
+ attributes: { value: l },
126
+ events: { value: m },
127
+ status: { value: { code: o.status.code } }
128
+ });
129
+ });
130
+ this.inner.export(p, s);
131
+ }
132
+ shutdown() {
133
+ return this.inner.shutdown();
134
+ }
135
+ forceFlush() {
136
+ return this.inner.forceFlush ? this.inner.forceFlush() : Promise.resolve();
137
+ }
138
+ }
139
+ const d = (t) => {
140
+ var e, s;
141
+ return ((s = (e = globalThis.process) == null ? void 0 : e.env) == null ? void 0 : s[t]) || void 0;
142
+ }, _ = /* @__PURE__ */ new Map();
143
+ function Y(t = {}) {
144
+ const e = (t.url ?? d("AGENTGLOW_URL") ?? "http://localhost:8100").replace(/\/+$/, ""), s = t.ingestKey ?? d("AGENTGLOW_API_KEY"), p = new P({ url: `${e}/v1/traces`, headers: s ? { "x-api-key": s } : {} });
145
+ return new I(
146
+ new W(p, t.privacy ?? "strict", t.scrub),
147
+ { scheduledDelayMillis: 250, maxExportBatchSize: 512 }
148
+ );
149
+ }
150
+ function ne(t = {}) {
151
+ const e = (t.url ?? d("AGENTGLOW_URL") ?? "http://localhost:8100").replace(/\/+$/, ""), s = _.get(e);
152
+ if (s) return s;
153
+ const p = t.service ?? d("OTEL_SERVICE_NAME") ?? "node-app", o = new R({
154
+ resource: $({ "service.name": p, "service.instance.id": z() }),
155
+ spanProcessors: [Y({ ...t, url: e })]
156
+ });
157
+ o.register();
158
+ const a = k.getTracerProvider();
159
+ (a.getDelegate ? a.getDelegate() : a) !== o && console.warn("agentglow: another OpenTelemetry tracer provider is already registered; add spanProcessor() from agentglow/node to its spanProcessors instead of calling watch()");
160
+ const l = t.ignorePaths ?? [], m = t.incoming ?? !d("NEXT_RUNTIME"), n = (r) => l.some((i) => typeof i == "string" ? i === r : i.test(r)), u = T({
161
+ tracerProvider: o,
162
+ instrumentations: [
163
+ new S({
164
+ disableIncomingRequestInstrumentation: !m,
165
+ // (ignoring them instead would suppress their fetch spans)
166
+ ignoreIncomingRequestHook: (r) => n((r.url ?? "/").split("?")[0])
167
+ }),
168
+ new Z()
169
+ // global fetch (Node >= 18)
170
+ ]
171
+ });
172
+ try {
173
+ const r = x(import.meta.url);
174
+ r("node:http"), r("node:https");
175
+ } catch {
176
+ }
177
+ const c = {
178
+ flush: () => o.forceFlush().catch(() => {
179
+ }),
180
+ shutdown: async () => {
181
+ _.delete(e), u(), await o.shutdown().catch(() => {
182
+ });
183
+ }
184
+ };
185
+ return _.set(e, c), c;
186
+ }
187
+ export {
188
+ b as normalizePath,
189
+ M as scrubSpan,
190
+ A as scrubText,
191
+ Y as spanProcessor,
192
+ ne as watch
193
+ };
package/dist/pulse.js ADDED
@@ -0,0 +1,20 @@
1
+ async function l(i, r, t = {}) {
2
+ const n = t.fetch ?? globalThis.fetch;
3
+ if (!n) return !1;
4
+ const e = typeof AbortController == "function" ? new AbortController() : void 0, o = e ? setTimeout(() => e.abort(), t.timeoutMs ?? 2e3) : void 0;
5
+ try {
6
+ return (await n(i.replace(/\/+$/, "") + "/v1/events", {
7
+ method: "POST",
8
+ headers: { "content-type": "application/json", ...t.apiKey ? { "x-api-key": t.apiKey } : {} },
9
+ body: JSON.stringify(r),
10
+ signal: e == null ? void 0 : e.signal
11
+ })).ok;
12
+ } catch {
13
+ return !1;
14
+ } finally {
15
+ o && clearTimeout(o);
16
+ }
17
+ }
18
+ export {
19
+ l as pulse
20
+ };
package/dist/style.css CHANGED
@@ -1 +1 @@
1
- .scene-root{position:fixed;top:0;right:0;bottom:0;left:0;background:#03050b;color:#e8edf5;font-family:Public Sans,system-ui,sans-serif;overflow:hidden}.scene-root canvas{display:block}.hud{position:absolute;z-index:10;background:#0a0e1a8c;border:1px solid rgba(148,163,255,.16);border-radius:14px;backdrop-filter:blur(14px) saturate(1.3);-webkit-backdrop-filter:blur(14px) saturate(1.3);box-shadow:0 8px 32px #00000059,inset 0 1px #ffffff0a}.hud-topwrap{position:absolute;z-index:10;top:12px;left:12px;max-width:calc(100% - var(--hud-side, 320px) - 36px);display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;pointer-events:none}.hud-topwrap.is-rail{--hud-side: 40px}.hud-topwrap>*{pointer-events:auto}.hud-top{position:relative;padding:6px 8px 6px 12px;min-width:0}.hud-bar{display:flex;align-items:center;gap:4px 8px;flex-wrap:wrap}.hud-bar .hud-run{margin-top:0}.hud-info{all:unset;cursor:pointer;width:18px;height:18px;border-radius:50%;display:grid;place-items:center;font:italic 600 11px/1 Georgia,serif;color:#94a3b8;border:1px solid rgba(148,163,184,.35)}.hud-info:hover,.hud-info.on{color:#e2e8f0;border-color:#818cf8}.hud-theme{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#03050b8c url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%2394a3b8'/%3E%3C/svg%3E") no-repeat right 9px center;color:#cbd5e1;border:1px solid rgba(148,163,255,.22);border-radius:999px;font:inherit;font-size:11px;text-transform:uppercase;letter-spacing:.08em;padding:4px 24px 4px 10px;cursor:pointer;outline:none}.hud-theme:hover{border-color:#818cf8}.hud-title{display:flex;align-items:center;gap:8px;font-weight:700;font-size:15px;letter-spacing:-.01em;white-space:nowrap}.hud-sub{margin:6px 0 2px;max-width:460px;font-size:12px;line-height:1.45;color:#94a3b8}.hud-dot{width:9px;height:9px;border-radius:50%;background:#22c55e;box-shadow:0 0 10px #22c55e;animation:hud-ping 1.6s ease-out infinite}@keyframes hud-ping{0%{box-shadow:0 0 #22c55eb3}to{box-shadow:0 0 0 10px #22c55e00}}.hud-badge{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;padding:2px 7px;border-radius:999px;background:#94a3b829;color:#cbd5e1}.hud-stats{display:flex;flex-wrap:wrap;align-items:center;gap:4px}.hud-stat{font-size:11px;color:#94a3b8;padding:2px 8px;border-radius:999px;background:#03050b66;white-space:nowrap}.hud-stat b{color:#f1f5f9;font-weight:700;font-variant-numeric:tabular-nums}.hud-dec{--dc: 94, 234, 212;animation:hud-dec-pulse .7s ease-out}.hud-dec.is-deny{--dc: 251, 59, 92}@keyframes hud-dec-pulse{0%{background:rgba(var(--dc),.5);box-shadow:0 0 rgba(var(--dc),.7);color:#fff}35%{background:rgba(var(--dc),.28);box-shadow:0 0 0 5px rgba(var(--dc),0)}to{background:#03050b66;box-shadow:0 0 rgba(var(--dc),0)}}@media(prefers-reduced-motion:reduce){.hud-dec{animation:none}}.hud-dec-hv{display:inline-flex;align-items:center;gap:4px;color:#a7f3d0;background:#5eead41a}.hud-dec-hv.is-deny{color:#fecdd3;background:#fb3b5c24}.hud-spark{color:#5eead4;margin-left:2px}.hud-dec-hv.is-deny .hud-spark{color:#fb7185}.hud-halt{color:#fecdd3;background:#fb3b5c38;box-shadow:inset 0 0 0 1px #fb3b5c8c;animation:hud-halt 1.6s ease-in-out infinite}.hud-halt b{color:#fb3b5c;letter-spacing:.04em}@keyframes hud-halt{50%{background:#fb3b5c57}}@media(prefers-reduced-motion:reduce){.hud-halt{animation:none}}.scene-root :focus-visible{outline:2px solid #818cf8;outline-offset:2px}.hud-side{top:12px;right:12px;bottom:12px;width:320px;display:flex;flex-direction:column;padding:8px 10px 10px;font-size:13px;box-sizing:border-box;animation:hs-in .18s ease-out}.hud-side.is-rail{width:40px;padding:6px 0;align-items:center}@keyframes hs-in{0%{opacity:.4}}.hs-head{display:flex;align-items:center;gap:2px;padding-bottom:8px;margin:0 -2px 2px;border-bottom:1px solid rgba(148,163,255,.12)}.hs-head button{all:unset;cursor:pointer;display:flex;align-items:center;gap:5px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:#94a3b8;padding:5px 9px;border-radius:999px}.hs-head button:hover{color:#e2e8f0}.hs-head button.on{color:#f1f5f9;background:#818cf838}.hs-head em,.hs-icon em{font-style:normal;font-size:10px;font-weight:700;font-variant-numeric:tabular-nums;color:#c7d2fe;letter-spacing:0}.hs-head .hs-collapse{margin-left:auto;font-size:14px;padding:2px 8px;letter-spacing:0}.hs-rail{display:flex;flex-direction:column;align-items:center;gap:6px}.hs-rail button{all:unset;cursor:pointer;position:relative;width:30px;height:30px;display:grid;place-items:center;border-radius:9px;color:#94a3b8}.hs-rail button:hover{color:#e2e8f0;background:#94a3ff1a}.hs-rail .hs-collapse{font-size:14px;margin-bottom:4px}.hs-icon em{position:absolute;top:-3px;right:-5px;min-width:14px;height:14px;padding:0 3px;box-sizing:border-box;border-radius:999px;display:grid;place-items:center;font-size:9px;background:#4f46e5;color:#eef2ff}.hs-icon em:empty{min-width:8px;width:8px;height:8px;padding:0;top:1px;right:1px;background:#22d3ee;box-shadow:0 0 8px #22d3ee}.hs-body{flex:1;min-height:0;display:flex;flex-direction:column}.hs-body[hidden]{display:none}.hs-empty{margin:14px 4px;font-size:12px;line-height:1.5;color:#64748b}.hs-events{list-style:none;margin:6px -4px 0;padding:0;overflow-y:auto;min-height:0;flex:1;font-size:11.5px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.hs-events li>*{all:unset;box-sizing:border-box;width:100%;display:flex;gap:8px;align-items:baseline;padding:4px 6px;border-radius:7px;color:#cbd5e1;line-height:1.4}.hs-events li>button{cursor:pointer}.hs-events li>button:hover{background:#94a3ff1a;color:#f1f5f9}.hs-events i{flex:0 0 7px;height:7px;border-radius:50%;background:var(--c);box-shadow:0 0 8px var(--c);transform:translateY(-1px)}.hs-events span{min-width:0;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow-wrap:anywhere}.ap-head{display:flex;align-items:center;gap:8px;margin-top:6px}.ap-count{flex:none;color:#64748b;font-size:11px;font-variant-numeric:tabular-nums}.ap-link{all:unset;cursor:pointer;font-size:12px;color:#93c5fd}.ap-link:hover{color:#bfdbfe}.ap-searchrow{display:flex;align-items:center;gap:8px;margin-top:8px}.ap-search{flex:1;min-width:0;width:100%;box-sizing:border-box;background:#03050b99;border:1px solid rgba(148,163,255,.2);border-radius:8px;color:inherit;font:inherit;font-size:12px;padding:6px 9px;outline:none}.ap-search:focus{border-color:#818cf8}.ap-chips{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}.ap-chips button{all:unset;cursor:pointer;display:flex;align-items:center;gap:5px;font-size:11px;padding:3px 7px;border-radius:999px;border:1px solid rgba(148,163,255,.15);color:#cbd5e1}.ap-chips button.on{border-color:var(--c);background:color-mix(in srgb,var(--c) 18%,transparent);color:#f8fafc}.ap-chips i{width:8px;height:8px;border-radius:50%;background:var(--c);box-shadow:0 0 8px var(--c)}.ap-chips em{font-style:normal;color:var(--c);font-weight:700;font-variant-numeric:tabular-nums}.ap-row-filters{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;align-items:center}.ap-seg{display:flex;border:1px solid rgba(148,163,255,.15);border-radius:8px;overflow:hidden}.ap-seg{flex:none}.ap-seg button{all:unset;cursor:pointer;font-size:11px;padding:3px 6px;color:#94a3b8;text-transform:capitalize}.ap-seg button.on{background:#818cf840;color:#f1f5f9}.ap-row-filters select{flex:1;min-width:64px;background:#03050b99;color:#cbd5e1;border:1px solid rgba(148,163,255,.15);border-radius:8px;font:inherit;font-size:11px;padding:3px 6px}.ap-list{list-style:none;margin:8px -4px 0;padding:0;overflow-y:auto;min-height:0;flex:1}.ap-list li button{all:unset;box-sizing:border-box;width:100%;cursor:pointer;display:flex;align-items:center;gap:8px;padding:6px;border-radius:8px}.ap-list li button:hover{background:#94a3ff1a}.ap-list li button.is-done{opacity:.55}.ap-list i{flex:0 0 9px;height:9px;border-radius:50%;background:var(--c);box-shadow:0 0 8px var(--c)}.ap-list i[data-status=thinking]{animation:ap-pulse .9s ease-in-out infinite}.ap-list i[data-status=waiting]{opacity:.5}.ap-list i[data-status=done]{background:transparent;border:1.5px solid var(--c);box-shadow:none}@keyframes ap-pulse{50%{transform:scale(1.5)}}.ap-name{flex:1;min-width:0;display:flex;flex-direction:column;font-size:12px;color:#e2e8f0}.ap-name small{color:#64748b;font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ap-meta{text-align:right;font-size:11px;color:#94a3b8;font-variant-numeric:tabular-nums;display:flex;flex-direction:column}.ap-meta b{color:var(--c);font-weight:600;text-transform:lowercase}.hs-events li.is-skill>*{background:#f5b83d12}.hs-skill{flex:0 0 auto;font-size:9.5px;font-weight:600;line-height:1.5;text-transform:uppercase;letter-spacing:.06em;color:#fcd581;padding:0 6px;border-radius:999px;border:1px solid rgba(245,184,61,.55);background:#f5b83d1f}.ap-title{display:flex;align-items:center;gap:6px;min-width:0}.ap-skill{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-size:9.5px;font-weight:600;color:#fcd581;padding:0 6px;border-radius:999px;border:1px solid rgba(245,184,61,.55);background:#f5b83d1f}.ap-skill:before{content:"skill:";color:#b8893a;font-weight:500}.hs-skill:before{content:"";display:inline-block;width:6px;height:6px;margin:0 4px 0 -1px;border:1px solid currentColor;border-radius:50%;vertical-align:0;box-shadow:0 0 4px #f5b83d99}.hs-events li.is-dec>*{background:#5eead40d}.hs-events li.is-deny>*{background:#fb3b5c1f}.hs-dec{flex:0 0 auto;font-size:9.5px;font-weight:600;line-height:1.5;text-transform:uppercase;letter-spacing:.06em;color:var(--c);padding:0 6px;border-radius:3px;border:1px solid var(--c);background:#ffffff0a}.ap-decisions{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:3px}.ap-decisions li{display:flex;gap:6px;align-items:baseline;font-size:11px;color:#e2e8f0;padding:2px 6px;border-left:2px solid var(--c);background:#ffffff08}.ap-decisions li.is-deny{background:#fb3b5c1f}.ap-decisions li.is-strike span{text-decoration:line-through;color:#94a3b8}.ap-hv{font-size:11.5px;color:#e2e8f0;margin:0 0 4px;font-variant-numeric:tabular-nums}.ap-hv-bar{display:flex;height:6px;border-radius:3px;overflow:hidden;gap:1px;background:#ffffff0d}.ap-hv-bar span{flex-basis:0;min-width:2px}.ap-decisions b{flex:0 0 auto;font-size:9.5px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--c)}.ap-decisions span{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ap-decisions em{flex:0 0 auto;font-style:normal;font-size:10px;color:#94a3b8;font-variant-numeric:tabular-nums}.ap-skills{display:flex;flex-wrap:wrap;gap:4px}.ap-skills span{font-size:11px;color:#e2e8f0;padding:2px 8px;border-radius:999px;border:1px solid rgba(245,184,61,.35);background:#f5b83d0f;display:inline-flex;gap:5px;align-items:baseline}.ap-skills span.on{border-color:#f5b83d;background:#f5b83d2e;color:#fde7b0;box-shadow:0 0 10px #f5b83d40}.ap-skills em{font-style:normal;font-size:10px;color:#b8893a;font-variant-numeric:tabular-nums}.ap-more{padding:6px;color:#64748b;font-size:11px}.ap-detail{overflow-y:auto;min-height:0;margin-top:8px;flex:1}.ap-detail h3{margin:0;display:flex;align-items:center;gap:8px;font-size:15px;color:var(--c)}.ap-detail h3 i{width:11px;height:11px;border-radius:50%;background:var(--c);box-shadow:0 0 10px var(--c)}.ap-detail h3 small{color:#64748b;font-size:11px;font-weight:500}.ap-status{margin-top:3px;font-size:12px;color:#cbd5e1}.ap-status[data-status=thinking]{color:#fde68a}.ap-status[data-status=waiting]{color:#fcd34d}.ap-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(46px,1fr));gap:4px;margin:10px 0 4px}.ap-stats div{background:#03050b73;border-radius:8px;padding:6px;text-align:center}.ap-stats dt{font-size:9px;text-transform:uppercase;letter-spacing:.06em;color:#64748b}.ap-stats dd{margin:2px 0 0;font-size:15px;font-weight:700;color:#f1f5f9;font-variant-numeric:tabular-nums}.ap-detail section{margin-top:10px}.ap-detail h4{margin:0 0 4px;font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#64748b}.ap-detail p{margin:0;font-size:12px;color:#cbd5e1}.ap-steps{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.ap-steps span{max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;text-transform:uppercase;letter-spacing:.06em;padding:2px 7px;border-radius:999px;border:1px solid #334155;color:#64748b}.ap-steps span[data-status=running]{border-color:#fbbf24;color:#fde68a}.ap-steps span[data-status=waiting]{border-color:#f59e0b;color:#fcd34d;background:#f59e0b24;animation:ap-wait-pulse 1.8s ease-in-out infinite}.ap-steps span[data-status=done]{border-color:#22c55e;color:#86efac}.ap-steps span[data-status=failed]{border-color:#ef4444;color:#fca5a5}.ap-chip-link{all:unset;cursor:pointer;display:block;font-size:12px;color:#e2e8f0;padding:3px 6px;border-left:2px solid var(--c);margin:2px 0;border-radius:0 6px 6px 0}.ap-chip-link:hover{background:#94a3ff1a}.ap-wait{color:#fbbf24!important;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.ap-nodes{line-height:1.5}.ap-chat{margin:0;padding:0;list-style:none;display:grid;gap:6px;font-size:12px;color:#e2e8f0;white-space:pre-wrap;overflow-wrap:anywhere;max-height:320px;overflow-y:auto}.ap-chat li[data-role=user]{color:#c7d2fe}.ap-chat li[data-role=agent]{padding-bottom:6px;border-bottom:1px solid rgba(148,163,255,.12)}.ap-chat b{font-weight:650}.ap-events{margin:0;padding-left:14px;display:grid;gap:3px;font-size:11px;color:#cbd5e1;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.hud-badge--live{background:#22c55e2e;color:#86efac}.hud-badge--denied{background:#f871712e;color:#fca5a5;text-transform:none;letter-spacing:.02em}.hud-chip{text-transform:none;letter-spacing:.02em;font-weight:500;background:#818cf829;color:#c7d2fe;white-space:nowrap;max-width:180px;overflow:hidden;text-overflow:ellipsis}.hud-chip b{font-weight:650;color:#e0e7ff}.hud-run{display:flex;gap:6px;margin-top:8px;align-items:center;flex-wrap:wrap}.hud-run input{flex:1;min-width:160px;background:#03050b99;border:1px solid rgba(148,163,255,.2);border-radius:999px;color:inherit;font:inherit;font-size:12px;padding:6px 11px;outline:none}.hud-run button{border:0;border-radius:999px;padding:6px 13px;font:inherit;font-size:12px;font-weight:600;background:linear-gradient(135deg,#818cf8,#22d3ee);color:#03050b;cursor:pointer}.hud-run button:disabled{opacity:.5}.hud-run select{max-width:160px;min-width:0;background:#03050b99;color:#cbd5e1;border:1px solid rgba(148,163,255,.2);border-radius:999px;font:inherit;font-size:12px;padding:5px 9px;cursor:pointer}.hud-run span{font-size:11px;color:#86efac}.agentglow-embed{position:relative;overflow:hidden;width:100%;height:100%;min-height:320px;isolation:isolate}.agentglow-embed .scene-root{position:absolute;top:0;right:0;bottom:0;left:0}.lod-cluster-label{all:unset;box-sizing:border-box;display:grid;gap:1px;text-align:center;cursor:pointer;pointer-events:auto;font-size:12px;font-weight:600;color:#f8fafc;padding:4px 11px 5px;border-radius:12px;white-space:nowrap;background:#03050b9e;border:1px solid color-mix(in srgb,var(--c, #818cf8) 60%,transparent);text-shadow:0 0 10px var(--c, #818cf8);box-shadow:0 0 18px color-mix(in srgb,var(--c, #818cf8) 22%,transparent);transition:border-color .2s,background .2s}.lod-cluster-label:hover{background:color-mix(in srgb,var(--c, #818cf8) 22%,rgba(3,5,11,.7));border-color:var(--c, #818cf8)}.lod-cluster-label b{font-weight:700;letter-spacing:-.01em}.lod-cluster-label small{font-size:10px;font-weight:500;color:#94a3b8;text-shadow:none;font-variant-numeric:tabular-nums}.hud-dock{display:flex;align-items:center;gap:8px}.hud-dock:empty{display:none}.hud-dock>.hud{position:static}.hud-lod{padding:6px 8px 6px 12px;display:flex;align-items:center;gap:8px;font-size:12px;color:#cbd5e1;white-space:nowrap}.hud-lod span b{margin:0 1px}.hud-lod b{color:#f1f5f9;font-variant-numeric:tabular-nums}.hud-lod i{width:7px;height:7px;border-radius:50%;background:#a5b4fc;box-shadow:0 0 8px #a5b4fc}.hud-lod button{all:unset;cursor:pointer;font-size:11px;padding:3px 9px;border-radius:999px;border:1px solid rgba(148,163,255,.25);color:#c7d2fe}.hud-lod button:hover{background:#818cf833;color:#f8fafc}.scene-root{container:agscene / size}@container agscene (max-width: 719px){.scene-root .hud-top{padding:5px 7px 5px 10px}.scene-root .hud-title{font-size:13px}.scene-root .hud-theme{padding:3px 20px 3px 8px;font-size:10px;background-position:right 7px center}.scene-root .hud-stat:nth-child(n+3){display:none}.scene-root .hud-side:not(.is-rail){width:min(290px,calc(100% - 64px));padding:6px 8px 8px}.scene-root .hs-head button{padding:4px 6px;letter-spacing:.04em;font-size:10.5px}.scene-root .hs-head .hs-collapse{padding:2px 4px}.scene-root .ap-list li button{padding:4px 6px}.scene-root .hud-topwrap:not(.is-rail){--hud-side: min(290px, calc(100% - 64px) )}}@container agscene (max-height: 520px){.scene-root .hud-sub{max-height:4.5em;overflow:auto}}@keyframes ap-wait-pulse{50%{box-shadow:0 0 10px #f59e0b8c;border-color:#fbbf24}}@media(prefers-reduced-motion:reduce){.ap-steps span[data-status=waiting]{animation:none}}.hud-approve{display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin-top:8px}.hud-approve button{border:1px solid transparent;border-radius:999px;padding:5px 13px;font:inherit;font-size:12px;font-weight:650;cursor:pointer}.hud-approve .ha-yes{background:linear-gradient(135deg,#34d399,#22d3ee);color:#03050b}.hud-approve .ha-no{background:#fb3b5c24;border-color:#fb718599;color:#fecdd3}.hud-approve .ha-yes:hover{filter:brightness(1.1)}.hud-approve .ha-no:hover{background:#fb3b5c47}.hud-approve span{font-size:11px;color:#94a3b8}.hud-approve[data-verdict=approved] span,.hud-approve[data-verdict=approving] span{color:#86efac}.hud-approve[data-verdict=rejected] span,.hud-approve[data-verdict=rejecting] span,.hud-approve[data-verdict=error] span{color:#fda4af}.hud-approve.is-compact{margin-top:0;flex:none;gap:4px}.hud-approve.is-compact button{padding:3px 9px;font-size:11px}.hud-approvals{left:12px;bottom:12px;z-index:9;width:max-content;max-width:min(460px,calc(100% - 356px));padding:8px 10px;font-size:12px;box-sizing:border-box;border-color:#f59e0b73;box-shadow:0 8px 32px #00000059,0 0 18px #f59e0b1f}.hud-approvals.is-rail{max-width:min(460px,calc(100% - 76px))}.hud-approvals h4{margin:0 0 6px;font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#fcd34d;display:flex;gap:6px;align-items:baseline}.hud-approvals h4 em{font-style:normal;font-variant-numeric:tabular-nums;color:#fde68a}.hud-approvals ul{list-style:none;margin:0;padding:0;display:grid;gap:4px}.hud-approvals li{display:flex;align-items:center;gap:8px;min-width:0}.hud-approvals .ha-who{all:unset;cursor:pointer;flex:1;min-width:0;display:flex;align-items:baseline;gap:6px;padding:2px 4px;border-radius:6px}.hud-approvals .ha-who:hover{background:#94a3ff1a}.hud-approvals .ha-who i{flex:0 0 8px;height:8px;border-radius:50%;background:var(--c);box-shadow:0 0 8px var(--c);align-self:center}.hud-approvals .ha-who b{color:#e2e8f0;font-weight:650;white-space:nowrap}.hud-approvals .ha-who span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#fbbf24;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}.hud-approvals p{margin:6px 0 0;font-size:11px;color:#64748b}@container agscene (max-width: 719px){.scene-root .hud-approvals{max-width:calc(100% - 76px);padding:6px 8px}.scene-root .hud-approvals .ha-who span{display:none}}.flow-run{display:flex;flex-direction:column;align-items:center;gap:4px;pointer-events:none}.flow-run .scene-label{font-size:11px;max-width:220px;overflow:hidden;text-overflow:ellipsis}.flow-steps{display:flex;gap:3px;font:600 9px/1 ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase;letter-spacing:.06em}.flow-steps span{padding:2px 5px;border-radius:999px;color:#64748b;background:#03050b8c;border:1px solid rgba(100,116,139,.35)}.flow-steps span[data-s=running]{color:#03050b;background:var(--c);border-color:var(--c);box-shadow:0 0 12px var(--c)}.flow-steps span[data-s=done]{color:var(--c);border-color:color-mix(in srgb,var(--c) 60%,transparent)}.flow-steps span[data-s=failed]{color:#fecaca;background:#7f1d1d}.flow-step{font:600 9px/1 ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase;letter-spacing:.08em;color:color-mix(in srgb,var(--c) 70%,white);text-shadow:0 0 8px var(--c);opacity:.55;pointer-events:none;white-space:nowrap;transition:opacity .3s}.flow-step[data-s=running]{opacity:1}.flow-hint{font-size:10px;padding:1px 7px;opacity:.9}.flow-label-core{font-size:11px;letter-spacing:.04em}
1
+ .scene-root{position:fixed;top:0;right:0;bottom:0;left:0;background:#03050b;color:#e8edf5;font-family:Public Sans,system-ui,sans-serif;overflow:hidden}.scene-root canvas{display:block}.hud{position:absolute;z-index:10;background:#0a0e1a8c;border:1px solid rgba(148,163,255,.16);border-radius:14px;backdrop-filter:blur(14px) saturate(1.3);-webkit-backdrop-filter:blur(14px) saturate(1.3);box-shadow:0 8px 32px #00000059,inset 0 1px #ffffff0a}.hud-topwrap{position:absolute;z-index:10;top:12px;left:12px;max-width:calc(100% - var(--hud-side, 320px) - 36px);display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;pointer-events:none}.hud-topwrap.is-rail{--hud-side: 40px}.hud-topwrap>*{pointer-events:auto}.hud-top{position:relative;padding:6px 8px 6px 12px;min-width:0}.hud-bar{display:flex;align-items:center;gap:4px 8px;flex-wrap:wrap}.hud-bar .hud-run{margin-top:0}.hud-info{all:unset;cursor:pointer;width:18px;height:18px;border-radius:50%;display:grid;place-items:center;font:italic 600 11px/1 Georgia,serif;color:#94a3b8;border:1px solid rgba(148,163,184,.35)}.hud-info:hover,.hud-info.on{color:#e2e8f0;border-color:#818cf8}.hud-theme{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:#03050b8c url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath d='M0 0l4 5 4-5z' fill='%2394a3b8'/%3E%3C/svg%3E") no-repeat right 9px center;color:#cbd5e1;border:1px solid rgba(148,163,255,.22);border-radius:999px;font:inherit;font-size:11px;text-transform:uppercase;letter-spacing:.08em;padding:4px 24px 4px 10px;cursor:pointer;outline:none}.hud-theme:hover{border-color:#818cf8}.hud-title{display:flex;align-items:center;gap:8px;font-weight:700;font-size:15px;letter-spacing:-.01em;white-space:nowrap}.hud-sub{margin:6px 0 2px;max-width:460px;font-size:12px;line-height:1.45;color:#94a3b8}.hud-dot{width:9px;height:9px;border-radius:50%;background:#22c55e;box-shadow:0 0 10px #22c55e;animation:hud-ping 1.6s ease-out infinite}@keyframes hud-ping{0%{box-shadow:0 0 #22c55eb3}to{box-shadow:0 0 0 10px #22c55e00}}.hud-badge{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;padding:2px 7px;border-radius:999px;background:#94a3b829;color:#cbd5e1}.hud-stats{display:flex;flex-wrap:wrap;align-items:center;gap:4px}.hud-stat{font-size:11px;color:#94a3b8;padding:2px 8px;border-radius:999px;background:#03050b66;white-space:nowrap}.hud-stat b{color:#f1f5f9;font-weight:700;font-variant-numeric:tabular-nums}.hud-dec{--dc: 94, 234, 212;animation:hud-dec-pulse .7s ease-out}.hud-dec.is-deny{--dc: 251, 59, 92}@keyframes hud-dec-pulse{0%{background:rgba(var(--dc),.5);box-shadow:0 0 rgba(var(--dc),.7);color:#fff}35%{background:rgba(var(--dc),.28);box-shadow:0 0 0 5px rgba(var(--dc),0)}to{background:#03050b66;box-shadow:0 0 rgba(var(--dc),0)}}@media(prefers-reduced-motion:reduce){.hud-dec{animation:none}}.hud-dec-hv{display:inline-flex;align-items:center;gap:4px;color:#a7f3d0;background:#5eead41a}.hud-dec-hv.is-deny{color:#fecdd3;background:#fb3b5c24}.hud-spark{color:#5eead4;margin-left:2px}.hud-dec-hv.is-deny .hud-spark{color:#fb7185}.hud-halt{color:#fecdd3;background:#fb3b5c38;box-shadow:inset 0 0 0 1px #fb3b5c8c;animation:hud-halt 1.6s ease-in-out infinite}.hud-halt b{color:#fb3b5c;letter-spacing:.04em}@keyframes hud-halt{50%{background:#fb3b5c57}}@media(prefers-reduced-motion:reduce){.hud-halt{animation:none}}.scene-root :focus-visible{outline:2px solid #818cf8;outline-offset:2px}.hud-side{top:12px;right:12px;bottom:12px;width:320px;display:flex;flex-direction:column;padding:8px 10px 10px;font-size:13px;box-sizing:border-box;animation:hs-in .18s ease-out}.hud-side.is-rail{width:40px;padding:6px 0;align-items:center}@keyframes hs-in{0%{opacity:.4}}.hs-head{display:flex;align-items:center;gap:2px;padding-bottom:8px;margin:0 -2px 2px;border-bottom:1px solid rgba(148,163,255,.12)}.hs-head button{all:unset;cursor:pointer;display:flex;align-items:center;gap:5px;font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:#94a3b8;padding:5px 9px;border-radius:999px}.hs-head button:hover{color:#e2e8f0}.hs-head button.on{color:#f1f5f9;background:#818cf838}.hs-head em,.hs-icon em{font-style:normal;font-size:10px;font-weight:700;font-variant-numeric:tabular-nums;color:#c7d2fe;letter-spacing:0}.hs-head .hs-collapse{margin-left:auto;font-size:14px;padding:2px 8px;letter-spacing:0}.hs-rail{display:flex;flex-direction:column;align-items:center;gap:6px}.hs-rail button{all:unset;cursor:pointer;position:relative;width:30px;height:30px;display:grid;place-items:center;border-radius:9px;color:#94a3b8}.hs-rail button:hover{color:#e2e8f0;background:#94a3ff1a}.hs-rail .hs-collapse{font-size:14px;margin-bottom:4px}.hs-icon em{position:absolute;top:-3px;right:-5px;min-width:14px;height:14px;padding:0 3px;box-sizing:border-box;border-radius:999px;display:grid;place-items:center;font-size:9px;background:#4f46e5;color:#eef2ff}.hs-icon em:empty{min-width:8px;width:8px;height:8px;padding:0;top:1px;right:1px;background:#22d3ee;box-shadow:0 0 8px #22d3ee}.hs-body{flex:1;min-height:0;display:flex;flex-direction:column}.hs-body[hidden]{display:none}.hs-empty{margin:14px 4px;font-size:12px;line-height:1.5;color:#64748b}.hs-events{list-style:none;margin:6px -4px 0;padding:0;overflow-y:auto;min-height:0;flex:1;font-size:11.5px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.hs-events li>*{all:unset;box-sizing:border-box;width:100%;display:flex;gap:8px;align-items:baseline;padding:4px 6px;border-radius:7px;color:#cbd5e1;line-height:1.4}.hs-events li>button{cursor:pointer}.hs-events li>button:hover{background:#94a3ff1a;color:#f1f5f9}.hs-events i{flex:0 0 7px;height:7px;border-radius:50%;background:var(--c);box-shadow:0 0 8px var(--c);transform:translateY(-1px)}.hs-events span{min-width:0;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow-wrap:anywhere}.ap-head{display:flex;align-items:center;gap:8px;margin-top:6px}.ap-count{flex:none;color:#64748b;font-size:11px;font-variant-numeric:tabular-nums}.ap-link{all:unset;cursor:pointer;font-size:12px;color:#93c5fd}.ap-link:hover{color:#bfdbfe}.ap-searchrow{display:flex;align-items:center;gap:8px;margin-top:8px}.ap-search{flex:1;min-width:0;width:100%;box-sizing:border-box;background:#03050b99;border:1px solid rgba(148,163,255,.2);border-radius:8px;color:inherit;font:inherit;font-size:12px;padding:6px 9px;outline:none}.ap-search:focus{border-color:#818cf8}.ap-chips{display:flex;flex-wrap:wrap;gap:4px;margin-top:8px}.ap-chips button{all:unset;cursor:pointer;display:flex;align-items:center;gap:5px;font-size:11px;padding:3px 7px;border-radius:999px;border:1px solid rgba(148,163,255,.15);color:#cbd5e1}.ap-chips button.on{border-color:var(--c);background:color-mix(in srgb,var(--c) 18%,transparent);color:#f8fafc}.ap-chips i{width:8px;height:8px;border-radius:50%;background:var(--c);box-shadow:0 0 8px var(--c)}.ap-chips em{font-style:normal;color:var(--c);font-weight:700;font-variant-numeric:tabular-nums}.ap-row-filters{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px;align-items:center}.ap-seg{display:flex;border:1px solid rgba(148,163,255,.15);border-radius:8px;overflow:hidden}.ap-seg{flex:none}.ap-seg button{all:unset;cursor:pointer;font-size:11px;padding:3px 6px;color:#94a3b8;text-transform:capitalize}.ap-seg button.on{background:#818cf840;color:#f1f5f9}.ap-row-filters select{flex:1;min-width:64px;background:#03050b99;color:#cbd5e1;border:1px solid rgba(148,163,255,.15);border-radius:8px;font:inherit;font-size:11px;padding:3px 6px}.ap-list{list-style:none;margin:8px -4px 0;padding:0;overflow-y:auto;min-height:0;flex:1}.ap-list li button{all:unset;box-sizing:border-box;width:100%;cursor:pointer;display:flex;align-items:center;gap:8px;padding:6px;border-radius:8px}.ap-list li button:hover{background:#94a3ff1a}.ap-list li button.is-done{opacity:.55}.ap-list i{flex:0 0 9px;height:9px;border-radius:50%;background:var(--c);box-shadow:0 0 8px var(--c)}.ap-list i[data-status=thinking]{animation:ap-pulse .9s ease-in-out infinite}.ap-list i[data-status=waiting]{opacity:.5}.ap-list i[data-status=done]{background:transparent;border:1.5px solid var(--c);box-shadow:none}@keyframes ap-pulse{50%{transform:scale(1.5)}}.ap-name{flex:1;min-width:0;display:flex;flex-direction:column;font-size:12px;color:#e2e8f0}.ap-name small{color:#64748b;font-size:11px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ap-meta{text-align:right;font-size:11px;color:#94a3b8;font-variant-numeric:tabular-nums;display:flex;flex-direction:column}.ap-meta b{color:var(--c);font-weight:600;text-transform:lowercase}.hs-events li.is-skill>*{background:#f5b83d12}.hs-skill{flex:0 0 auto;font-size:9.5px;font-weight:600;line-height:1.5;text-transform:uppercase;letter-spacing:.06em;color:#fcd581;padding:0 6px;border-radius:999px;border:1px solid rgba(245,184,61,.55);background:#f5b83d1f}.ap-title{display:flex;align-items:center;gap:6px;min-width:0}.ap-skill{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-style:normal;font-size:9.5px;font-weight:600;color:#fcd581;padding:0 6px;border-radius:999px;border:1px solid rgba(245,184,61,.55);background:#f5b83d1f}.ap-skill:before{content:"skill:";color:#b8893a;font-weight:500}.hs-skill:before{content:"";display:inline-block;width:6px;height:6px;margin:0 4px 0 -1px;border:1px solid currentColor;border-radius:50%;vertical-align:0;box-shadow:0 0 4px #f5b83d99}.hs-events li.is-dec>*{background:#5eead40d}.hs-events li.is-deny>*{background:#fb3b5c1f}.hs-dec{flex:0 0 auto;font-size:9.5px;font-weight:600;line-height:1.5;text-transform:uppercase;letter-spacing:.06em;color:var(--c);padding:0 6px;border-radius:3px;border:1px solid var(--c);background:#ffffff0a}.ap-decisions{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:3px}.ap-decisions li{display:flex;gap:6px;align-items:baseline;font-size:11px;color:#e2e8f0;padding:2px 6px;border-left:2px solid var(--c);background:#ffffff08}.ap-decisions li.is-deny{background:#fb3b5c1f}.ap-decisions li.is-strike span{text-decoration:line-through;color:#94a3b8}.ap-hv{font-size:11.5px;color:#e2e8f0;margin:0 0 4px;font-variant-numeric:tabular-nums}.ap-hv-bar{display:flex;height:6px;border-radius:3px;overflow:hidden;gap:1px;background:#ffffff0d}.ap-hv-bar span{flex-basis:0;min-width:2px}.ap-decisions b{flex:0 0 auto;font-size:9.5px;font-weight:600;text-transform:uppercase;letter-spacing:.05em;color:var(--c)}.ap-decisions span{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ap-decisions em{flex:0 0 auto;font-style:normal;font-size:10px;color:#94a3b8;font-variant-numeric:tabular-nums}.ap-skills{display:flex;flex-wrap:wrap;gap:4px}.ap-skills span{font-size:11px;color:#e2e8f0;padding:2px 8px;border-radius:999px;border:1px solid rgba(245,184,61,.35);background:#f5b83d0f;display:inline-flex;gap:5px;align-items:baseline}.ap-skills span.on{border-color:#f5b83d;background:#f5b83d2e;color:#fde7b0;box-shadow:0 0 10px #f5b83d40}.ap-skills em{font-style:normal;font-size:10px;color:#b8893a;font-variant-numeric:tabular-nums}.ap-more{padding:6px;color:#64748b;font-size:11px}.ap-detail{overflow-y:auto;min-height:0;margin-top:8px;flex:1}.ap-detail h3{margin:0;display:flex;align-items:center;gap:8px;font-size:15px;color:var(--c)}.ap-detail h3 i{width:11px;height:11px;border-radius:50%;background:var(--c);box-shadow:0 0 10px var(--c)}.ap-detail h3 small{color:#64748b;font-size:11px;font-weight:500}.ap-status{margin-top:3px;font-size:12px;color:#cbd5e1}.ap-status[data-status=thinking]{color:#fde68a}.ap-status[data-status=waiting]{color:#fcd34d}.ap-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(46px,1fr));gap:4px;margin:10px 0 4px}.ap-stats div{background:#03050b73;border-radius:8px;padding:6px;text-align:center}.ap-stats dt{font-size:9px;text-transform:uppercase;letter-spacing:.06em;color:#64748b}.ap-stats dd{margin:2px 0 0;font-size:15px;font-weight:700;color:#f1f5f9;font-variant-numeric:tabular-nums}.ap-detail section{margin-top:10px}.ap-detail h4{margin:0 0 4px;font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#64748b}.ap-detail p{margin:0;font-size:12px;color:#cbd5e1}.ap-steps{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.ap-steps span{max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:10px;text-transform:uppercase;letter-spacing:.06em;padding:2px 7px;border-radius:999px;border:1px solid #334155;color:#64748b}.ap-steps span[data-status=running]{border-color:#fbbf24;color:#fde68a}.ap-steps span[data-status=waiting]{border-color:#f59e0b;color:#fcd34d;background:#f59e0b24;animation:ap-wait-pulse 1.8s ease-in-out infinite}.ap-steps span[data-status=done]{border-color:#22c55e;color:#86efac}.ap-steps span[data-status=failed]{border-color:#ef4444;color:#fca5a5}.ap-chip-link{all:unset;cursor:pointer;display:block;font-size:12px;color:#e2e8f0;padding:3px 6px;border-left:2px solid var(--c);margin:2px 0;border-radius:0 6px 6px 0}.ap-chip-link:hover{background:#94a3ff1a}.ap-wait{color:#fbbf24!important;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.ap-idle{color:#94a3b8!important;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.ap-runhead{display:flex;align-items:center;justify-content:space-between}.ap-dismiss{border:0;background:transparent;color:#94a3b8;font-size:15px;line-height:1;padding:0 4px;cursor:pointer;border-radius:4px}.ap-dismiss:hover,.ap-dismiss:focus-visible{color:#f1f5f9;background:#94a3b82e}.hud-hidden{border:0;cursor:pointer}.hud-hidden:hover{color:#f1f5f9}.ap-nodes{line-height:1.5}.ap-chat{margin:0;padding:0;list-style:none;display:grid;gap:6px;font-size:12px;color:#e2e8f0;white-space:pre-wrap;overflow-wrap:anywhere;max-height:320px;overflow-y:auto}.ap-chat li[data-role=user]{color:#c7d2fe}.ap-chat li[data-role=agent]{padding-bottom:6px;border-bottom:1px solid rgba(148,163,255,.12)}.ap-chat b{font-weight:650}.ap-events{margin:0;padding-left:14px;display:grid;gap:3px;font-size:11px;color:#cbd5e1;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.hud-badge--live{background:#22c55e2e;color:#86efac}.hud-badge--denied{background:#f871712e;color:#fca5a5;text-transform:none;letter-spacing:.02em}.hud-chip{text-transform:none;letter-spacing:.02em;font-weight:500;background:#818cf829;color:#c7d2fe;white-space:nowrap;max-width:180px;overflow:hidden;text-overflow:ellipsis}.hud-chip b{font-weight:650;color:#e0e7ff}.hud-run{display:flex;gap:6px;margin-top:8px;align-items:center;flex-wrap:wrap}.hud-run input{flex:1;min-width:160px;background:#03050b99;border:1px solid rgba(148,163,255,.2);border-radius:999px;color:inherit;font:inherit;font-size:12px;padding:6px 11px;outline:none}.hud-run button{border:0;border-radius:999px;padding:6px 13px;font:inherit;font-size:12px;font-weight:600;background:linear-gradient(135deg,#818cf8,#22d3ee);color:#03050b;cursor:pointer}.hud-run button:disabled{opacity:.5}.hud-run select{max-width:160px;min-width:0;background:#03050b99;color:#cbd5e1;border:1px solid rgba(148,163,255,.2);border-radius:999px;font:inherit;font-size:12px;padding:5px 9px;cursor:pointer}.hud-run span{font-size:11px;color:#86efac}.agentglow-embed{position:relative;overflow:hidden;width:100%;height:100%;min-height:320px;isolation:isolate}.agentglow-embed .scene-root{position:absolute;top:0;right:0;bottom:0;left:0}.lod-cluster-label{all:unset;box-sizing:border-box;display:grid;gap:1px;text-align:center;cursor:pointer;pointer-events:auto;font-size:12px;font-weight:600;color:#f8fafc;padding:4px 11px 5px;border-radius:12px;white-space:nowrap;background:#03050b9e;border:1px solid color-mix(in srgb,var(--c, #818cf8) 60%,transparent);text-shadow:0 0 10px var(--c, #818cf8);box-shadow:0 0 18px color-mix(in srgb,var(--c, #818cf8) 22%,transparent);transition:border-color .2s,background .2s}.lod-cluster-label:hover{background:color-mix(in srgb,var(--c, #818cf8) 22%,rgba(3,5,11,.7));border-color:var(--c, #818cf8)}.lod-cluster-label b{font-weight:700;letter-spacing:-.01em}.lod-cluster-label small{font-size:10px;font-weight:500;color:#94a3b8;text-shadow:none;font-variant-numeric:tabular-nums}.hud-dock{display:flex;align-items:center;gap:8px}.hud-dock:empty{display:none}.hud-dock>.hud{position:static}.hud-lod{padding:6px 8px 6px 12px;display:flex;align-items:center;gap:8px;font-size:12px;color:#cbd5e1;white-space:nowrap}.hud-lod span b{margin:0 1px}.hud-lod b{color:#f1f5f9;font-variant-numeric:tabular-nums}.hud-lod i{width:7px;height:7px;border-radius:50%;background:#a5b4fc;box-shadow:0 0 8px #a5b4fc}.hud-lod button{all:unset;cursor:pointer;font-size:11px;padding:3px 9px;border-radius:999px;border:1px solid rgba(148,163,255,.25);color:#c7d2fe}.hud-lod button:hover{background:#818cf833;color:#f8fafc}.scene-root{container:agscene / size}@container agscene (max-width: 719px){.scene-root .hud-top{padding:5px 7px 5px 10px}.scene-root .hud-title{font-size:13px}.scene-root .hud-theme{padding:3px 20px 3px 8px;font-size:10px;background-position:right 7px center}.scene-root .hud-stat:nth-child(n+3){display:none}.scene-root .hud-side:not(.is-rail){width:min(290px,calc(100% - 64px));padding:6px 8px 8px}.scene-root .hs-head button{padding:4px 6px;letter-spacing:.04em;font-size:10.5px}.scene-root .hs-head .hs-collapse{padding:2px 4px}.scene-root .ap-list li button{padding:4px 6px}.scene-root .hud-topwrap:not(.is-rail){--hud-side: min(290px, calc(100% - 64px) )}}@container agscene (max-height: 520px){.scene-root .hud-sub{max-height:4.5em;overflow:auto}}@keyframes ap-wait-pulse{50%{box-shadow:0 0 10px #f59e0b8c;border-color:#fbbf24}}@media(prefers-reduced-motion:reduce){.ap-steps span[data-status=waiting]{animation:none}}.hud-approve{display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin-top:8px}.hud-approve button{border:1px solid transparent;border-radius:999px;padding:5px 13px;font:inherit;font-size:12px;font-weight:650;cursor:pointer}.hud-approve .ha-yes{background:linear-gradient(135deg,#34d399,#22d3ee);color:#03050b}.hud-approve .ha-no{background:#fb3b5c24;border-color:#fb718599;color:#fecdd3}.hud-approve .ha-yes:hover{filter:brightness(1.1)}.hud-approve .ha-no:hover{background:#fb3b5c47}.hud-approve span{font-size:11px;color:#94a3b8}.hud-approve[data-verdict=approved] span,.hud-approve[data-verdict=approving] span{color:#86efac}.hud-approve[data-verdict=rejected] span,.hud-approve[data-verdict=rejecting] span,.hud-approve[data-verdict=error] span{color:#fda4af}.hud-approve.is-compact{margin-top:0;flex:none;gap:4px}.hud-approve.is-compact button{padding:3px 9px;font-size:11px}.hud-approvals{left:12px;bottom:12px;z-index:9;width:max-content;max-width:min(460px,calc(100% - 356px));padding:8px 10px;font-size:12px;box-sizing:border-box;border-color:#f59e0b73;box-shadow:0 8px 32px #00000059,0 0 18px #f59e0b1f}.hud-approvals.is-rail{max-width:min(460px,calc(100% - 76px))}.hud-approvals h4{margin:0 0 6px;font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#fcd34d;display:flex;gap:6px;align-items:baseline}.hud-approvals h4 em{font-style:normal;font-variant-numeric:tabular-nums;color:#fde68a}.hud-approvals ul{list-style:none;margin:0;padding:0;display:grid;gap:4px}.hud-approvals .ha-late{font-style:normal}.hud-approvals .ha-late.is-due{color:#86efac}.hud-approvals .ha-late.is-overdue{color:#f59e0b;font-weight:600}.hud-approvals li{display:flex;align-items:center;gap:8px;min-width:0}.hud-approvals .ha-who{all:unset;cursor:pointer;flex:1;min-width:0;display:flex;align-items:baseline;gap:6px;padding:2px 4px;border-radius:6px}.hud-approvals .ha-who:hover{background:#94a3ff1a}.hud-approvals .ha-who i{flex:0 0 8px;height:8px;border-radius:50%;background:var(--c);box-shadow:0 0 8px var(--c);align-self:center}.hud-approvals .ha-who b{color:#e2e8f0;font-weight:650;white-space:nowrap}.hud-approvals .ha-who span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#fbbf24;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}.hud-approvals p{margin:6px 0 0;font-size:11px;color:#64748b}.hud-approvals .ha-details,.ap-approve-row .ha-details{all:unset;cursor:pointer;flex:none;font-size:11px;color:#cbd5e1;padding:3px 8px;border-radius:999px;border:1px solid rgba(148,163,255,.28)}.hud-approvals .ha-details:hover,.ap-approve-row .ha-details:hover,.hud-approvals .ha-details:focus-visible{border-color:#818cf8;color:#f1f5f9}.ap-approve-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.ap-approve-row .ha-details{margin-top:8px}.hud-drawer{top:64px;max-height:calc(100% - 76px);right:calc(var(--hud-side, 320px) + 24px);width:360px;max-width:calc(100% - var(--hud-side, 320px) - 48px);z-index:11;display:flex;flex-direction:column;gap:10px;padding:14px 14px 12px;box-sizing:border-box;overflow-y:auto;font-size:12px;outline:none;background:#0a0e1ac7;border-color:#f59e0b73;box-shadow:0 12px 40px #00000073,0 0 22px #f59e0b1a;animation:hd-in .18s ease-out}.hud-drawer.is-rail{--hud-side: 40px}@keyframes hd-in{0%{opacity:0;transform:translate(12px)}to{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.hud-drawer{animation:none}}.hud-drawer .hd-head{display:flex;align-items:flex-start;gap:8px}.hud-drawer .hd-head>div{flex:1;min-width:0}.hud-drawer .hd-kicker{margin:0 0 2px;font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#fcd34d}.hud-drawer h3{margin:0;font-size:15px;font-weight:700;line-height:1.3;color:#f1f5f9;overflow-wrap:anywhere}.hud-drawer .hd-close{all:unset;cursor:pointer;width:24px;height:24px;display:grid;place-items:center;border-radius:50%;font-size:17px;color:#94a3b8}.hud-drawer .hd-close:hover,.hud-drawer .hd-close:focus-visible{color:#f1f5f9;background:#94a3ff24}.hud-drawer .hd-who{all:unset;cursor:pointer;display:flex;align-items:baseline;gap:6px;min-width:0;padding:2px 4px;margin:-2px -4px;border-radius:6px}.hud-drawer .hd-who:hover{background:#94a3ff1a}.hud-drawer .hd-who i{flex:0 0 8px;height:8px;border-radius:50%;background:var(--c);box-shadow:0 0 8px var(--c);align-self:center}.hud-drawer .hd-who b{color:#e2e8f0;white-space:nowrap}.hud-drawer .hd-who span{color:#94a3b8;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hud-drawer .hd-deadline{align-self:flex-start;font-size:11px;font-variant-numeric:tabular-nums;color:#fde68a;padding:2px 9px;border-radius:999px;background:#f59e0b1f;border:1px solid rgba(245,158,11,.3)}.hud-drawer .hd-deadline.is-due{color:#86efac;background:#22c55e1f;border-color:#22c55e59}.hud-drawer .hd-deadline.is-overdue{color:#fbbf24;font-weight:650}.hud-drawer section h4{margin:0 0 5px;font-size:10px;text-transform:uppercase;letter-spacing:.08em;color:#64748b}.hud-drawer .hd-why{border-left:2px solid #5eead4;padding:2px 0 2px 8px}.hud-drawer .hd-why.is-deny{border-left-color:#fb7185}.hud-drawer .hd-why p{margin:0 0 4px;color:#e2e8f0;line-height:1.4}.hud-drawer .hd-why p b{font-size:9px;letter-spacing:.06em;color:#94a3b8;margin-right:2px}.hud-drawer .hd-why p em{font-style:normal;font-weight:700;color:#5eead4}.hud-drawer .hd-why.is-deny p em{color:#fda4af}.hud-drawer .hd-reason{margin:0;color:#fbbf24;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}.hud-drawer .hd-dl{display:grid;grid-template-columns:auto 1fr;gap:3px 12px;margin:0;font-size:11px}.hud-drawer .hd-dl div{display:contents}.hud-drawer .hd-dl dt{color:#64748b}.hud-drawer .hd-dl dd{margin:0;color:#e2e8f0;font-variant-numeric:tabular-nums;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hud-drawer .hd-details dd{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.hud-drawer .ap-decisions{margin:0}.hud-drawer .hd-foot{display:grid;gap:8px;padding-top:4px;border-top:1px solid rgba(148,163,255,.12)}.hud-drawer .hd-note{width:100%;box-sizing:border-box;resize:vertical;min-height:38px;margin-top:8px;padding:6px 8px;font:inherit;font-size:12px;color:#e2e8f0;background:#03050b8c;border:1px solid rgba(148,163,255,.22);border-radius:8px;outline:none}.hud-drawer .hd-note:focus{border-color:#818cf8}.hud-drawer .hud-approve{margin-top:0}.hud-drawer .hd-keys{margin:0;font-size:10px;color:#64748b}.hud-drawer .hd-links{display:flex;flex-wrap:wrap;gap:6px}.hud-drawer .hd-links a,.hud-drawer .hd-links button{all:unset;cursor:pointer;font-size:11px;color:#c7d2fe;padding:3px 9px;border-radius:999px;border:1px solid rgba(148,163,255,.28)}.hud-drawer .hd-links a:hover,.hud-drawer .hd-links button:hover,.hud-drawer .hd-links a:focus-visible,.hud-drawer .hd-links button:focus-visible{border-color:#818cf8;color:#f1f5f9}.hud-halotip{position:fixed;z-index:30;pointer-events:none;padding:5px 8px;border-radius:8px;font-size:11px;line-height:1.45;color:#cbd5e1;background:#0a0e1ae0;border:1px solid rgba(148,163,255,.22);font-variant-numeric:tabular-nums;white-space:nowrap}.hud-halotip b{color:#f1f5f9}@container agscene (max-width: 719px){.scene-root .hud-approvals{max-width:calc(100% - 76px);padding:6px 8px}.scene-root .hud-approvals .ha-who span{display:none}.scene-root .hud-drawer{left:8px;right:8px;top:auto;bottom:8px;width:auto;max-width:none;max-height:72%}}.hud-rejected{color:#fde68a}.hud-rejected b{color:#fbbf24}.ap-prim-dim{font-size:11px;color:#94a3b8;margin:3px 0 0;font-variant-numeric:tabular-nums}.ap-prim-bar{height:6px;border-radius:3px;overflow:hidden;background:#ffffff0f;margin-top:6px}.ap-prim-bar span{display:block;height:100%;background:#5eead4;box-shadow:0 0 8px #5eead480}.ap-skills span.ap-prim-stage{border-color:color-mix(in srgb,var(--c) 45%,transparent);background:color-mix(in srgb,var(--c) 8%,transparent)}.ap-skills span.ap-prim-stage.on{border-color:var(--c);color:#e6fffb;box-shadow:0 0 10px color-mix(in srgb,var(--c) 30%,transparent)}.ap-skills span.ap-prim-stage em{color:#94a3b8}.ap-prim-dl{display:grid;grid-template-columns:auto 1fr;gap:2px 10px;margin:0;font-size:11px}.ap-prim-dl div{display:contents}.ap-prim-dl dt{color:#64748b}.ap-prim-dl dd{margin:0;color:#e2e8f0;font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.flow-run{display:flex;flex-direction:column;align-items:center;gap:4px;pointer-events:none}.flow-run .scene-label{font-size:11px;max-width:220px;overflow:hidden;text-overflow:ellipsis}.flow-steps{display:flex;gap:3px;font:600 9px/1 ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase;letter-spacing:.06em}.flow-steps span{padding:2px 5px;border-radius:999px;color:#64748b;background:#03050b8c;border:1px solid rgba(100,116,139,.35)}.flow-steps span[data-s=running]{color:#03050b;background:var(--c);border-color:var(--c);box-shadow:0 0 12px var(--c)}.flow-steps span[data-s=done]{color:var(--c);border-color:color-mix(in srgb,var(--c) 60%,transparent)}.flow-steps span[data-s=failed]{color:#fecaca;background:#7f1d1d}.flow-step{font:600 9px/1 ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase;letter-spacing:.08em;color:color-mix(in srgb,var(--c) 70%,white);text-shadow:0 0 8px var(--c);opacity:.55;pointer-events:none;white-space:nowrap;transition:opacity .3s}.flow-step[data-s=running]{opacity:1}.flow-hint{font-size:10px;padding:1px 7px;opacity:.9}.flow-label-core{font-size:11px;letter-spacing:.04em}
@@ -0,0 +1,45 @@
1
+ import type { SpanProcessor } from "@opentelemetry/sdk-trace-node";
2
+ export type Attrs = Record<string, unknown>;
3
+ /** what `scrub` sees about the span besides its attributes */
4
+ export type SpanInfo = {
5
+ name: string;
6
+ kind: "internal" | "server" | "client" | "producer" | "consumer";
7
+ };
8
+ export type WatchOptions = {
9
+ /** service name (the agent in the scene); default env OTEL_SERVICE_NAME, else "node-app" */
10
+ service?: string;
11
+ /** AgentGlow server; default env AGENTGLOW_URL, else http://localhost:8100 */
12
+ url?: string;
13
+ /** sent as `x-api-key` (server `--ingest-key`); default env AGENTGLOW_API_KEY */
14
+ ingestKey?: string;
15
+ /** "strict" (default): attribute allowlist. "standard": keep other attributes, still drop headers / bodies / query
16
+ * strings / userinfo / identity keys and run the regex backstop on every string */
17
+ privacy?: "strict" | "standard";
18
+ /** extra scrub after the built-in rules: return new attributes (or mutate `attrs` and return nothing) */
19
+ scrub?: (attrs: Attrs, span: SpanInfo) => Attrs | void;
20
+ /** trace incoming HTTP requests (default true, except under Next.js, which makes its own request spans) */
21
+ incoming?: boolean;
22
+ /** incoming paths not traced (health checks): exact strings or regexes */
23
+ ignorePaths?: (string | RegExp)[];
24
+ };
25
+ export type Watch = {
26
+ /** export everything finished so far (call before a short script exits) */
27
+ flush(): Promise<void>;
28
+ /** flush, stop exporting and disable the instrumentations */
29
+ shutdown(): Promise<void>;
30
+ };
31
+ /** Regex backstop for any string: secrets, emails, phone numbers, long ids, query strings, URL userinfo. */
32
+ export declare function scrubText(s: string): string;
33
+ /** `/orders/123?x=1` -> `/orders/:id`: no query / fragment, id-looking segments (numbers, uuids, hex, long or
34
+ * digit-heavy tokens, emails) replaced with `:id`. Route templates (`/orders/:id`, `/orders/[id]`) pass unchanged. */
35
+ export declare function normalizePath(p: string): string;
36
+ /** The privacy rules of `watch()` for one span: returns the name and attributes that may leave the process. */
37
+ export declare function scrubSpan(name: string, kind: SpanInfo["kind"], attrs: Attrs, privacy?: "strict" | "standard", hook?: WatchOptions["scrub"]): {
38
+ name: string;
39
+ attributes: Attrs;
40
+ };
41
+ /** The span processor `watch()` uses (scrubbing + OTLP/HTTP JSON to `<url>/v1/traces`), for apps that already set up
42
+ * OpenTelemetry themselves (NodeSDK, @vercel/otel): add it to their `spanProcessors`. */
43
+ export declare function spanProcessor(opts?: Pick<WatchOptions, "url" | "ingestKey" | "privacy" | "scrub">): SpanProcessor;
44
+ /** Trace this Node.js process into AgentGlow. Idempotent per url; never throws because the server is down. */
45
+ export declare function watch(opts?: WatchOptions): Watch;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * `agentglow/pulse`: send flat events to an AgentGlow server from any JS/TS backend (Node >= 18, Deno, Bun, edge,
3
+ * browsers), no OpenTelemetry needed. POST /v1/events (docs/SPEC.md "Backend services" > "Flat events").
4
+ *
5
+ * import { pulse } from "agentglow/pulse";
6
+ * await pulse("http://localhost:8100", { service: "checkout", event: "request", name: "POST /pay", status: 200, duration_ms: 42 });
7
+ *
8
+ * Never throws: resolves false when the server is down or rejects the event (tracing must never break the app).
9
+ * No React / three.js: this entry is dependency-free.
10
+ */
11
+ export type PulseEvent = {
12
+ /** the service (or long-lived agent) the event belongs to; `agent` is an alias */
13
+ service?: string;
14
+ agent?: string;
15
+ /** request (default) | message | call | error | llm | tool; anything else counts as a request named after it */
16
+ event?: "request" | "message" | "call" | "error" | "llm" | "tool" | (string & {});
17
+ name?: string;
18
+ /** HTTP status (>= 500 = error) or "error" */
19
+ status?: number | string;
20
+ duration_ms?: number;
21
+ /** message: the consuming service; call: the external system (redis, postgres, payments-api) */
22
+ to?: string;
23
+ topic?: string;
24
+ /** call: db | warehouse | spark | api | storage | queue */
25
+ kind?: string;
26
+ tokens_in?: number;
27
+ tokens_out?: number;
28
+ /** scope (tenant / user) the event belongs to; the `?scope=` of the URL works too */
29
+ scope?: string;
30
+ };
31
+ export type PulseOptions = {
32
+ apiKey?: string;
33
+ timeoutMs?: number;
34
+ fetch?: typeof fetch;
35
+ };
36
+ /** POST one event or a batch to `<url>/v1/events`; `apiKey` is sent as `x-api-key` (server `--ingest-key`). */
37
+ export declare function pulse(url: string, event: PulseEvent | PulseEvent[], opts?: PulseOptions): Promise<boolean>;
@@ -1,6 +1,6 @@
1
1
  /** The AgentGlow themes (scene modules live in src/scenes/<theme>/index.tsx). */
2
2
  import type { ComponentType } from "react";
3
- export declare const THEMES: readonly ["neural", "constellation", "orbit", "atom", "flow"];
3
+ export declare const THEMES: readonly ["neural", "constellation", "orbit", "atom", "flow", "bubblechamber", "fireworks"];
4
4
  export type Theme = (typeof THEMES)[number];
5
5
  export declare const THEME_INFO: Record<Theme, {
6
6
  name: string;