@probelabs/visor 0.1.96 → 0.1.97
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 +6 -5
- package/dist/{168.index.js → 136.index.js} +5 -5
- package/dist/{272.index.js → 146.index.js} +5 -5
- package/dist/{13.index.js → 160.index.js} +5 -5
- package/dist/{421.index.js → 179.index.js} +3 -3
- package/dist/{85.index.js → 191.index.js} +5 -5
- package/dist/{544.index.js → 384.index.js} +3 -3
- package/dist/{861.index.js → 405.index.js} +3 -3
- package/dist/{320.index.js → 42.index.js} +3 -3
- package/dist/448.index.js +48 -0
- package/dist/{878.index.js → 491.index.js} +5 -5
- package/dist/663.index.js +321 -0
- package/dist/69.index.js +38 -0
- package/dist/{54.index.js → 760.index.js} +5 -5
- package/dist/80.index.js +263 -0
- package/dist/886.index.js +81 -0
- package/dist/917.index.js +82 -0
- package/dist/955.index.js +82 -0
- package/dist/ai-review-service.d.ts +2 -3
- package/dist/ai-review-service.d.ts.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/generated/config-schema.d.ts +18 -1
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +23 -1
- package/dist/index.js +191599 -155303
- package/dist/proto/protoc-gen-validate/LICENSE +202 -0
- package/dist/proto/protoc-gen-validate/validate/validate.proto +797 -0
- package/dist/proto/xds/LICENSE +201 -0
- package/dist/proto/xds/xds/data/orca/v3/orca_load_report.proto +58 -0
- package/dist/proto/xds/xds/service/orca/v3/orca.proto +36 -0
- package/dist/protoc-gen-validate/LICENSE +202 -0
- package/dist/protoc-gen-validate/validate/validate.proto +797 -0
- package/dist/providers/check-provider-registry.d.ts.map +1 -1
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/mcp-check-provider.d.ts +102 -0
- package/dist/providers/mcp-check-provider.d.ts.map +1 -0
- package/dist/sdk/check-execution-engine-S7BFPVWA.mjs +11 -0
- package/dist/sdk/{chunk-Q4S5A5TO.mjs → chunk-4VK6WTYU.mjs} +610 -21
- package/dist/sdk/chunk-4VK6WTYU.mjs.map +1 -0
- package/dist/sdk/chunk-IG3BFIIN.mjs +174 -0
- package/dist/sdk/chunk-IG3BFIIN.mjs.map +1 -0
- package/dist/sdk/chunk-YXOWIDEF.mjs +60 -0
- package/dist/sdk/chunk-YXOWIDEF.mjs.map +1 -0
- package/dist/sdk/{mermaid-telemetry-LZGDD35I.mjs → mermaid-telemetry-4DUEYCLE.mjs} +2 -2
- package/dist/sdk/sdk.d.mts +12 -1
- package/dist/sdk/sdk.d.ts +12 -1
- package/dist/sdk/sdk.js +1019 -1577
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +22 -4
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/{tracer-init-O7RLXMJ3.mjs → tracer-init-RJGAIOBP.mjs} +2 -2
- package/dist/session-registry.d.ts +2 -3
- package/dist/session-registry.d.ts.map +1 -1
- package/dist/traces/run-2025-10-19T14-24-36-341Z.ndjson +40 -0
- package/dist/traces/run-2025-10-19T14-24-48-674Z.ndjson +40 -0
- package/dist/traces/run-2025-10-19T14-24-49-238Z.ndjson +40 -0
- package/dist/traces/run-2025-10-19T14-24-49-761Z.ndjson +40 -0
- package/dist/traces/run-2025-10-19T14-24-50-279Z.ndjson +12 -0
- package/dist/types/config.d.ts +12 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/tracer-init.d.ts +3 -4
- package/dist/utils/tracer-init.d.ts.map +1 -1
- package/dist/xds/LICENSE +201 -0
- package/dist/xds/xds/data/orca/v3/orca_load_report.proto +58 -0
- package/dist/xds/xds/service/orca/v3/orca.proto +36 -0
- package/package.json +15 -8
- package/dist/sdk/check-execution-engine-NMPXJ7FQ.mjs +0 -11
- package/dist/sdk/chunk-KVHVCGY6.mjs +0 -103
- package/dist/sdk/chunk-KVHVCGY6.mjs.map +0 -1
- package/dist/sdk/chunk-Q4S5A5TO.mjs.map +0 -1
- package/dist/sdk/chunk-TWJKAYT6.mjs +0 -1124
- package/dist/sdk/chunk-TWJKAYT6.mjs.map +0 -1
- /package/dist/{traces/run-2025-10-18T20-24-27-886Z.ndjson → output/traces/run-2025-10-19T14-24-36-341Z.ndjson} +0 -0
- /package/dist/{traces/run-2025-10-18T20-24-38-817Z.ndjson → output/traces/run-2025-10-19T14-24-48-674Z.ndjson} +0 -0
- /package/dist/{traces/run-2025-10-18T20-24-39-361Z.ndjson → output/traces/run-2025-10-19T14-24-49-238Z.ndjson} +0 -0
- /package/dist/{traces/run-2025-10-18T20-24-39-852Z.ndjson → output/traces/run-2025-10-19T14-24-49-761Z.ndjson} +0 -0
- /package/dist/{traces/run-2025-10-18T20-24-40-335Z.ndjson → output/traces/run-2025-10-19T14-24-50-279Z.ndjson} +0 -0
- /package/dist/sdk/{check-execution-engine-NMPXJ7FQ.mjs.map → check-execution-engine-S7BFPVWA.mjs.map} +0 -0
- /package/dist/sdk/{mermaid-telemetry-LZGDD35I.mjs.map → mermaid-telemetry-4DUEYCLE.mjs.map} +0 -0
- /package/dist/sdk/{tracer-init-O7RLXMJ3.mjs.map → tracer-init-RJGAIOBP.mjs.map} +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__esm,
|
|
3
|
+
__export,
|
|
4
|
+
__toCommonJS
|
|
5
|
+
} from "./chunk-WMJKH4XE.mjs";
|
|
6
|
+
|
|
7
|
+
// src/telemetry/fallback-ndjson.ts
|
|
8
|
+
var fallback_ndjson_exports = {};
|
|
9
|
+
__export(fallback_ndjson_exports, {
|
|
10
|
+
emitNdjsonFallback: () => emitNdjsonFallback,
|
|
11
|
+
emitNdjsonSpanWithEvents: () => emitNdjsonSpanWithEvents,
|
|
12
|
+
flushNdjson: () => flushNdjson
|
|
13
|
+
});
|
|
14
|
+
import * as fs from "fs";
|
|
15
|
+
import * as path from "path";
|
|
16
|
+
function resolveTargetPath(outDir) {
|
|
17
|
+
if (process.env.VISOR_FALLBACK_TRACE_FILE) {
|
|
18
|
+
CURRENT_FILE = process.env.VISOR_FALLBACK_TRACE_FILE;
|
|
19
|
+
return CURRENT_FILE;
|
|
20
|
+
}
|
|
21
|
+
if (CURRENT_FILE) return CURRENT_FILE;
|
|
22
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
23
|
+
CURRENT_FILE = path.join(outDir, `${ts}.ndjson`);
|
|
24
|
+
return CURRENT_FILE;
|
|
25
|
+
}
|
|
26
|
+
function isEnabled() {
|
|
27
|
+
if (process.env.VISOR_FALLBACK_TRACE_FILE) return true;
|
|
28
|
+
return process.env.VISOR_TELEMETRY_ENABLED === "true" && (process.env.VISOR_TELEMETRY_SINK || "file") === "file";
|
|
29
|
+
}
|
|
30
|
+
function appendAsync(outDir, line) {
|
|
31
|
+
writeChain = writeChain.then(async () => {
|
|
32
|
+
if (!dirReady) {
|
|
33
|
+
try {
|
|
34
|
+
await fs.promises.mkdir(outDir, { recursive: true });
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
dirReady = true;
|
|
38
|
+
}
|
|
39
|
+
const target = resolveTargetPath(outDir);
|
|
40
|
+
await fs.promises.appendFile(target, line, "utf8");
|
|
41
|
+
}).catch(() => {
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async function flushNdjson() {
|
|
45
|
+
try {
|
|
46
|
+
await writeChain;
|
|
47
|
+
} catch {
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function emitNdjsonFallback(name, attrs) {
|
|
51
|
+
try {
|
|
52
|
+
if (!isEnabled()) return;
|
|
53
|
+
const outDir = process.env.VISOR_TRACE_DIR || path.join(process.cwd(), "output", "traces");
|
|
54
|
+
const line = JSON.stringify({ name, attributes: attrs }) + "\n";
|
|
55
|
+
appendAsync(outDir, line);
|
|
56
|
+
} catch {
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function emitNdjsonSpanWithEvents(name, attrs, events) {
|
|
60
|
+
try {
|
|
61
|
+
if (!isEnabled()) return;
|
|
62
|
+
const outDir = process.env.VISOR_TRACE_DIR || path.join(process.cwd(), "output", "traces");
|
|
63
|
+
const line = JSON.stringify({ name, attributes: attrs, events }) + "\n";
|
|
64
|
+
appendAsync(outDir, line);
|
|
65
|
+
} catch {
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
var CURRENT_FILE, dirReady, writeChain;
|
|
69
|
+
var init_fallback_ndjson = __esm({
|
|
70
|
+
"src/telemetry/fallback-ndjson.ts"() {
|
|
71
|
+
"use strict";
|
|
72
|
+
CURRENT_FILE = null;
|
|
73
|
+
dirReady = false;
|
|
74
|
+
writeChain = Promise.resolve();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// src/telemetry/trace-helpers.ts
|
|
79
|
+
import { context as otContext, SpanStatusCode, trace } from "@opentelemetry/api";
|
|
80
|
+
function addEvent(name, attrs) {
|
|
81
|
+
const span = trace.getSpan(otContext.active());
|
|
82
|
+
if (span) {
|
|
83
|
+
try {
|
|
84
|
+
span.addEvent(name, attrs);
|
|
85
|
+
} catch {
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const { emitNdjsonSpanWithEvents: emitNdjsonSpanWithEvents2 } = (init_fallback_ndjson(), __toCommonJS(fallback_ndjson_exports));
|
|
90
|
+
emitNdjsonSpanWithEvents2("visor.event", {}, [{ name, attrs }]);
|
|
91
|
+
if (name === "fail_if.triggered") {
|
|
92
|
+
emitNdjsonSpanWithEvents2("visor.event", {}, [
|
|
93
|
+
{ name: "fail_if.evaluated", attrs },
|
|
94
|
+
{ name: "fail_if.triggered", attrs }
|
|
95
|
+
]);
|
|
96
|
+
}
|
|
97
|
+
} catch {
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/telemetry/metrics.ts
|
|
102
|
+
import { metrics } from "@opentelemetry/api";
|
|
103
|
+
var initialized = false;
|
|
104
|
+
var meter = metrics.getMeter("visor");
|
|
105
|
+
var TEST_ENABLED = process.env.VISOR_TEST_METRICS === "true";
|
|
106
|
+
var TEST_SNAPSHOT = { fail_if_triggered: 0 };
|
|
107
|
+
var checkDurationHist;
|
|
108
|
+
var providerDurationHist;
|
|
109
|
+
var foreachDurationHist;
|
|
110
|
+
var issuesCounter;
|
|
111
|
+
var activeChecks;
|
|
112
|
+
var failIfCounter;
|
|
113
|
+
var diagramBlocks;
|
|
114
|
+
function ensureInstruments() {
|
|
115
|
+
if (initialized) return;
|
|
116
|
+
try {
|
|
117
|
+
checkDurationHist = meter.createHistogram("visor.check.duration_ms", {
|
|
118
|
+
description: "Duration of a check execution in milliseconds",
|
|
119
|
+
unit: "ms"
|
|
120
|
+
});
|
|
121
|
+
providerDurationHist = meter.createHistogram("visor.provider.duration_ms", {
|
|
122
|
+
description: "Duration of provider execution in milliseconds",
|
|
123
|
+
unit: "ms"
|
|
124
|
+
});
|
|
125
|
+
foreachDurationHist = meter.createHistogram("visor.foreach.item.duration_ms", {
|
|
126
|
+
description: "Duration of a forEach item execution in milliseconds",
|
|
127
|
+
unit: "ms"
|
|
128
|
+
});
|
|
129
|
+
issuesCounter = meter.createCounter("visor.check.issues", {
|
|
130
|
+
description: "Number of issues produced by checks",
|
|
131
|
+
unit: "1"
|
|
132
|
+
});
|
|
133
|
+
activeChecks = meter.createUpDownCounter("visor.run.active_checks", {
|
|
134
|
+
description: "Number of checks actively running",
|
|
135
|
+
unit: "1"
|
|
136
|
+
});
|
|
137
|
+
failIfCounter = meter.createCounter("visor.fail_if.triggered", {
|
|
138
|
+
description: "Number of times fail_if condition triggered",
|
|
139
|
+
unit: "1"
|
|
140
|
+
});
|
|
141
|
+
diagramBlocks = meter.createCounter("visor.diagram.blocks", {
|
|
142
|
+
description: "Number of Mermaid diagram blocks emitted",
|
|
143
|
+
unit: "1"
|
|
144
|
+
});
|
|
145
|
+
initialized = true;
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function addFailIfTriggered(check, scope) {
|
|
150
|
+
ensureInstruments();
|
|
151
|
+
try {
|
|
152
|
+
failIfCounter?.add(1, { "visor.check.id": check, scope });
|
|
153
|
+
} catch {
|
|
154
|
+
}
|
|
155
|
+
if (TEST_ENABLED) TEST_SNAPSHOT.fail_if_triggered++;
|
|
156
|
+
}
|
|
157
|
+
function addDiagramBlock(origin) {
|
|
158
|
+
ensureInstruments();
|
|
159
|
+
try {
|
|
160
|
+
diagramBlocks?.add(1, { origin });
|
|
161
|
+
} catch {
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export {
|
|
166
|
+
emitNdjsonFallback,
|
|
167
|
+
emitNdjsonSpanWithEvents,
|
|
168
|
+
fallback_ndjson_exports,
|
|
169
|
+
init_fallback_ndjson,
|
|
170
|
+
addEvent,
|
|
171
|
+
addFailIfTriggered,
|
|
172
|
+
addDiagramBlock
|
|
173
|
+
};
|
|
174
|
+
//# sourceMappingURL=chunk-IG3BFIIN.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/telemetry/fallback-ndjson.ts","../../src/telemetry/trace-helpers.ts","../../src/telemetry/metrics.ts"],"sourcesContent":["import * as fs from 'fs';\nimport * as path from 'path';\n\nlet CURRENT_FILE: string | null = null;\nlet dirReady = false;\nlet writeChain: Promise<void> = Promise.resolve();\nfunction resolveTargetPath(outDir: string): string {\n if (process.env.VISOR_FALLBACK_TRACE_FILE) {\n CURRENT_FILE = process.env.VISOR_FALLBACK_TRACE_FILE;\n return CURRENT_FILE;\n }\n if (CURRENT_FILE) return CURRENT_FILE;\n const ts = new Date().toISOString().replace(/[:.]/g, '-');\n CURRENT_FILE = path.join(outDir, `${ts}.ndjson`);\n return CURRENT_FILE;\n}\n\nfunction isEnabled(): boolean {\n // Enable when CLI set a fallback file (serverless mode), or when explicit file sink is enabled\n if (process.env.VISOR_FALLBACK_TRACE_FILE) return true;\n return (\n process.env.VISOR_TELEMETRY_ENABLED === 'true' &&\n (process.env.VISOR_TELEMETRY_SINK || 'file') === 'file'\n );\n}\n\nfunction appendAsync(outDir: string, line: string): void {\n writeChain = writeChain\n .then(async () => {\n if (!dirReady) {\n try {\n await fs.promises.mkdir(outDir, { recursive: true });\n } catch {}\n dirReady = true;\n }\n const target = resolveTargetPath(outDir);\n await fs.promises.appendFile(target, line, 'utf8');\n })\n .catch(() => {});\n}\n\nexport async function flushNdjson(): Promise<void> {\n try {\n await writeChain;\n } catch {}\n}\n\nexport function emitNdjsonFallback(name: string, attrs: Record<string, unknown>): void {\n try {\n if (!isEnabled()) return;\n const outDir = process.env.VISOR_TRACE_DIR || path.join(process.cwd(), 'output', 'traces');\n const line = JSON.stringify({ name, attributes: attrs }) + '\\n';\n appendAsync(outDir, line);\n } catch {\n // ignore\n }\n}\n\nexport function emitNdjsonSpanWithEvents(\n name: string,\n attrs: Record<string, unknown>,\n events: Array<{ name: string; attrs?: Record<string, unknown> }>\n): void {\n try {\n if (!isEnabled()) return;\n const outDir = process.env.VISOR_TRACE_DIR || path.join(process.cwd(), 'output', 'traces');\n const line = JSON.stringify({ name, attributes: attrs, events }) + '\\n';\n appendAsync(outDir, line);\n } catch {\n // ignore\n }\n}\n","import { context as otContext, Span, SpanStatusCode, trace, Attributes } from '@opentelemetry/api';\n\nexport function getTracer() {\n return trace.getTracer('visor');\n}\n\nexport async function withActiveSpan<T>(\n name: string,\n attrs: Record<string, unknown> | undefined,\n fn: (span: Span) => Promise<T>\n): Promise<T> {\n const tracer = getTracer();\n return await new Promise<T>((resolve, reject) => {\n const callback = async (span: Span) => {\n try {\n const res = await fn(span);\n resolve(res);\n } catch (err) {\n try {\n if (err instanceof Error) span.recordException(err);\n span.setStatus({ code: SpanStatusCode.ERROR });\n } catch {}\n reject(err);\n } finally {\n try {\n span.end();\n } catch {}\n }\n };\n if (attrs) {\n tracer.startActiveSpan(name, { attributes: attrs as Attributes }, callback);\n } else {\n tracer.startActiveSpan(name, callback as (span: Span) => void);\n }\n });\n}\n\nexport function addEvent(name: string, attrs?: Record<string, unknown>): void {\n const span = trace.getSpan(otContext.active());\n if (span) {\n try {\n span.addEvent(name, attrs as Attributes);\n } catch {\n // ignore\n }\n }\n // Fallback NDJSON emission for serverless/file sink when SDK may be inactive\n try {\n const { emitNdjsonSpanWithEvents } = require('./fallback-ndjson');\n emitNdjsonSpanWithEvents('visor.event', {}, [{ name, attrs }]);\n if (name === 'fail_if.triggered') {\n emitNdjsonSpanWithEvents('visor.event', {}, [\n { name: 'fail_if.evaluated', attrs },\n { name: 'fail_if.triggered', attrs },\n ]);\n }\n } catch {}\n}\n\nexport function setSpanAttributes(attrs: Record<string, unknown>): void {\n const span = trace.getSpan(otContext.active());\n if (!span) return;\n try {\n for (const [k, v] of Object.entries(attrs)) span.setAttribute(k, v as never);\n } catch {\n // ignore\n }\n}\n\nexport function setSpanError(err: unknown): void {\n const span = trace.getSpan(otContext.active());\n if (!span) return;\n try {\n if (err instanceof Error) span.recordException(err);\n span.setStatus({ code: SpanStatusCode.ERROR });\n } catch {\n // ignore\n }\n}\n\n// Internal helper for tests: write a minimal run marker to NDJSON when using file sink\nlet __ndjsonPath: string | null = null;\nexport function __getOrCreateNdjsonPath(): string | null {\n try {\n if (process.env.VISOR_TELEMETRY_SINK !== 'file') return null;\n const path = require('path');\n const fs = require('fs');\n // Prefer explicit fallback file path if set by the CLI\n if (process.env.VISOR_FALLBACK_TRACE_FILE) {\n __ndjsonPath = process.env.VISOR_FALLBACK_TRACE_FILE;\n const dir = path.dirname(__ndjsonPath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n return __ndjsonPath;\n }\n const outDir = process.env.VISOR_TRACE_DIR || path.join(process.cwd(), 'output', 'traces');\n if (!fs.existsSync(outDir)) fs.mkdirSync(outDir, { recursive: true });\n if (!__ndjsonPath) {\n const ts = new Date().toISOString().replace(/[:.]/g, '-');\n __ndjsonPath = path.join(outDir, `${ts}.ndjson`);\n }\n return __ndjsonPath;\n } catch {\n return null;\n }\n}\nexport function _appendRunMarker(): void {\n try {\n const fs = require('fs');\n const p = __getOrCreateNdjsonPath();\n if (!p) return;\n const line = { name: 'visor.run', attributes: { started: true } };\n fs.appendFileSync(p, JSON.stringify(line) + '\\n', 'utf8');\n } catch {}\n}\n","import { metrics } from '@opentelemetry/api';\n\nlet initialized = false;\nconst meter = metrics.getMeter('visor');\n\n// Test helpers (enabled with VISOR_TEST_METRICS=true)\nconst TEST_ENABLED = process.env.VISOR_TEST_METRICS === 'true';\nconst TEST_SNAPSHOT: { [k: string]: number } = { fail_if_triggered: 0 };\n\n// Instruments (lazily created when first used)\nlet checkDurationHist: ReturnType<typeof meter.createHistogram> | undefined;\nlet providerDurationHist: ReturnType<typeof meter.createHistogram> | undefined;\nlet foreachDurationHist: ReturnType<typeof meter.createHistogram> | undefined;\nlet issuesCounter: ReturnType<typeof meter.createCounter> | undefined;\nlet activeChecks: ReturnType<typeof meter.createUpDownCounter> | undefined;\nlet failIfCounter: ReturnType<typeof meter.createCounter> | undefined;\nlet diagramBlocks: ReturnType<typeof meter.createCounter> | undefined;\n\nfunction ensureInstruments() {\n if (initialized) return;\n try {\n checkDurationHist = meter.createHistogram('visor.check.duration_ms', {\n description: 'Duration of a check execution in milliseconds',\n unit: 'ms',\n });\n providerDurationHist = meter.createHistogram('visor.provider.duration_ms', {\n description: 'Duration of provider execution in milliseconds',\n unit: 'ms',\n });\n foreachDurationHist = meter.createHistogram('visor.foreach.item.duration_ms', {\n description: 'Duration of a forEach item execution in milliseconds',\n unit: 'ms',\n });\n issuesCounter = meter.createCounter('visor.check.issues', {\n description: 'Number of issues produced by checks',\n unit: '1',\n });\n activeChecks = meter.createUpDownCounter('visor.run.active_checks', {\n description: 'Number of checks actively running',\n unit: '1',\n });\n failIfCounter = meter.createCounter('visor.fail_if.triggered', {\n description: 'Number of times fail_if condition triggered',\n unit: '1',\n });\n diagramBlocks = meter.createCounter('visor.diagram.blocks', {\n description: 'Number of Mermaid diagram blocks emitted',\n unit: '1',\n });\n initialized = true;\n } catch {\n // Metrics may be unavailable if SDK not initialized; ignore gracefully\n }\n}\n\nexport function recordCheckDuration(check: string, durationMs: number, group?: string) {\n ensureInstruments();\n try {\n checkDurationHist?.record(durationMs, {\n 'visor.check.id': check,\n 'visor.check.group': group || 'default',\n });\n } catch {}\n}\n\nexport function recordProviderDuration(check: string, providerType: string, durationMs: number) {\n ensureInstruments();\n try {\n providerDurationHist?.record(durationMs, {\n 'visor.check.id': check,\n 'visor.provider.type': providerType,\n });\n } catch {}\n}\n\nexport function recordForEachDuration(\n check: string,\n index: number,\n total: number,\n durationMs: number\n) {\n ensureInstruments();\n try {\n foreachDurationHist?.record(durationMs, {\n 'visor.check.id': check,\n 'visor.foreach.index': index,\n 'visor.foreach.total': total,\n });\n } catch {}\n}\n\nexport function addIssues(check: string, severity: string, count = 1) {\n ensureInstruments();\n try {\n issuesCounter?.add(count, {\n 'visor.check.id': check,\n severity,\n });\n } catch {}\n}\n\nexport function incActiveCheck(check: string) {\n ensureInstruments();\n try {\n activeChecks?.add(1, { 'visor.check.id': check });\n } catch {}\n}\n\nexport function decActiveCheck(check: string) {\n ensureInstruments();\n try {\n activeChecks?.add(-1, { 'visor.check.id': check });\n } catch {}\n}\n\nexport function addFailIfTriggered(check: string, scope: 'global' | 'check') {\n ensureInstruments();\n try {\n failIfCounter?.add(1, { 'visor.check.id': check, scope });\n } catch {}\n if (TEST_ENABLED) TEST_SNAPSHOT.fail_if_triggered++;\n}\n\nexport function addDiagramBlock(origin: 'content' | 'issue') {\n ensureInstruments();\n try {\n diagramBlocks?.add(1, { origin });\n } catch {}\n}\n\nexport function getTestMetricsSnapshot() {\n return { ...TEST_SNAPSHOT };\n}\n\nexport function resetTestMetricsSnapshot() {\n Object.keys(TEST_SNAPSHOT).forEach(k => (TEST_SNAPSHOT[k] = 0));\n}\n"],"mappings":"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","names":["emitNdjsonSpanWithEvents"]}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__esm
|
|
3
|
+
} from "./chunk-WMJKH4XE.mjs";
|
|
4
|
+
|
|
5
|
+
// src/utils/tracer-init.ts
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
import * as fs from "fs";
|
|
8
|
+
import { SimpleTelemetry, SimpleAppTracer } from "@probelabs/probe";
|
|
9
|
+
async function initializeTracer(sessionId, checkName) {
|
|
10
|
+
try {
|
|
11
|
+
if (SimpleTelemetry && SimpleAppTracer) {
|
|
12
|
+
const sanitizedCheckName = checkName ? path.basename(checkName) : "check";
|
|
13
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
14
|
+
const traceDir = process.env.GITHUB_WORKSPACE ? path.join(process.env.GITHUB_WORKSPACE, "debug-artifacts") : path.join(process.cwd(), "debug-artifacts");
|
|
15
|
+
if (!fs.existsSync(traceDir)) {
|
|
16
|
+
fs.mkdirSync(traceDir, { recursive: true });
|
|
17
|
+
}
|
|
18
|
+
const traceFilePath = path.join(traceDir, `trace-${sanitizedCheckName}-${timestamp}.jsonl`);
|
|
19
|
+
const resolvedTracePath = path.resolve(traceFilePath);
|
|
20
|
+
const resolvedTraceDir = path.resolve(traceDir);
|
|
21
|
+
if (!resolvedTracePath.startsWith(resolvedTraceDir)) {
|
|
22
|
+
console.error(
|
|
23
|
+
`\u26A0\uFE0F Security: Attempted path traversal detected. Check name: ${checkName}, resolved path: ${resolvedTracePath}`
|
|
24
|
+
);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
const telemetry = new SimpleTelemetry({
|
|
28
|
+
enableFile: true,
|
|
29
|
+
filePath: traceFilePath,
|
|
30
|
+
enableConsole: false
|
|
31
|
+
});
|
|
32
|
+
const tracer = new SimpleAppTracer(telemetry, sessionId);
|
|
33
|
+
console.error(`\u{1F4CA} Simple tracing enabled, will save to: ${traceFilePath}`);
|
|
34
|
+
if (process.env.GITHUB_ACTIONS) {
|
|
35
|
+
console.log(`::notice title=AI Trace::Trace will be saved to ${traceFilePath}`);
|
|
36
|
+
console.log(`::set-output name=trace-path::${traceFilePath}`);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
tracer,
|
|
40
|
+
telemetryConfig: telemetry,
|
|
41
|
+
filePath: traceFilePath
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
console.error("\u26A0\uFE0F Telemetry classes not available in ProbeAgent, skipping tracing");
|
|
45
|
+
return null;
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error("\u26A0\uFE0F Warning: Failed to initialize tracing:", error);
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
var init_tracer_init = __esm({
|
|
52
|
+
"src/utils/tracer-init.ts"() {
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
initializeTracer,
|
|
58
|
+
init_tracer_init
|
|
59
|
+
};
|
|
60
|
+
//# sourceMappingURL=chunk-YXOWIDEF.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/tracer-init.ts"],"sourcesContent":["import * as path from 'path';\nimport * as fs from 'fs';\nimport { SimpleTelemetry, SimpleAppTracer } from '@probelabs/probe';\n\n/**\n * Safely initialize a tracer for ProbeAgent with proper path sanitization\n * Uses SimpleTelemetry for lightweight tracing\n * This prevents path traversal vulnerabilities by sanitizing the checkName\n */\nexport async function initializeTracer(\n sessionId: string,\n checkName?: string\n): Promise<{ tracer: unknown; telemetryConfig: unknown; filePath: string } | null> {\n try {\n // Use SimpleTelemetry (probe no longer exports full OpenTelemetry classes)\n if (SimpleTelemetry && SimpleAppTracer) {\n // SECURITY: Sanitize checkName to prevent path traversal attacks\n const sanitizedCheckName = checkName ? path.basename(checkName) : 'check';\n\n // Create trace file path in debug-artifacts directory\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const traceDir = process.env.GITHUB_WORKSPACE\n ? path.join(process.env.GITHUB_WORKSPACE, 'debug-artifacts')\n : path.join(process.cwd(), 'debug-artifacts');\n\n // Create traces directory if it doesn't exist\n if (!fs.existsSync(traceDir)) {\n fs.mkdirSync(traceDir, { recursive: true });\n }\n\n // SECURITY: Use path.join to safely construct the path\n const traceFilePath = path.join(traceDir, `trace-${sanitizedCheckName}-${timestamp}.jsonl`);\n\n // SECURITY: Verify the resolved path is within the intended directory\n const resolvedTracePath = path.resolve(traceFilePath);\n const resolvedTraceDir = path.resolve(traceDir);\n if (!resolvedTracePath.startsWith(resolvedTraceDir)) {\n console.error(\n `⚠️ Security: Attempted path traversal detected. Check name: ${checkName}, resolved path: ${resolvedTracePath}`\n );\n return null;\n }\n\n // Initialize simple telemetry\n const telemetry = new SimpleTelemetry({\n enableFile: true,\n filePath: traceFilePath,\n enableConsole: false,\n });\n\n const tracer = new SimpleAppTracer(telemetry, sessionId);\n\n console.error(`📊 Simple tracing enabled, will save to: ${traceFilePath}`);\n\n // If in GitHub Actions, log the path for artifact upload\n if (process.env.GITHUB_ACTIONS) {\n console.log(`::notice title=AI Trace::Trace will be saved to ${traceFilePath}`);\n console.log(`::set-output name=trace-path::${traceFilePath}`);\n }\n\n // Return with SimpleTelemetry\n return {\n tracer,\n telemetryConfig: telemetry,\n filePath: traceFilePath,\n };\n }\n\n console.error('⚠️ Telemetry classes not available in ProbeAgent, skipping tracing');\n return null;\n } catch (error) {\n console.error('⚠️ Warning: Failed to initialize tracing:', error);\n return null;\n }\n}\n"],"mappings":";;;;;AAAA,YAAY,UAAU;AACtB,YAAY,QAAQ;AACpB,SAAS,iBAAiB,uBAAuB;AAOjD,eAAsB,iBACpB,WACA,WACiF;AACjF,MAAI;AAEF,QAAI,mBAAmB,iBAAiB;AAEtC,YAAM,qBAAqB,YAAiB,cAAS,SAAS,IAAI;AAGlE,YAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,SAAS,GAAG;AAC/D,YAAM,WAAW,QAAQ,IAAI,mBACpB,UAAK,QAAQ,IAAI,kBAAkB,iBAAiB,IACpD,UAAK,QAAQ,IAAI,GAAG,iBAAiB;AAG9C,UAAI,CAAI,cAAW,QAAQ,GAAG;AAC5B,QAAG,aAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,MAC5C;AAGA,YAAM,gBAAqB,UAAK,UAAU,SAAS,kBAAkB,IAAI,SAAS,QAAQ;AAG1F,YAAM,oBAAyB,aAAQ,aAAa;AACpD,YAAM,mBAAwB,aAAQ,QAAQ;AAC9C,UAAI,CAAC,kBAAkB,WAAW,gBAAgB,GAAG;AACnD,gBAAQ;AAAA,UACN,yEAA+D,SAAS,oBAAoB,iBAAiB;AAAA,QAC/G;AACA,eAAO;AAAA,MACT;AAGA,YAAM,YAAY,IAAI,gBAAgB;AAAA,QACpC,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,eAAe;AAAA,MACjB,CAAC;AAED,YAAM,SAAS,IAAI,gBAAgB,WAAW,SAAS;AAEvD,cAAQ,MAAM,mDAA4C,aAAa,EAAE;AAGzE,UAAI,QAAQ,IAAI,gBAAgB;AAC9B,gBAAQ,IAAI,mDAAmD,aAAa,EAAE;AAC9E,gBAAQ,IAAI,iCAAiC,aAAa,EAAE;AAAA,MAC9D;AAGA,aAAO;AAAA,QACL;AAAA,QACA,iBAAiB;AAAA,QACjB,UAAU;AAAA,MACZ;AAAA,IACF;AAEA,YAAQ,MAAM,8EAAoE;AAClF,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,uDAA6C,KAAK;AAChE,WAAO;AAAA,EACT;AACF;AA1EA;AAAA;AAAA;AAAA;","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
addDiagramBlock,
|
|
3
3
|
addEvent
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-IG3BFIIN.mjs";
|
|
5
5
|
import "./chunk-WMJKH4XE.mjs";
|
|
6
6
|
|
|
7
7
|
// src/utils/mermaid-telemetry.ts
|
|
@@ -58,4 +58,4 @@ function emitMermaidFromMarkdown(checkName, markdown, origin) {
|
|
|
58
58
|
export {
|
|
59
59
|
emitMermaidFromMarkdown
|
|
60
60
|
};
|
|
61
|
-
//# sourceMappingURL=mermaid-telemetry-
|
|
61
|
+
//# sourceMappingURL=mermaid-telemetry-4DUEYCLE.mjs.map
|
package/dist/sdk/sdk.d.mts
CHANGED
|
@@ -120,7 +120,7 @@ interface FailureConditionResult {
|
|
|
120
120
|
/**
|
|
121
121
|
* Valid check types in configuration
|
|
122
122
|
*/
|
|
123
|
-
type ConfigCheckType = 'ai' | 'command' | 'http' | 'http_input' | 'http_client' | 'noop' | 'log' | 'memory' | 'github' | 'claude-code';
|
|
123
|
+
type ConfigCheckType = 'ai' | 'command' | 'http' | 'http_input' | 'http_client' | 'noop' | 'log' | 'memory' | 'github' | 'claude-code' | 'mcp';
|
|
124
124
|
/**
|
|
125
125
|
* Valid event triggers for checks
|
|
126
126
|
*/
|
|
@@ -314,6 +314,17 @@ interface CheckConfig {
|
|
|
314
314
|
op?: string;
|
|
315
315
|
/** Values for GitHub operations (can be array or single value) */
|
|
316
316
|
values?: string[] | string;
|
|
317
|
+
/**
|
|
318
|
+
* MCP provider specific options (optional, only used when type === 'mcp').
|
|
319
|
+
*/
|
|
320
|
+
/** Transport type for MCP: stdio (default), sse (legacy), or http (streamable HTTP) */
|
|
321
|
+
transport?: 'stdio' | 'sse' | 'http';
|
|
322
|
+
/** Arguments to pass to the MCP method (supports Liquid templates) */
|
|
323
|
+
methodArgs?: Record<string, unknown>;
|
|
324
|
+
/** Transform template for method arguments (Liquid) */
|
|
325
|
+
argsTransform?: string;
|
|
326
|
+
/** Session ID for HTTP transport (optional, server may generate one) */
|
|
327
|
+
sessionId?: string;
|
|
317
328
|
}
|
|
318
329
|
/**
|
|
319
330
|
* Backoff policy for retries
|
package/dist/sdk/sdk.d.ts
CHANGED
|
@@ -120,7 +120,7 @@ interface FailureConditionResult {
|
|
|
120
120
|
/**
|
|
121
121
|
* Valid check types in configuration
|
|
122
122
|
*/
|
|
123
|
-
type ConfigCheckType = 'ai' | 'command' | 'http' | 'http_input' | 'http_client' | 'noop' | 'log' | 'memory' | 'github' | 'claude-code';
|
|
123
|
+
type ConfigCheckType = 'ai' | 'command' | 'http' | 'http_input' | 'http_client' | 'noop' | 'log' | 'memory' | 'github' | 'claude-code' | 'mcp';
|
|
124
124
|
/**
|
|
125
125
|
* Valid event triggers for checks
|
|
126
126
|
*/
|
|
@@ -314,6 +314,17 @@ interface CheckConfig {
|
|
|
314
314
|
op?: string;
|
|
315
315
|
/** Values for GitHub operations (can be array or single value) */
|
|
316
316
|
values?: string[] | string;
|
|
317
|
+
/**
|
|
318
|
+
* MCP provider specific options (optional, only used when type === 'mcp').
|
|
319
|
+
*/
|
|
320
|
+
/** Transport type for MCP: stdio (default), sse (legacy), or http (streamable HTTP) */
|
|
321
|
+
transport?: 'stdio' | 'sse' | 'http';
|
|
322
|
+
/** Arguments to pass to the MCP method (supports Liquid templates) */
|
|
323
|
+
methodArgs?: Record<string, unknown>;
|
|
324
|
+
/** Transform template for method arguments (Liquid) */
|
|
325
|
+
argsTransform?: string;
|
|
326
|
+
/** Session ID for HTTP transport (optional, server may generate one) */
|
|
327
|
+
sessionId?: string;
|
|
317
328
|
}
|
|
318
329
|
/**
|
|
319
330
|
* Backoff policy for retries
|