@merittdev/horus 0.21.7 → 0.21.8
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/horus_source.whl +0 -0
- package/dist/index.cjs +628 -24
- package/package.json +1 -1
package/dist/horus_source.whl
CHANGED
|
Binary file
|
package/dist/index.cjs
CHANGED
|
@@ -3057,7 +3057,7 @@ var init_version = __esm({
|
|
|
3057
3057
|
"../../packages/core/src/version.ts"() {
|
|
3058
3058
|
"use strict";
|
|
3059
3059
|
init_cjs_shims();
|
|
3060
|
-
HORUS_VERSION = true ? "0.21.
|
|
3060
|
+
HORUS_VERSION = true ? "0.21.8" : "dev";
|
|
3061
3061
|
PINNED_SOURCE_VERSION = HORUS_VERSION;
|
|
3062
3062
|
SOURCE_PIN_ENFORCED = HORUS_VERSION !== "dev";
|
|
3063
3063
|
EXPECTED_INDEX_CAPABILITY = 2;
|
|
@@ -29518,7 +29518,7 @@ var require_lib = __commonJS({
|
|
|
29518
29518
|
}
|
|
29519
29519
|
return new ErrorType(`${options.context ? options.context : "Value"} ${message}.`);
|
|
29520
29520
|
}
|
|
29521
|
-
function
|
|
29521
|
+
function toNumber3(value, options) {
|
|
29522
29522
|
if (typeof value === "bigint") {
|
|
29523
29523
|
throw makeException(TypeError, "is a BigInt which cannot be converted to a number", options);
|
|
29524
29524
|
}
|
|
@@ -29561,7 +29561,7 @@ var require_lib = __commonJS({
|
|
|
29561
29561
|
const twoToTheBitLength = 2 ** bitLength;
|
|
29562
29562
|
const twoToOneLessThanTheBitLength = 2 ** (bitLength - 1);
|
|
29563
29563
|
return (value, options = {}) => {
|
|
29564
|
-
let x4 =
|
|
29564
|
+
let x4 = toNumber3(value, options);
|
|
29565
29565
|
x4 = censorNegativeZero(x4);
|
|
29566
29566
|
if (options.enforceRange) {
|
|
29567
29567
|
if (!Number.isFinite(x4)) {
|
|
@@ -29601,7 +29601,7 @@ var require_lib = __commonJS({
|
|
|
29601
29601
|
const lowerBound = unsigned ? 0 : Number.MIN_SAFE_INTEGER;
|
|
29602
29602
|
const asBigIntN = unsigned ? BigInt.asUintN : BigInt.asIntN;
|
|
29603
29603
|
return (value, options = {}) => {
|
|
29604
|
-
let x4 =
|
|
29604
|
+
let x4 = toNumber3(value, options);
|
|
29605
29605
|
x4 = censorNegativeZero(x4);
|
|
29606
29606
|
if (options.enforceRange) {
|
|
29607
29607
|
if (!Number.isFinite(x4)) {
|
|
@@ -29648,18 +29648,18 @@ var require_lib = __commonJS({
|
|
|
29648
29648
|
exports2["long long"] = createLongLongConversion(64, { unsigned: false });
|
|
29649
29649
|
exports2["unsigned long long"] = createLongLongConversion(64, { unsigned: true });
|
|
29650
29650
|
exports2.double = (value, options = {}) => {
|
|
29651
|
-
const x4 =
|
|
29651
|
+
const x4 = toNumber3(value, options);
|
|
29652
29652
|
if (!Number.isFinite(x4)) {
|
|
29653
29653
|
throw makeException(TypeError, "is not a finite floating-point value", options);
|
|
29654
29654
|
}
|
|
29655
29655
|
return x4;
|
|
29656
29656
|
};
|
|
29657
29657
|
exports2["unrestricted double"] = (value, options = {}) => {
|
|
29658
|
-
const x4 =
|
|
29658
|
+
const x4 = toNumber3(value, options);
|
|
29659
29659
|
return x4;
|
|
29660
29660
|
};
|
|
29661
29661
|
exports2.float = (value, options = {}) => {
|
|
29662
|
-
const x4 =
|
|
29662
|
+
const x4 = toNumber3(value, options);
|
|
29663
29663
|
if (!Number.isFinite(x4)) {
|
|
29664
29664
|
throw makeException(TypeError, "is not a finite floating-point value", options);
|
|
29665
29665
|
}
|
|
@@ -29673,7 +29673,7 @@ var require_lib = __commonJS({
|
|
|
29673
29673
|
return y5;
|
|
29674
29674
|
};
|
|
29675
29675
|
exports2["unrestricted float"] = (value, options = {}) => {
|
|
29676
|
-
const x4 =
|
|
29676
|
+
const x4 = toNumber3(value, options);
|
|
29677
29677
|
if (isNaN(x4)) {
|
|
29678
29678
|
return x4;
|
|
29679
29679
|
}
|
|
@@ -75376,6 +75376,501 @@ function shortTs2(iso) {
|
|
|
75376
75376
|
return `${iso.slice(5, 10)} ${iso.slice(11, 16)}`;
|
|
75377
75377
|
}
|
|
75378
75378
|
|
|
75379
|
+
// ../../packages/connectors/src/lens/client.ts
|
|
75380
|
+
init_cjs_shims();
|
|
75381
|
+
init_src();
|
|
75382
|
+
var LensCloudClient = class {
|
|
75383
|
+
apiBaseUrl;
|
|
75384
|
+
token;
|
|
75385
|
+
workspaceId;
|
|
75386
|
+
http;
|
|
75387
|
+
constructor(opts) {
|
|
75388
|
+
this.apiBaseUrl = opts.apiBaseUrl.replace(/\/$/, "");
|
|
75389
|
+
this.token = opts.token;
|
|
75390
|
+
this.workspaceId = opts.workspaceId;
|
|
75391
|
+
this.http = opts.http ?? {};
|
|
75392
|
+
}
|
|
75393
|
+
async request(path) {
|
|
75394
|
+
const url = `${this.apiBaseUrl}${path}`;
|
|
75395
|
+
const res = await fetchWithRetry(
|
|
75396
|
+
url,
|
|
75397
|
+
{
|
|
75398
|
+
method: "GET",
|
|
75399
|
+
headers: {
|
|
75400
|
+
Authorization: `Bearer ${this.token}`,
|
|
75401
|
+
"Content-Type": "application/json"
|
|
75402
|
+
}
|
|
75403
|
+
},
|
|
75404
|
+
this.http
|
|
75405
|
+
);
|
|
75406
|
+
if (!res.ok) {
|
|
75407
|
+
const text2 = await res.text().catch(() => "");
|
|
75408
|
+
throw new Error(`Lens GET ${path} -> ${res.status}: ${redactUpstreamBody(text2)}`);
|
|
75409
|
+
}
|
|
75410
|
+
return res.json();
|
|
75411
|
+
}
|
|
75412
|
+
get base() {
|
|
75413
|
+
return `/v1/workspaces/${encodeURIComponent(this.workspaceId)}/lens`;
|
|
75414
|
+
}
|
|
75415
|
+
/**
|
|
75416
|
+
* List the Lens sites the workspace owns. Reports are site-scoped, so this is the
|
|
75417
|
+
* discovery step before `listReports`. Transport/auth failures PROPAGATE (like Sentry's
|
|
75418
|
+
* `listIssues`) so an outage reads as a gap, not as "no sites".
|
|
75419
|
+
*/
|
|
75420
|
+
async listSites() {
|
|
75421
|
+
const raw = await this.request(`${this.base}/sites`);
|
|
75422
|
+
const sites = Array.isArray(raw) ? raw : raw?.["sites"];
|
|
75423
|
+
if (!Array.isArray(sites)) return [];
|
|
75424
|
+
return sites.map((s5) => ({
|
|
75425
|
+
id: typeof s5["id"] === "string" ? s5["id"] : "",
|
|
75426
|
+
name: typeof s5["name"] === "string" && s5["name"] !== "" ? s5["name"] : typeof s5["id"] === "string" ? s5["id"] : ""
|
|
75427
|
+
})).filter((s5) => s5.id !== "");
|
|
75428
|
+
}
|
|
75429
|
+
/** Build the site-reports query path with the incident-window + filter params. */
|
|
75430
|
+
reportsPath(siteId, opts = {}) {
|
|
75431
|
+
const params = new URLSearchParams();
|
|
75432
|
+
if (opts.from !== void 0) params.set("from", opts.from);
|
|
75433
|
+
if (opts.to !== void 0) params.set("to", opts.to);
|
|
75434
|
+
if (opts.q !== void 0 && opts.q !== "") params.set("q", opts.q);
|
|
75435
|
+
if (opts.status !== void 0) params.set("status", opts.status);
|
|
75436
|
+
params.set("limit", String(Math.max(1, Math.min(opts.limit ?? 25, 200))));
|
|
75437
|
+
return `${this.base}/sites/${encodeURIComponent(siteId)}/reports?${params.toString()}`;
|
|
75438
|
+
}
|
|
75439
|
+
/**
|
|
75440
|
+
* List reports for a site within an optional incident window. `from`/`to` are inclusive
|
|
75441
|
+
* `createdAt` ISO-8601 bounds; `q` is a single case-insensitive substring over the
|
|
75442
|
+
* comment + env URL (NOT hint fan-out — the provider relevance-ranks client-side).
|
|
75443
|
+
* Returns the first page; transport/auth failures PROPAGATE.
|
|
75444
|
+
*/
|
|
75445
|
+
async listReports(siteId, opts = {}) {
|
|
75446
|
+
const raw = await this.request(this.reportsPath(siteId, opts));
|
|
75447
|
+
const reports = raw?.["reports"];
|
|
75448
|
+
if (!Array.isArray(reports)) return [];
|
|
75449
|
+
return reports.map((r) => parseSummary(r, siteId));
|
|
75450
|
+
}
|
|
75451
|
+
/**
|
|
75452
|
+
* Fetch one full report (with metadata) by id, scoped to its site. Transport/auth
|
|
75453
|
+
* failures PROPAGATE; the provider wraps each call so one bad report never aborts a
|
|
75454
|
+
* collection.
|
|
75455
|
+
*/
|
|
75456
|
+
async getReport(siteId, reportId) {
|
|
75457
|
+
const raw = await this.request(
|
|
75458
|
+
`${this.base}/sites/${encodeURIComponent(siteId)}/reports/${encodeURIComponent(reportId)}`
|
|
75459
|
+
);
|
|
75460
|
+
return parseReport(raw);
|
|
75461
|
+
}
|
|
75462
|
+
/** Cheap reachability probe: `listSites` succeeds → ok. Never throws. */
|
|
75463
|
+
async health() {
|
|
75464
|
+
try {
|
|
75465
|
+
const sites = await this.listSites();
|
|
75466
|
+
return { ok: true, detail: `lens reachable (workspace ${this.workspaceId}, ${sites.length} site(s))` };
|
|
75467
|
+
} catch (err2) {
|
|
75468
|
+
return { ok: false, detail: redactErrorMessage(err2) };
|
|
75469
|
+
}
|
|
75470
|
+
}
|
|
75471
|
+
};
|
|
75472
|
+
function toNumber2(v4) {
|
|
75473
|
+
if (typeof v4 === "number") return Number.isFinite(v4) ? v4 : 0;
|
|
75474
|
+
if (typeof v4 === "string") {
|
|
75475
|
+
const n4 = Number(v4);
|
|
75476
|
+
return Number.isFinite(n4) ? n4 : 0;
|
|
75477
|
+
}
|
|
75478
|
+
return 0;
|
|
75479
|
+
}
|
|
75480
|
+
function parseSummary(raw, siteId) {
|
|
75481
|
+
const summary = {
|
|
75482
|
+
id: String(raw["id"] ?? ""),
|
|
75483
|
+
lensSiteId: typeof raw["lensSiteId"] === "string" ? raw["lensSiteId"] : siteId,
|
|
75484
|
+
status: typeof raw["status"] === "string" ? raw["status"] : "",
|
|
75485
|
+
createdAt: typeof raw["createdAt"] === "string" ? raw["createdAt"] : "",
|
|
75486
|
+
submittedAt: typeof raw["submittedAt"] === "string" ? raw["submittedAt"] : null,
|
|
75487
|
+
externalIssue: raw["externalIssue"] ?? null,
|
|
75488
|
+
lensIssueId: typeof raw["lensIssueId"] === "string" ? raw["lensIssueId"] : null,
|
|
75489
|
+
issueOccurrenceCount: typeof raw["issueOccurrenceCount"] === "number" ? raw["issueOccurrenceCount"] : null,
|
|
75490
|
+
errorCount: toNumber2(raw["errorCount"]),
|
|
75491
|
+
hasReplay: raw["hasReplay"] === true
|
|
75492
|
+
};
|
|
75493
|
+
if (typeof raw["comment"] === "string") summary.comment = raw["comment"];
|
|
75494
|
+
if (typeof raw["url"] === "string") summary.url = raw["url"];
|
|
75495
|
+
return summary;
|
|
75496
|
+
}
|
|
75497
|
+
function parseReport(raw) {
|
|
75498
|
+
const o5 = raw ?? {};
|
|
75499
|
+
return {
|
|
75500
|
+
id: String(o5["id"] ?? ""),
|
|
75501
|
+
status: typeof o5["status"] === "string" ? o5["status"] : "",
|
|
75502
|
+
createdAt: typeof o5["createdAt"] === "string" ? o5["createdAt"] : "",
|
|
75503
|
+
submittedAt: typeof o5["submittedAt"] === "string" ? o5["submittedAt"] : null,
|
|
75504
|
+
metadata: parseMetadata(o5["metadata"])
|
|
75505
|
+
};
|
|
75506
|
+
}
|
|
75507
|
+
function parseMetadata(raw) {
|
|
75508
|
+
if (raw === null || raw === void 0 || typeof raw !== "object") return null;
|
|
75509
|
+
const m5 = raw;
|
|
75510
|
+
const meta = {
|
|
75511
|
+
errors: parseErrors(m5["errors"]),
|
|
75512
|
+
networkTail: parseNetworkTail(m5["networkTail"])
|
|
75513
|
+
};
|
|
75514
|
+
if (typeof m5["comment"] === "string") meta.comment = m5["comment"];
|
|
75515
|
+
if (typeof m5["trigger"] === "string") meta.trigger = m5["trigger"];
|
|
75516
|
+
const target = m5["target"];
|
|
75517
|
+
if (target && typeof target === "object") {
|
|
75518
|
+
const t2 = target;
|
|
75519
|
+
const parsed = {};
|
|
75520
|
+
if (typeof t2["domPath"] === "string") parsed.domPath = t2["domPath"];
|
|
75521
|
+
if (typeof t2["tagName"] === "string") parsed.tagName = t2["tagName"];
|
|
75522
|
+
if (typeof t2["text"] === "string") parsed.text = t2["text"];
|
|
75523
|
+
if (Array.isArray(t2["reactComponents"])) {
|
|
75524
|
+
parsed.reactComponents = t2["reactComponents"].filter(
|
|
75525
|
+
(c4) => typeof c4 === "string"
|
|
75526
|
+
);
|
|
75527
|
+
}
|
|
75528
|
+
meta.target = parsed;
|
|
75529
|
+
}
|
|
75530
|
+
const env = m5["env"];
|
|
75531
|
+
if (env && typeof env === "object") {
|
|
75532
|
+
const e = env;
|
|
75533
|
+
const parsed = { url: typeof e["url"] === "string" ? e["url"] : "" };
|
|
75534
|
+
if (typeof e["route"] === "string") parsed.route = e["route"];
|
|
75535
|
+
if (typeof e["userAgent"] === "string") parsed.userAgent = e["userAgent"];
|
|
75536
|
+
if (typeof e["browser"] === "string") parsed.browser = e["browser"];
|
|
75537
|
+
if (typeof e["os"] === "string") parsed.os = e["os"];
|
|
75538
|
+
meta.env = parsed;
|
|
75539
|
+
}
|
|
75540
|
+
const app = m5["app"];
|
|
75541
|
+
if (app && typeof app === "object") {
|
|
75542
|
+
const a2 = app;
|
|
75543
|
+
const parsed = {};
|
|
75544
|
+
if (typeof a2["release"] === "string") parsed.release = a2["release"];
|
|
75545
|
+
if (typeof a2["gitSha"] === "string") parsed.gitSha = a2["gitSha"];
|
|
75546
|
+
if (typeof a2["environment"] === "string") parsed.environment = a2["environment"];
|
|
75547
|
+
if (a2["featureFlags"] && typeof a2["featureFlags"] === "object") {
|
|
75548
|
+
parsed.featureFlags = a2["featureFlags"];
|
|
75549
|
+
}
|
|
75550
|
+
meta.app = parsed;
|
|
75551
|
+
}
|
|
75552
|
+
return meta;
|
|
75553
|
+
}
|
|
75554
|
+
function parseErrors(raw) {
|
|
75555
|
+
if (!Array.isArray(raw)) return [];
|
|
75556
|
+
return raw.filter((e) => typeof e["message"] === "string").map((e) => {
|
|
75557
|
+
const err2 = {
|
|
75558
|
+
message: e["message"],
|
|
75559
|
+
source: typeof e["source"] === "string" ? e["source"] : "",
|
|
75560
|
+
timestamp: toNumber2(e["timestamp"])
|
|
75561
|
+
};
|
|
75562
|
+
if (typeof e["stack"] === "string") err2.stack = e["stack"];
|
|
75563
|
+
return err2;
|
|
75564
|
+
});
|
|
75565
|
+
}
|
|
75566
|
+
function parseNetworkTail(raw) {
|
|
75567
|
+
if (!Array.isArray(raw)) return [];
|
|
75568
|
+
return raw.map((n4) => {
|
|
75569
|
+
const entry = {
|
|
75570
|
+
method: typeof n4["method"] === "string" ? n4["method"] : "",
|
|
75571
|
+
url: typeof n4["url"] === "string" ? n4["url"] : "",
|
|
75572
|
+
status: typeof n4["status"] === "number" ? n4["status"] : null,
|
|
75573
|
+
ok: typeof n4["ok"] === "boolean" ? n4["ok"] : null,
|
|
75574
|
+
durationMs: typeof n4["durationMs"] === "number" ? n4["durationMs"] : null,
|
|
75575
|
+
requestType: typeof n4["requestType"] === "string" ? n4["requestType"] : "",
|
|
75576
|
+
startedAt: toNumber2(n4["startedAt"])
|
|
75577
|
+
};
|
|
75578
|
+
if (typeof n4["error"] === "string") entry.error = n4["error"];
|
|
75579
|
+
return entry;
|
|
75580
|
+
});
|
|
75581
|
+
}
|
|
75582
|
+
|
|
75583
|
+
// ../../packages/connectors/src/lens/provider.ts
|
|
75584
|
+
init_cjs_shims();
|
|
75585
|
+
init_src();
|
|
75586
|
+
var LensProvider = class {
|
|
75587
|
+
constructor(client, opts = {}) {
|
|
75588
|
+
this.client = client;
|
|
75589
|
+
this.opts = opts;
|
|
75590
|
+
}
|
|
75591
|
+
client;
|
|
75592
|
+
opts;
|
|
75593
|
+
id = "lens";
|
|
75594
|
+
kind = "logs";
|
|
75595
|
+
sitesCache = null;
|
|
75596
|
+
get limit() {
|
|
75597
|
+
return this.opts.limit ?? 25;
|
|
75598
|
+
}
|
|
75599
|
+
get statusFilter() {
|
|
75600
|
+
return this.opts.statusFilter ?? "submitted";
|
|
75601
|
+
}
|
|
75602
|
+
/**
|
|
75603
|
+
* Collect recent reports across every site within the window and resolve each one's
|
|
75604
|
+
* top frame + failing requests. Reports are low-volume, so we fetch the full metadata
|
|
75605
|
+
* for up to `limit` (relevance-ranked) reports. A failing site LIST or reports LIST
|
|
75606
|
+
* PROPAGATES so the engine records a gap; per-report metadata fetches are best-effort
|
|
75607
|
+
* (a report still becomes a signal from its summary alone). Use queryEvidence() for the
|
|
75608
|
+
* degrade-to-[] contract.
|
|
75609
|
+
*/
|
|
75610
|
+
async collect(opts = {}) {
|
|
75611
|
+
const siteIds = await this.sites();
|
|
75612
|
+
const hintTerms = opts.hintTerms ?? [];
|
|
75613
|
+
const summaries = [];
|
|
75614
|
+
for (const siteId of siteIds) {
|
|
75615
|
+
const page = await this.client.listReports(siteId, {
|
|
75616
|
+
...opts.from !== void 0 ? { from: opts.from } : {},
|
|
75617
|
+
...opts.to !== void 0 ? { to: opts.to } : {},
|
|
75618
|
+
status: this.statusFilter,
|
|
75619
|
+
limit: this.limit
|
|
75620
|
+
});
|
|
75621
|
+
summaries.push(...page);
|
|
75622
|
+
}
|
|
75623
|
+
const windowed = summaries.filter((s5) => inWindow(s5.createdAt, opts.from, opts.to));
|
|
75624
|
+
const ranked = rankSummaries(windowed, hintTerms).slice(0, this.limit);
|
|
75625
|
+
const reports = await Promise.all(
|
|
75626
|
+
ranked.map(
|
|
75627
|
+
(s5) => this.client.getReport(s5.lensSiteId, s5.id).catch(() => null)
|
|
75628
|
+
)
|
|
75629
|
+
);
|
|
75630
|
+
return ranked.map((summary, i3) => buildSignal(summary, reports[i3] ?? null));
|
|
75631
|
+
}
|
|
75632
|
+
/**
|
|
75633
|
+
* Synthesize Evidence from Lens reports. One `kind: 'log'` Evidence per report, with the
|
|
75634
|
+
* comment as the human signature, the captured error + failing requests + app context in
|
|
75635
|
+
* the payload, and the top frame surfaced as `filePath`/`symbolName`/`lineStart` (payload)
|
|
75636
|
+
* and `file`/`line` (links) so the engine can seed directly on it.
|
|
75637
|
+
*/
|
|
75638
|
+
toEvidence(signals, hintTerms, collectedAt) {
|
|
75639
|
+
const query = `lens reports (status:${this.statusFilter}, up to ${this.limit})`;
|
|
75640
|
+
return signals.map((sig, i3) => signalToEvidence(sig, hintTerms, query, collectedAt, i3));
|
|
75641
|
+
}
|
|
75642
|
+
/**
|
|
75643
|
+
* One-shot evidence query: collect reports, convert to redacted Evidence. Preferred entry
|
|
75644
|
+
* point for the investigation engine. Degrades to [] on any failure so a flaky Cloud never
|
|
75645
|
+
* aborts an investigation.
|
|
75646
|
+
*/
|
|
75647
|
+
async queryEvidence(opts = {}) {
|
|
75648
|
+
try {
|
|
75649
|
+
const hintTerms = opts.hintTerms ?? [];
|
|
75650
|
+
const signals = await this.collect({
|
|
75651
|
+
...opts.from !== void 0 ? { from: opts.from } : {},
|
|
75652
|
+
...opts.to !== void 0 ? { to: opts.to } : {},
|
|
75653
|
+
hintTerms
|
|
75654
|
+
});
|
|
75655
|
+
return this.toEvidence(signals, hintTerms, opts.collectedAt ?? (/* @__PURE__ */ new Date()).toISOString());
|
|
75656
|
+
} catch {
|
|
75657
|
+
return [];
|
|
75658
|
+
}
|
|
75659
|
+
}
|
|
75660
|
+
async health() {
|
|
75661
|
+
return this.client.health();
|
|
75662
|
+
}
|
|
75663
|
+
/** In-instance site-id cache — reports are site-scoped and the site list is stable. */
|
|
75664
|
+
async sites() {
|
|
75665
|
+
if (this.sitesCache !== null) return this.sitesCache;
|
|
75666
|
+
const sites = await this.client.listSites();
|
|
75667
|
+
this.sitesCache = sites.map((s5) => s5.id);
|
|
75668
|
+
return this.sitesCache;
|
|
75669
|
+
}
|
|
75670
|
+
};
|
|
75671
|
+
function buildSignal(summary, report) {
|
|
75672
|
+
const meta = report?.metadata ?? null;
|
|
75673
|
+
const errors2 = meta?.errors ?? [];
|
|
75674
|
+
const { frame, message } = topFrameFromErrors(errors2);
|
|
75675
|
+
const signal = {
|
|
75676
|
+
id: summary.id,
|
|
75677
|
+
lensSiteId: summary.lensSiteId,
|
|
75678
|
+
status: summary.status,
|
|
75679
|
+
createdAt: summary.createdAt,
|
|
75680
|
+
submittedAt: summary.submittedAt,
|
|
75681
|
+
issueOccurrenceCount: summary.issueOccurrenceCount,
|
|
75682
|
+
errorCount: summary.errorCount || errors2.length,
|
|
75683
|
+
hasReplay: summary.hasReplay,
|
|
75684
|
+
topFrame: frame,
|
|
75685
|
+
failingRequests: failingRequestsFrom(meta?.networkTail ?? [])
|
|
75686
|
+
};
|
|
75687
|
+
const comment = meta?.comment ?? summary.comment;
|
|
75688
|
+
if (comment !== void 0) signal.comment = comment;
|
|
75689
|
+
const route2 = meta?.env?.route;
|
|
75690
|
+
if (route2 !== void 0) signal.route = route2;
|
|
75691
|
+
const url = meta?.env?.url && meta.env.url !== "" ? meta.env.url : summary.url;
|
|
75692
|
+
if (url !== void 0) signal.url = url;
|
|
75693
|
+
if (meta?.app?.release !== void 0) signal.release = meta.app.release;
|
|
75694
|
+
if (meta?.app?.gitSha !== void 0) signal.gitSha = meta.app.gitSha;
|
|
75695
|
+
if (meta?.app?.environment !== void 0) signal.environment = meta.app.environment;
|
|
75696
|
+
if (meta?.app?.featureFlags !== void 0) signal.featureFlags = meta.app.featureFlags;
|
|
75697
|
+
if (meta?.trigger !== void 0) signal.trigger = meta.trigger;
|
|
75698
|
+
if (message !== void 0) signal.topErrorMessage = message;
|
|
75699
|
+
const react = meta?.target?.reactComponents;
|
|
75700
|
+
if (react !== void 0 && react.length > 0) signal.reactComponents = react;
|
|
75701
|
+
return signal;
|
|
75702
|
+
}
|
|
75703
|
+
function failingRequestsFrom(tail) {
|
|
75704
|
+
return tail.filter((n4) => n4.ok === false || typeof n4.status === "number" && n4.status >= 500).slice(0, 5).map((n4) => ({ method: n4.method, url: n4.url, status: n4.status }));
|
|
75705
|
+
}
|
|
75706
|
+
function topFrameFromErrors(errors2) {
|
|
75707
|
+
let firstMessage;
|
|
75708
|
+
for (const err2 of errors2) {
|
|
75709
|
+
if (firstMessage === void 0 && err2.message) firstMessage = err2.message;
|
|
75710
|
+
if (!err2.stack) continue;
|
|
75711
|
+
const frame = parseStackTopFrame(err2.stack);
|
|
75712
|
+
if (frame) return { frame, message: err2.message || firstMessage };
|
|
75713
|
+
}
|
|
75714
|
+
return firstMessage !== void 0 ? { frame: null, message: firstMessage } : { frame: null };
|
|
75715
|
+
}
|
|
75716
|
+
function isSkippableLocation(location2) {
|
|
75717
|
+
if (location2 === "") return true;
|
|
75718
|
+
if (location2.includes("node_modules")) return true;
|
|
75719
|
+
if (/^[a-z-]+-extension:\/\//i.test(location2)) return true;
|
|
75720
|
+
if (location2.includes("[native code]") || location2.includes("<anonymous>")) return true;
|
|
75721
|
+
return false;
|
|
75722
|
+
}
|
|
75723
|
+
function parseStackTopFrame(stack) {
|
|
75724
|
+
const lines = stack.split("\n");
|
|
75725
|
+
for (const raw of lines) {
|
|
75726
|
+
const line2 = raw.trim();
|
|
75727
|
+
if (line2 === "") continue;
|
|
75728
|
+
let fnName;
|
|
75729
|
+
let location2;
|
|
75730
|
+
if (line2.startsWith("at ")) {
|
|
75731
|
+
const body2 = line2.slice(3).trim();
|
|
75732
|
+
const parenMatch = /^(.*?)\s*\((.+)\)\s*$/.exec(body2);
|
|
75733
|
+
if (parenMatch) {
|
|
75734
|
+
fnName = parenMatch[1]?.trim() || void 0;
|
|
75735
|
+
location2 = parenMatch[2].trim();
|
|
75736
|
+
} else {
|
|
75737
|
+
location2 = body2;
|
|
75738
|
+
}
|
|
75739
|
+
} else if (line2.includes("@")) {
|
|
75740
|
+
const at4 = line2.lastIndexOf("@");
|
|
75741
|
+
fnName = line2.slice(0, at4).trim() || void 0;
|
|
75742
|
+
location2 = line2.slice(at4 + 1).trim();
|
|
75743
|
+
} else {
|
|
75744
|
+
continue;
|
|
75745
|
+
}
|
|
75746
|
+
if (location2 === void 0 || isSkippableLocation(location2)) continue;
|
|
75747
|
+
const parsed = parseLocation(location2);
|
|
75748
|
+
if (!parsed) continue;
|
|
75749
|
+
if (isSkippableLocation(parsed.filename)) continue;
|
|
75750
|
+
const frame = { filename: parsed.filename };
|
|
75751
|
+
if (fnName !== void 0 && fnName !== "") frame.function = fnName;
|
|
75752
|
+
if (parsed.lineno !== void 0) frame.lineno = parsed.lineno;
|
|
75753
|
+
return frame;
|
|
75754
|
+
}
|
|
75755
|
+
return null;
|
|
75756
|
+
}
|
|
75757
|
+
function parseLocation(location2) {
|
|
75758
|
+
const m5 = /^(.*?):(\d+)(?::(\d+))?$/.exec(location2);
|
|
75759
|
+
const rawUrl = m5 ? m5[1] : location2;
|
|
75760
|
+
const lineno = m5 ? Number(m5[2]) : void 0;
|
|
75761
|
+
let filename = rawUrl;
|
|
75762
|
+
try {
|
|
75763
|
+
if (/^[a-z]+:\/\//i.test(rawUrl)) filename = new URL(rawUrl).pathname;
|
|
75764
|
+
} catch {
|
|
75765
|
+
filename = rawUrl;
|
|
75766
|
+
}
|
|
75767
|
+
if (filename === "") return null;
|
|
75768
|
+
return lineno !== void 0 && Number.isFinite(lineno) ? { filename, lineno } : { filename };
|
|
75769
|
+
}
|
|
75770
|
+
function signalToEvidence(sig, hintTerms, query, collectedAt, index2) {
|
|
75771
|
+
const frame = sig.topFrame;
|
|
75772
|
+
const title = buildTitle2(sig);
|
|
75773
|
+
const relevance = computeRelevance2(sig, hintTerms);
|
|
75774
|
+
const payload = {
|
|
75775
|
+
source: "lens",
|
|
75776
|
+
reportId: sig.id,
|
|
75777
|
+
...sig.comment !== void 0 ? { comment: redactSecrets(sig.comment) } : {},
|
|
75778
|
+
...sig.route !== void 0 ? { route: sig.route } : {},
|
|
75779
|
+
...sig.url !== void 0 ? { url: sig.url } : {},
|
|
75780
|
+
...sig.release !== void 0 ? { release: sig.release } : {},
|
|
75781
|
+
...sig.gitSha !== void 0 ? { gitSha: sig.gitSha } : {},
|
|
75782
|
+
...sig.trigger !== void 0 ? { trigger: sig.trigger } : {},
|
|
75783
|
+
errorCount: sig.errorCount,
|
|
75784
|
+
...sig.topErrorMessage !== void 0 ? { topError: redactSecrets(sig.topErrorMessage) } : {},
|
|
75785
|
+
...sig.failingRequests.length > 0 ? { failingRequests: sig.failingRequests } : {},
|
|
75786
|
+
...sig.reactComponents !== void 0 ? { reactComponents: sig.reactComponents } : {},
|
|
75787
|
+
...sig.featureFlags !== void 0 ? { featureFlags: sig.featureFlags } : {}
|
|
75788
|
+
};
|
|
75789
|
+
if (frame?.filename !== void 0) payload["filePath"] = frame.filename;
|
|
75790
|
+
if (frame?.function !== void 0) payload["symbolName"] = frame.function;
|
|
75791
|
+
if (frame?.lineno !== void 0) payload["lineStart"] = frame.lineno;
|
|
75792
|
+
const links = {};
|
|
75793
|
+
if (frame?.filename !== void 0) links.file = frame.filename;
|
|
75794
|
+
if (frame?.lineno !== void 0) links.line = frame.lineno;
|
|
75795
|
+
const ev = {
|
|
75796
|
+
id: `ev_lens_${index2}`,
|
|
75797
|
+
source: "logs",
|
|
75798
|
+
kind: "log",
|
|
75799
|
+
title,
|
|
75800
|
+
relevance,
|
|
75801
|
+
payload,
|
|
75802
|
+
links,
|
|
75803
|
+
provenance: { query, collectedAt }
|
|
75804
|
+
};
|
|
75805
|
+
const ts = sig.submittedAt ?? sig.createdAt;
|
|
75806
|
+
if (ts) ev.timestamp = ts;
|
|
75807
|
+
return ev;
|
|
75808
|
+
}
|
|
75809
|
+
function buildTitle2(sig) {
|
|
75810
|
+
const rawComment = sig.comment ? redactSecrets(sig.comment) : "";
|
|
75811
|
+
const comment = rawComment !== "" ? rawComment.slice(0, 80) : "(no comment)";
|
|
75812
|
+
const errs = `${sig.errorCount} error(s)`;
|
|
75813
|
+
const where = sig.route ?? sig.url ?? "";
|
|
75814
|
+
const whereStr = where !== "" ? ` \xB7 ${where}` : "";
|
|
75815
|
+
const when = sig.createdAt ? ` \xB7 ${shortTs3(sig.createdAt)}` : "";
|
|
75816
|
+
return `Lens report: "${comment}" \xB7 ${errs}${whereStr}${when}`.slice(0, 220);
|
|
75817
|
+
}
|
|
75818
|
+
function computeRelevance2(sig, hintTerms, now = Date.now()) {
|
|
75819
|
+
let score = 0.6;
|
|
75820
|
+
const hay = [
|
|
75821
|
+
sig.comment ?? "",
|
|
75822
|
+
sig.route ?? "",
|
|
75823
|
+
sig.url ?? "",
|
|
75824
|
+
sig.topErrorMessage ?? "",
|
|
75825
|
+
sig.topFrame?.filename ?? "",
|
|
75826
|
+
sig.topFrame?.function ?? ""
|
|
75827
|
+
].join(" ").toLowerCase();
|
|
75828
|
+
const domainTerms = hintTerms.filter((t2) => t2.length > 2);
|
|
75829
|
+
if (domainTerms.some((t2) => hay.includes(t2.toLowerCase()))) score += 0.2;
|
|
75830
|
+
const ts = sig.submittedAt ?? sig.createdAt;
|
|
75831
|
+
if (ts) {
|
|
75832
|
+
const ageMs = now - Date.parse(ts);
|
|
75833
|
+
if (Number.isFinite(ageMs)) {
|
|
75834
|
+
if (ageMs <= 864e5) score += 0.1;
|
|
75835
|
+
else if (ageMs <= 7 * 864e5) score += 0.05;
|
|
75836
|
+
}
|
|
75837
|
+
}
|
|
75838
|
+
if ((sig.issueOccurrenceCount ?? 0) >= 3) score += 0.05;
|
|
75839
|
+
return Math.min(0.95, Math.max(0.5, score));
|
|
75840
|
+
}
|
|
75841
|
+
function rankSummaries(summaries, hintTerms, now = Date.now()) {
|
|
75842
|
+
const domainTerms = hintTerms.filter((t2) => t2.length > 2);
|
|
75843
|
+
const score = (s5) => {
|
|
75844
|
+
let v4 = 0;
|
|
75845
|
+
const hay = `${s5.comment ?? ""} ${s5.url ?? ""}`.toLowerCase();
|
|
75846
|
+
if (domainTerms.some((t2) => hay.includes(t2.toLowerCase()))) v4 += 2;
|
|
75847
|
+
if (s5.createdAt) {
|
|
75848
|
+
const ageMs = now - Date.parse(s5.createdAt);
|
|
75849
|
+
if (Number.isFinite(ageMs) && ageMs <= 864e5) v4 += 1;
|
|
75850
|
+
}
|
|
75851
|
+
if ((s5.issueOccurrenceCount ?? 0) >= 3) v4 += 0.5;
|
|
75852
|
+
return v4;
|
|
75853
|
+
};
|
|
75854
|
+
return [...summaries].sort((a2, b5) => {
|
|
75855
|
+
const d3 = score(b5) - score(a2);
|
|
75856
|
+
if (d3 !== 0) return d3;
|
|
75857
|
+
return (Date.parse(b5.createdAt) || 0) - (Date.parse(a2.createdAt) || 0);
|
|
75858
|
+
});
|
|
75859
|
+
}
|
|
75860
|
+
function inWindow(createdAt, from, to) {
|
|
75861
|
+
const t2 = Date.parse(createdAt);
|
|
75862
|
+
if (!Number.isFinite(t2)) return true;
|
|
75863
|
+
const lo = from !== void 0 ? Date.parse(from) : NaN;
|
|
75864
|
+
const hi = to !== void 0 ? Date.parse(to) : NaN;
|
|
75865
|
+
if (Number.isFinite(lo) && t2 < lo) return false;
|
|
75866
|
+
if (Number.isFinite(hi) && t2 > hi) return false;
|
|
75867
|
+
return true;
|
|
75868
|
+
}
|
|
75869
|
+
function shortTs3(iso) {
|
|
75870
|
+
if (!iso || iso.length < 16) return iso || "\u2014";
|
|
75871
|
+
return `${iso.slice(5, 10)} ${iso.slice(11, 16)}`;
|
|
75872
|
+
}
|
|
75873
|
+
|
|
75379
75874
|
// ../../packages/connectors/src/axiom/client.ts
|
|
75380
75875
|
init_cjs_shims();
|
|
75381
75876
|
init_src();
|
|
@@ -75629,8 +76124,8 @@ var AxiomProvider = class {
|
|
|
75629
76124
|
return this.client.health();
|
|
75630
76125
|
}
|
|
75631
76126
|
recordToEvidence(rec, hintTerms, query, collectedAt, index2) {
|
|
75632
|
-
const title =
|
|
75633
|
-
const relevance =
|
|
76127
|
+
const title = buildTitle3(rec, this.opts.dataset);
|
|
76128
|
+
const relevance = computeRelevance3(rec, hintTerms);
|
|
75634
76129
|
const payload = {
|
|
75635
76130
|
source: "axiom",
|
|
75636
76131
|
dataset: this.opts.dataset,
|
|
@@ -75660,7 +76155,7 @@ function pickField2(fields, candidates) {
|
|
|
75660
76155
|
}
|
|
75661
76156
|
return void 0;
|
|
75662
76157
|
}
|
|
75663
|
-
function
|
|
76158
|
+
function buildTitle3(rec, dataset) {
|
|
75664
76159
|
const msg = pickField2(rec.fields, MESSAGE_FIELDS);
|
|
75665
76160
|
const level = pickField2(rec.fields, LEVEL_FIELDS);
|
|
75666
76161
|
const lvl = level ? `[${level}] ` : "";
|
|
@@ -75668,13 +76163,13 @@ function buildTitle2(rec, dataset) {
|
|
|
75668
76163
|
const rawCount = rec.fields["count"];
|
|
75669
76164
|
const count = typeof rawCount === "number" && Number.isFinite(rawCount) && rawCount > 1 ? rawCount : void 0;
|
|
75670
76165
|
if (count !== void 0) {
|
|
75671
|
-
const latest = rec.timestamp ? ` (latest ${
|
|
76166
|
+
const latest = rec.timestamp ? ` (latest ${shortTs4(rec.timestamp)})` : "";
|
|
75672
76167
|
return `Axiom ${dataset}: ${lvl}${body2} \xD7${count.toLocaleString("en-US")}${latest}`.slice(0, 220);
|
|
75673
76168
|
}
|
|
75674
|
-
const ts = rec.timestamp ? ` \xB7 ${
|
|
76169
|
+
const ts = rec.timestamp ? ` \xB7 ${shortTs4(rec.timestamp)}` : "";
|
|
75675
76170
|
return `Axiom ${dataset}: ${lvl}${body2}${ts}`.slice(0, 220);
|
|
75676
76171
|
}
|
|
75677
|
-
function
|
|
76172
|
+
function computeRelevance3(rec, hintTerms, now = Date.now()) {
|
|
75678
76173
|
let score = 0.6;
|
|
75679
76174
|
const hay = JSON.stringify(rec.fields).toLowerCase();
|
|
75680
76175
|
const domainTerms = hintTerms.filter((t2) => t2.length > 2);
|
|
@@ -75693,7 +76188,7 @@ function computeRelevance2(rec, hintTerms, now = Date.now()) {
|
|
|
75693
76188
|
if (typeof count === "number" && count >= 10) score += 0.1;
|
|
75694
76189
|
return Math.min(0.95, Math.max(0.5, score));
|
|
75695
76190
|
}
|
|
75696
|
-
function
|
|
76191
|
+
function shortTs4(iso) {
|
|
75697
76192
|
if (!iso || iso.length < 16) return iso || "\u2014";
|
|
75698
76193
|
return `${iso.slice(5, 10)} ${iso.slice(11, 16)}`;
|
|
75699
76194
|
}
|
|
@@ -75942,8 +76437,8 @@ var ShopifyProvider = class {
|
|
|
75942
76437
|
id: `ev_shopify_${index2}`,
|
|
75943
76438
|
source: KIND_TO_SOURCE[rec.kind],
|
|
75944
76439
|
kind: rec.kind,
|
|
75945
|
-
title:
|
|
75946
|
-
relevance:
|
|
76440
|
+
title: buildTitle4(rec, this.opts.store),
|
|
76441
|
+
relevance: computeRelevance4(rec, hintTerms),
|
|
75947
76442
|
payload,
|
|
75948
76443
|
links: {},
|
|
75949
76444
|
provenance: { query: `shopify ${this.opts.store} ${rec.name}`, collectedAt }
|
|
@@ -75960,8 +76455,8 @@ function bindWindowVars(q2, from, to) {
|
|
|
75960
76455
|
if (to !== void 0) window2["to"] = to;
|
|
75961
76456
|
return { ...base2, ...window2 };
|
|
75962
76457
|
}
|
|
75963
|
-
function
|
|
75964
|
-
const ts = rec.timestamp ? ` \xB7 ${
|
|
76458
|
+
function buildTitle4(rec, store) {
|
|
76459
|
+
const ts = rec.timestamp ? ` \xB7 ${shortTs5(rec.timestamp)}` : "";
|
|
75965
76460
|
return redactSecrets(`Shopify ${store} ${rec.name}: ${summarize2(rec)}${ts}`).slice(0, 220);
|
|
75966
76461
|
}
|
|
75967
76462
|
function summarize2(rec) {
|
|
@@ -75988,14 +76483,14 @@ function countResults(data) {
|
|
|
75988
76483
|
}
|
|
75989
76484
|
return found ? total : null;
|
|
75990
76485
|
}
|
|
75991
|
-
function
|
|
76486
|
+
function computeRelevance4(rec, hintTerms) {
|
|
75992
76487
|
let score = rec.relevance ?? 0.6;
|
|
75993
76488
|
const hay = JSON.stringify(rec.data ?? {}).toLowerCase();
|
|
75994
76489
|
const domainTerms = hintTerms.filter((t2) => t2.length > 2);
|
|
75995
76490
|
if (domainTerms.some((t2) => hay.includes(t2.toLowerCase()))) score += 0.2;
|
|
75996
76491
|
return Math.min(0.95, Math.max(0.5, score));
|
|
75997
76492
|
}
|
|
75998
|
-
function
|
|
76493
|
+
function shortTs5(iso) {
|
|
75999
76494
|
if (!iso || iso.length < 16) return iso || "\u2014";
|
|
76000
76495
|
return `${iso.slice(5, 10)} ${iso.slice(11, 16)}`;
|
|
76001
76496
|
}
|
|
@@ -76714,6 +77209,15 @@ function shopifyForEnv(renv) {
|
|
|
76714
77209
|
}
|
|
76715
77210
|
);
|
|
76716
77211
|
}
|
|
77212
|
+
function lensForCloud(opts) {
|
|
77213
|
+
return new LensProvider(
|
|
77214
|
+
new LensCloudClient({
|
|
77215
|
+
apiBaseUrl: opts.apiBaseUrl,
|
|
77216
|
+
token: opts.token,
|
|
77217
|
+
workspaceId: opts.workspaceId
|
|
77218
|
+
})
|
|
77219
|
+
);
|
|
77220
|
+
}
|
|
76717
77221
|
function codeForRepo(config2, repoName) {
|
|
76718
77222
|
const renv = resolveEnvironment(config2, { project: repoName });
|
|
76719
77223
|
const c4 = codeForEnv(renv);
|
|
@@ -77096,6 +77600,9 @@ async function redisServerStatus(renv) {
|
|
|
77096
77600
|
// ../../packages/connectors/src/shopify/index.ts
|
|
77097
77601
|
init_cjs_shims();
|
|
77098
77602
|
|
|
77603
|
+
// ../../packages/connectors/src/lens/index.ts
|
|
77604
|
+
init_cjs_shims();
|
|
77605
|
+
|
|
77099
77606
|
// ../../packages/cli/src/lib/bundled-backend.ts
|
|
77100
77607
|
init_cjs_shims();
|
|
77101
77608
|
var import_node_fs5 = require("fs");
|
|
@@ -94233,6 +94740,7 @@ init_cjs_shims();
|
|
|
94233
94740
|
|
|
94234
94741
|
// ../../packages/engine/src/engine.ts
|
|
94235
94742
|
init_cjs_shims();
|
|
94743
|
+
init_src();
|
|
94236
94744
|
|
|
94237
94745
|
// ../../packages/engine/src/render.ts
|
|
94238
94746
|
init_cjs_shims();
|
|
@@ -97328,7 +97836,7 @@ async function captureInvestigationMemory(store, investigationId, report, report
|
|
|
97328
97836
|
init_cjs_shims();
|
|
97329
97837
|
function hasAnyRuntimeConnector(c4) {
|
|
97330
97838
|
return Boolean(
|
|
97331
|
-
c4.elasticsearch || c4.sentry || c4.axiom || c4.grafana || c4.mongodb || c4.postgres || c4.redis || c4.queue || c4.shopify
|
|
97839
|
+
c4.elasticsearch || c4.sentry || c4.lens || c4.axiom || c4.grafana || c4.mongodb || c4.postgres || c4.redis || c4.queue || c4.shopify
|
|
97332
97840
|
);
|
|
97333
97841
|
}
|
|
97334
97842
|
function isUnavailable(c4, kind) {
|
|
@@ -100055,6 +100563,88 @@ async function investigate(input, deps) {
|
|
|
100055
100563
|
sentryFailureReason = connectorFailureReason(sentryErr);
|
|
100056
100564
|
}
|
|
100057
100565
|
}
|
|
100566
|
+
let lensCollected = false;
|
|
100567
|
+
let lensFailureReason;
|
|
100568
|
+
let lensReportCount = 0;
|
|
100569
|
+
if (deps.lens) {
|
|
100570
|
+
try {
|
|
100571
|
+
const from = logWindowFrom(input.logsSince ?? input.since);
|
|
100572
|
+
const to = (/* @__PURE__ */ new Date()).toISOString();
|
|
100573
|
+
const lensSeedBase = top ? top.filePath.split("/").pop() ?? "" : "";
|
|
100574
|
+
const lensTerms = top ? [.../* @__PURE__ */ new Set([...tokenize(hint), ...tokenize(top.name), ...tokenize(lensSeedBase)])] : [...new Set(tokenize(hint))];
|
|
100575
|
+
const seedFileBase = top ? (top.filePath.split("/").pop() ?? "").toLowerCase() : "";
|
|
100576
|
+
const signals = await deps.lens.collect({ from, to, hintTerms: lensTerms });
|
|
100577
|
+
lensCollected = true;
|
|
100578
|
+
lensReportCount = signals.length;
|
|
100579
|
+
for (const sig of signals.slice(0, 10)) {
|
|
100580
|
+
const frame = sig.topFrame;
|
|
100581
|
+
const sigKey = [sig.comment ?? "", sig.topErrorMessage ?? "", frame?.function ?? "", frame?.filename ?? ""].filter(Boolean).join(" ");
|
|
100582
|
+
const frameFileBase = (frame?.filename ?? "").split("/").pop()?.toLowerCase() ?? "";
|
|
100583
|
+
const frameMatchesSeed = seedFileBase.length > 0 && frameFileBase.length > 0 && (frameFileBase === seedFileBase || frameFileBase.includes(seedFileBase) || seedFileBase.includes(frameFileBase));
|
|
100584
|
+
const { relevanceClass: classified, relevanceReason } = classifyLogRelevance(
|
|
100585
|
+
sigKey,
|
|
100586
|
+
frame?.filename ? [frame.filename] : [],
|
|
100587
|
+
lensTerms,
|
|
100588
|
+
input.service
|
|
100589
|
+
);
|
|
100590
|
+
const relevanceClass = frameMatchesSeed ? "direct" : classified;
|
|
100591
|
+
const reason = frameMatchesSeed ? `Lens report frame at seed file ${frame?.filename ?? ""}` : relevanceReason;
|
|
100592
|
+
const commentText = sig.comment ? redactSecrets(sig.comment).slice(0, 80) : "(no comment)";
|
|
100593
|
+
const where = sig.route ?? sig.url ?? "";
|
|
100594
|
+
const whereStr = where !== "" ? ` \xB7 ${where}` : "";
|
|
100595
|
+
const frameLoc = frame?.filename ? ` @ ${frame.filename}${frame.lineno !== void 0 ? `:${frame.lineno}` : ""}` : "";
|
|
100596
|
+
const tag = relevanceClass === "ambient" ? " [ambient]" : "";
|
|
100597
|
+
const title = `Lens report: "${commentText}" \xB7 ${sig.errorCount} error(s)${whereStr} (${shortTs(sig.createdAt)})${frameLoc}${tag}`.slice(
|
|
100598
|
+
0,
|
|
100599
|
+
220
|
|
100600
|
+
);
|
|
100601
|
+
const links = {};
|
|
100602
|
+
if (frame?.filename !== void 0) links.file = frame.filename;
|
|
100603
|
+
if (frame?.lineno !== void 0) links.line = frame.lineno;
|
|
100604
|
+
const ev = mkEv(
|
|
100605
|
+
"log",
|
|
100606
|
+
title,
|
|
100607
|
+
{
|
|
100608
|
+
source: "lens",
|
|
100609
|
+
reportId: sig.id,
|
|
100610
|
+
comment: sig.comment ? redactSecrets(sig.comment) : null,
|
|
100611
|
+
route: sig.route ?? null,
|
|
100612
|
+
url: sig.url ?? null,
|
|
100613
|
+
release: sig.release ?? null,
|
|
100614
|
+
gitSha: sig.gitSha ?? null,
|
|
100615
|
+
trigger: sig.trigger ?? null,
|
|
100616
|
+
errorCount: sig.errorCount,
|
|
100617
|
+
topError: sig.topErrorMessage ? redactSecrets(sig.topErrorMessage) : null,
|
|
100618
|
+
// Direct code seed — same fields the engine reads off a code symbol.
|
|
100619
|
+
filePath: frame?.filename ?? null,
|
|
100620
|
+
symbolName: frame?.function ?? null,
|
|
100621
|
+
lineStart: frame?.lineno ?? null,
|
|
100622
|
+
failingRequests: sig.failingRequests,
|
|
100623
|
+
reactComponents: sig.reactComponents ?? null,
|
|
100624
|
+
featureFlags: sig.featureFlags ?? null,
|
|
100625
|
+
relevanceClass,
|
|
100626
|
+
relevanceReason: reason
|
|
100627
|
+
},
|
|
100628
|
+
links,
|
|
100629
|
+
sig.submittedAt ?? sig.createdAt ?? void 0,
|
|
100630
|
+
// Direct: full report weight, boosted when the raise-site frame is resolved.
|
|
100631
|
+
// Ambient: demoted so unrelated reports don't inflate confidence.
|
|
100632
|
+
relevanceClass === "direct" ? frame?.filename ? 0.95 : 0.9 : 0.45
|
|
100633
|
+
);
|
|
100634
|
+
logEvIds.push(ev.id);
|
|
100635
|
+
if (relevanceClass === "direct") {
|
|
100636
|
+
directLogEvIds.push(ev.id);
|
|
100637
|
+
const sigLabel = sig.comment && sig.comment.trim() !== "" ? redactSecrets(sig.comment).slice(0, 120) : sig.topErrorMessage ? redactSecrets(sig.topErrorMessage) : `Lens report ${sig.id}`;
|
|
100638
|
+
directSignatures.push({ key: sigLabel, count: Math.max(1, sig.errorCount), message: sigLabel });
|
|
100639
|
+
} else {
|
|
100640
|
+
ambientLogEvIds.push(ev.id);
|
|
100641
|
+
}
|
|
100642
|
+
}
|
|
100643
|
+
} catch (lensErr) {
|
|
100644
|
+
lensCollected = false;
|
|
100645
|
+
lensFailureReason = connectorFailureReason(lensErr);
|
|
100646
|
+
}
|
|
100647
|
+
}
|
|
100058
100648
|
let axiomCollected = false;
|
|
100059
100649
|
let axiomFailureReason;
|
|
100060
100650
|
if (deps.axiom) {
|
|
@@ -101080,6 +101670,7 @@ async function investigate(input, deps) {
|
|
|
101080
101670
|
["mongodb", deps.connectors.mongodb, deps.mongo],
|
|
101081
101671
|
["postgres", deps.connectors.postgres, deps.postgres],
|
|
101082
101672
|
["sentry", deps.connectors.sentry, deps.sentry],
|
|
101673
|
+
["lens", deps.connectors.lens, deps.lens],
|
|
101083
101674
|
["axiom", deps.connectors.axiom, deps.axiom],
|
|
101084
101675
|
["shopify", deps.connectors.shopify, deps.shopify],
|
|
101085
101676
|
["redis", deps.connectors.redis, deps.redisState]
|
|
@@ -101095,6 +101686,8 @@ async function investigate(input, deps) {
|
|
|
101095
101686
|
// `unavailable` instead of silently flipping to "not configured".
|
|
101096
101687
|
sentryCollected,
|
|
101097
101688
|
sentryFailureReason,
|
|
101689
|
+
lensCollected,
|
|
101690
|
+
lensFailureReason,
|
|
101098
101691
|
axiomCollected,
|
|
101099
101692
|
axiomFailureReason,
|
|
101100
101693
|
shopifyCollected,
|
|
@@ -101117,6 +101710,9 @@ async function investigate(input, deps) {
|
|
|
101117
101710
|
sentry: deps.sentry != null,
|
|
101118
101711
|
sentryCollected,
|
|
101119
101712
|
sentryFailureReason,
|
|
101713
|
+
lens: deps.lens != null,
|
|
101714
|
+
lensCollected,
|
|
101715
|
+
lensFailureReason,
|
|
101120
101716
|
axiom: deps.axiom != null,
|
|
101121
101717
|
axiomCollected,
|
|
101122
101718
|
axiomFailureReason,
|
|
@@ -104451,8 +105047,8 @@ function buildLowerPriority(report, seedLowConfidence, effectiveTopLower) {
|
|
|
104451
105047
|
});
|
|
104452
105048
|
const noEvidence = !c4.implicated && !hasRuntimeEvidence;
|
|
104453
105049
|
if (!noEvidence) continue;
|
|
104454
|
-
const
|
|
104455
|
-
if (
|
|
105050
|
+
const inWindow2 = [...c4.files].some((f5) => changedFiles.has(f5));
|
|
105051
|
+
if (inWindow2) continue;
|
|
104456
105052
|
out2.push({
|
|
104457
105053
|
area: c4.area,
|
|
104458
105054
|
reasons: [
|
|
@@ -120039,6 +120635,9 @@ async function buildInvestigationContext(renv, opts) {
|
|
|
120039
120635
|
const mongo = mongoForEnv(renv);
|
|
120040
120636
|
const postgres2 = postgresForEnv(renv);
|
|
120041
120637
|
const sentry = sentryForEnv(renv);
|
|
120638
|
+
const auth = readAuth();
|
|
120639
|
+
const cloudCfg = readCloudConfig(renv.path);
|
|
120640
|
+
const lens = auth && cloudCfg?.workspace?.id ? lensForCloud({ apiBaseUrl: auth.apiBaseUrl, token: auth.token, workspaceId: cloudCfg.workspace.id }) : null;
|
|
120042
120641
|
const axiom = axiomForEnv(renv);
|
|
120043
120642
|
const shopify = shopifyForEnv(renv);
|
|
120044
120643
|
const queue = queueForEnv(renv);
|
|
@@ -120057,6 +120656,7 @@ async function buildInvestigationContext(renv, opts) {
|
|
|
120057
120656
|
mongo,
|
|
120058
120657
|
postgres: postgres2,
|
|
120059
120658
|
sentry,
|
|
120659
|
+
lens,
|
|
120060
120660
|
axiom,
|
|
120061
120661
|
shopify,
|
|
120062
120662
|
queue,
|
|
@@ -120109,6 +120709,7 @@ async function runOneInvestigation(input, ctx, opts = {}) {
|
|
|
120109
120709
|
mongo: ctx.mongo,
|
|
120110
120710
|
postgres: ctx.postgres,
|
|
120111
120711
|
sentry: ctx.sentry,
|
|
120712
|
+
lens: ctx.lens,
|
|
120112
120713
|
axiom: ctx.axiom,
|
|
120113
120714
|
shopify: ctx.shopify,
|
|
120114
120715
|
queue: ctx.queue,
|
|
@@ -120125,6 +120726,9 @@ async function runOneInvestigation(input, ctx, opts = {}) {
|
|
|
120125
120726
|
mongodb: !!renv.connectors.mongodb,
|
|
120126
120727
|
postgres: !!renv.connectors.postgres,
|
|
120127
120728
|
sentry: !!renv.connectors.sentry,
|
|
120729
|
+
// Lens is NATIVE (no config stanza) — "configured" == provider present, mirroring how
|
|
120730
|
+
// `queue` is derived from `ctx.queue`. Absent when not logged in / repo not cloud-linked.
|
|
120731
|
+
lens: ctx.lens != null,
|
|
120128
120732
|
axiom: !!renv.connectors.axiom,
|
|
120129
120733
|
shopify: !!renv.connectors.shopify,
|
|
120130
120734
|
redis: !!renv.connectors.redis,
|