@merittdev/horus 0.16.1 → 0.17.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.cjs +93 -5
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -65880,7 +65880,7 @@ init_cjs_shims();
|
|
|
65880
65880
|
|
|
65881
65881
|
// ../../packages/core/src/version.ts
|
|
65882
65882
|
init_cjs_shims();
|
|
65883
|
-
var HORUS_VERSION = true ? "0.
|
|
65883
|
+
var HORUS_VERSION = true ? "0.17.0" : "dev";
|
|
65884
65884
|
var PINNED_SOURCE_VERSION = "2.0.2";
|
|
65885
65885
|
|
|
65886
65886
|
// ../../packages/core/src/evidence.ts
|
|
@@ -70670,10 +70670,23 @@ var connectorsSchema = external_exports.object({
|
|
|
70670
70670
|
).optional()
|
|
70671
70671
|
}).optional()
|
|
70672
70672
|
}).default({});
|
|
70673
|
+
var notifySchema = external_exports.object({
|
|
70674
|
+
/** Only dispatch when an auto-investigation's confidence is >= this (0..1). Default 0.6. */
|
|
70675
|
+
minConfidence: external_exports.number().min(0).max(1).default(0.6),
|
|
70676
|
+
/** Generic outbound webhook (Slack-compatible JSON, HMAC-signed when `secret` is set). */
|
|
70677
|
+
webhook: external_exports.object({
|
|
70678
|
+
url: external_exports.string().url(),
|
|
70679
|
+
/** HMAC-SHA256 signing secret; when set, payloads carry an `X-Horus-Signature` header. */
|
|
70680
|
+
secret: external_exports.string().min(1).optional()
|
|
70681
|
+
}).optional(),
|
|
70682
|
+
/** Also push the headline to Horus Cloud (uses the existing cloud session, if signed in). */
|
|
70683
|
+
cloud: external_exports.boolean().default(false)
|
|
70684
|
+
}).optional();
|
|
70673
70685
|
var environmentSchema = external_exports.object({
|
|
70674
70686
|
name: external_exports.string().min(1),
|
|
70675
70687
|
readOnly: external_exports.boolean().default(true),
|
|
70676
|
-
connectors: connectorsSchema
|
|
70688
|
+
connectors: connectorsSchema,
|
|
70689
|
+
notify: notifySchema
|
|
70677
70690
|
});
|
|
70678
70691
|
var projectSchema = external_exports.object({
|
|
70679
70692
|
name: external_exports.string().min(1),
|
|
@@ -70919,7 +70932,8 @@ function resolveEnvironment(config2, opts) {
|
|
|
70919
70932
|
readOnly: environment.readOnly,
|
|
70920
70933
|
repositories: repositories2,
|
|
70921
70934
|
path: primary?.path ?? "",
|
|
70922
|
-
connectors: resolved
|
|
70935
|
+
connectors: resolved,
|
|
70936
|
+
...environment.notify !== void 0 ? { notify: environment.notify } : {}
|
|
70923
70937
|
};
|
|
70924
70938
|
}
|
|
70925
70939
|
var CONFIG_EXAMPLES = {
|
|
@@ -118235,6 +118249,70 @@ async function runPacket(hintOrId, opts) {
|
|
|
118235
118249
|
// ../../packages/cli/src/commands/watch.ts
|
|
118236
118250
|
init_cjs_shims();
|
|
118237
118251
|
var import_picocolors19 = __toESM(require_picocolors(), 1);
|
|
118252
|
+
|
|
118253
|
+
// ../../packages/cli/src/lib/notify-sink.ts
|
|
118254
|
+
init_cjs_shims();
|
|
118255
|
+
var import_node_crypto11 = require("crypto");
|
|
118256
|
+
function buildWebhookPayload(h3) {
|
|
118257
|
+
const pct2 = `${Math.round(h3.confidence * 100)}%`;
|
|
118258
|
+
return {
|
|
118259
|
+
text: `\u{1F52D} Horus: ${h3.hint} \u2192 ${h3.cause} (${pct2})`,
|
|
118260
|
+
investigationId: h3.investigationId,
|
|
118261
|
+
hint: h3.hint,
|
|
118262
|
+
cause: h3.cause,
|
|
118263
|
+
confidence: h3.confidence
|
|
118264
|
+
};
|
|
118265
|
+
}
|
|
118266
|
+
function signPayload(body2, secret) {
|
|
118267
|
+
return `sha256=${(0, import_node_crypto11.createHmac)("sha256", secret).update(body2).digest("hex")}`;
|
|
118268
|
+
}
|
|
118269
|
+
function shouldNotify(confidence, notify) {
|
|
118270
|
+
if (notify === void 0) return false;
|
|
118271
|
+
if (notify.webhook === void 0 && notify.cloud !== true) return false;
|
|
118272
|
+
return confidence >= notify.minConfidence;
|
|
118273
|
+
}
|
|
118274
|
+
async function postWebhook(url, secret, h3, timeoutMs) {
|
|
118275
|
+
const body2 = JSON.stringify(buildWebhookPayload(h3));
|
|
118276
|
+
const headers = { "content-type": "application/json" };
|
|
118277
|
+
if (secret !== void 0) headers["x-horus-signature"] = signPayload(body2, secret);
|
|
118278
|
+
const controller = new AbortController();
|
|
118279
|
+
const timer2 = setTimeout(() => controller.abort(), timeoutMs);
|
|
118280
|
+
try {
|
|
118281
|
+
const res = await fetch(url, { method: "POST", headers, body: body2, signal: controller.signal });
|
|
118282
|
+
if (!res.ok) return { target: "webhook", ok: false, detail: `HTTP ${res.status}` };
|
|
118283
|
+
return { target: "webhook", ok: true, detail: `HTTP ${res.status}` };
|
|
118284
|
+
} catch (err2) {
|
|
118285
|
+
return { target: "webhook", ok: false, detail: err2.message };
|
|
118286
|
+
} finally {
|
|
118287
|
+
clearTimeout(timer2);
|
|
118288
|
+
}
|
|
118289
|
+
}
|
|
118290
|
+
async function dispatchNotify(report, notify, opts = {}) {
|
|
118291
|
+
if (notify === void 0) return [];
|
|
118292
|
+
const h3 = {
|
|
118293
|
+
investigationId: report.id,
|
|
118294
|
+
hint: report.hint,
|
|
118295
|
+
cause: report.cause,
|
|
118296
|
+
confidence: report.confidence
|
|
118297
|
+
};
|
|
118298
|
+
if (!shouldNotify(report.confidence, notify)) return [];
|
|
118299
|
+
const timeoutMs = opts.timeoutMs ?? 5e3;
|
|
118300
|
+
const results = [];
|
|
118301
|
+
if (notify.webhook !== void 0) {
|
|
118302
|
+
results.push(await postWebhook(notify.webhook.url, notify.webhook.secret, h3, timeoutMs));
|
|
118303
|
+
}
|
|
118304
|
+
if (notify.cloud === true && opts.cloudPush !== void 0) {
|
|
118305
|
+
try {
|
|
118306
|
+
await opts.cloudPush();
|
|
118307
|
+
results.push({ target: "cloud", ok: true, detail: "pushed" });
|
|
118308
|
+
} catch (err2) {
|
|
118309
|
+
results.push({ target: "cloud", ok: false, detail: err2.message });
|
|
118310
|
+
}
|
|
118311
|
+
}
|
|
118312
|
+
return results;
|
|
118313
|
+
}
|
|
118314
|
+
|
|
118315
|
+
// ../../packages/cli/src/commands/watch.ts
|
|
118238
118316
|
function detectNewSentryIncidents(issues, seen) {
|
|
118239
118317
|
const fresh = [];
|
|
118240
118318
|
for (const issue2 of issues) {
|
|
@@ -118364,6 +118442,16 @@ async function runWatch(opts) {
|
|
|
118364
118442
|
console.log(
|
|
118365
118443
|
`${import_picocolors19.default.bold("\u25CF")} ${incident.hint} ${import_picocolors19.default.dim("\u2192")} ${cause} ${import_picocolors19.default.dim(`(${(confidence * 100).toFixed(0)}%)`)} ${import_picocolors19.default.dim(`id: ${report.id}`)}${persisted}`
|
|
118366
118444
|
);
|
|
118445
|
+
if (shouldNotify(confidence, renv.notify)) {
|
|
118446
|
+
const results = await dispatchNotify(
|
|
118447
|
+
{ id: report.id, confidence, hint: incident.hint, cause },
|
|
118448
|
+
renv.notify
|
|
118449
|
+
);
|
|
118450
|
+
for (const r of results) {
|
|
118451
|
+
if (r.ok) console.error(import_picocolors19.default.dim(`[watch] notified ${r.target} (${r.detail})`));
|
|
118452
|
+
else console.error(import_picocolors19.default.yellow(`[watch] notify ${r.target} failed \u2014 ${r.detail}`));
|
|
118453
|
+
}
|
|
118454
|
+
}
|
|
118367
118455
|
} catch (err2) {
|
|
118368
118456
|
console.error(
|
|
118369
118457
|
import_picocolors19.default.yellow(`[watch] investigation failed for "${incident.ref}" \u2014 ${err2.message}`)
|
|
@@ -125233,7 +125321,7 @@ async function createProjectFromRepo(client, ctx, remote, yes) {
|
|
|
125233
125321
|
// ../../packages/cli/src/commands/telemetry.ts
|
|
125234
125322
|
init_cjs_shims();
|
|
125235
125323
|
var import_picocolors56 = __toESM(require_picocolors(), 1);
|
|
125236
|
-
var
|
|
125324
|
+
var import_node_crypto12 = require("crypto");
|
|
125237
125325
|
|
|
125238
125326
|
// ../../packages/cli/src/lib/telemetry/transport.ts
|
|
125239
125327
|
init_cjs_shims();
|
|
@@ -125425,7 +125513,7 @@ async function runTelemetryDisableContent() {
|
|
|
125425
125513
|
return 0;
|
|
125426
125514
|
}
|
|
125427
125515
|
async function runTelemetryResetId() {
|
|
125428
|
-
const next = (0,
|
|
125516
|
+
const next = (0, import_node_crypto12.randomUUID)();
|
|
125429
125517
|
updateTelemetryState((s5) => {
|
|
125430
125518
|
s5.installId = next;
|
|
125431
125519
|
});
|