@tritard/waterbrother 0.16.109 → 0.16.110
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/package.json +1 -1
- package/src/gateway.js +148 -0
package/package.json
CHANGED
package/src/gateway.js
CHANGED
|
@@ -646,6 +646,36 @@ function getLatestReviewResult(project) {
|
|
|
646
646
|
return ordered.find((event) => String(event?.type || "").trim() === "review-result") || null;
|
|
647
647
|
}
|
|
648
648
|
|
|
649
|
+
function getBlockingVerificationResult(project) {
|
|
650
|
+
if (String(project?.verificationMode || "manual").trim() !== "blocking") {
|
|
651
|
+
return null;
|
|
652
|
+
}
|
|
653
|
+
const latestResult = getLatestVerificationResult(project);
|
|
654
|
+
const latestId = String(latestResult?.id || "").trim();
|
|
655
|
+
const latestOutcome = String(latestResult?.outcome || "").trim().toLowerCase();
|
|
656
|
+
if (!latestId || !latestOutcome || latestOutcome === "passed") {
|
|
657
|
+
return null;
|
|
658
|
+
}
|
|
659
|
+
const events = Array.isArray(project?.recentEvents) ? [...project.recentEvents] : [];
|
|
660
|
+
const ordered = events
|
|
661
|
+
.filter((event) => event?.createdAt)
|
|
662
|
+
.sort((a, b) => String(b.createdAt || "").localeCompare(String(a.createdAt || "")));
|
|
663
|
+
for (const event of ordered) {
|
|
664
|
+
const type = String(event?.type || "").trim();
|
|
665
|
+
const meta = event?.meta && typeof event.meta === "object" ? event.meta : {};
|
|
666
|
+
if (String(meta.verificationResultId || "").trim() !== latestId) {
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
if (type === "verification-override") {
|
|
670
|
+
return null;
|
|
671
|
+
}
|
|
672
|
+
if (type === "verification-result") {
|
|
673
|
+
return latestResult;
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
return latestResult;
|
|
677
|
+
}
|
|
678
|
+
|
|
649
679
|
function memberRoleWeight(role = "") {
|
|
650
680
|
const normalized = String(role || "").trim().toLowerCase();
|
|
651
681
|
if (normalized === "owner") return 3;
|
|
@@ -916,6 +946,12 @@ function parseTelegramStateIntent(text = "") {
|
|
|
916
946
|
if (/^(?:run|start|do)\s+verification\b/.test(lower) || /^(?:verify)\b/.test(lower) || /\bshow latest verification result\b/.test(lower) || /\bdid verification pass\b/.test(lower)) {
|
|
917
947
|
return { action: /\bshow latest verification result\b/.test(lower) || /\bdid verification pass\b/.test(lower) ? "verification-status" : "run-verification" };
|
|
918
948
|
}
|
|
949
|
+
if (/\boverride verification\b/.test(lower)) {
|
|
950
|
+
return { action: "verification-override" };
|
|
951
|
+
}
|
|
952
|
+
if (/\bre-?run verification\b/.test(lower) || /\brun verification again\b/.test(lower) || /\bverify again\b/.test(lower)) {
|
|
953
|
+
return { action: "verification-rerun" };
|
|
954
|
+
}
|
|
919
955
|
if (/\bverification mode\b/.test(lower)) {
|
|
920
956
|
const modeMatch = lower.match(/\b(off|manual|auto|blocking)\b/);
|
|
921
957
|
return modeMatch?.[1] ? { action: "verification-mode-set", mode: modeMatch[1] } : { action: "verification-mode-status" };
|
|
@@ -2435,6 +2471,29 @@ class TelegramGateway {
|
|
|
2435
2471
|
}
|
|
2436
2472
|
};
|
|
2437
2473
|
}
|
|
2474
|
+
if (continuation.kind === "blocking-verification-override") {
|
|
2475
|
+
const reply = this.stripBotMention(String(message?.text || "").trim()).toLowerCase();
|
|
2476
|
+
if (/\boverride verification\b/.test(reply) || /\boverride\b/.test(reply)) {
|
|
2477
|
+
return {
|
|
2478
|
+
markup: await this.handleStateIntent(message, sessionId, { action: "verification-override" })
|
|
2479
|
+
};
|
|
2480
|
+
}
|
|
2481
|
+
if (/\bre-?run verification\b/.test(reply) || /\brerun\b/.test(reply) || /\bverify again\b/.test(reply)) {
|
|
2482
|
+
return {
|
|
2483
|
+
markup: await this.handleStateIntent(message, sessionId, { action: "verification-rerun" })
|
|
2484
|
+
};
|
|
2485
|
+
}
|
|
2486
|
+
return {
|
|
2487
|
+
markup: "Reply with <code>rerun verification</code> or <code>override verification</code>.",
|
|
2488
|
+
remember: {
|
|
2489
|
+
text: String(continuation.lastPrompt || "").trim() || "Reply with rerun verification or override verification.",
|
|
2490
|
+
kind: continuation.kind,
|
|
2491
|
+
source: continuation.source,
|
|
2492
|
+
context: continuation.context || {},
|
|
2493
|
+
force: true
|
|
2494
|
+
}
|
|
2495
|
+
};
|
|
2496
|
+
}
|
|
2438
2497
|
return null;
|
|
2439
2498
|
}
|
|
2440
2499
|
|
|
@@ -2532,6 +2591,37 @@ class TelegramGateway {
|
|
|
2532
2591
|
return formatVerificationResultMarkup(result, verifier);
|
|
2533
2592
|
}
|
|
2534
2593
|
|
|
2594
|
+
if (intent.action === "verification-override") {
|
|
2595
|
+
if (!project?.enabled) {
|
|
2596
|
+
return "This project is not shared.";
|
|
2597
|
+
}
|
|
2598
|
+
const blockingVerification = getBlockingVerificationResult(project);
|
|
2599
|
+
if (!blockingVerification) {
|
|
2600
|
+
return "<b>Verification override</b>\nNo blocking verification is active.";
|
|
2601
|
+
}
|
|
2602
|
+
await addSharedRoomNote(cwd, "Blocking verification overridden for now", {
|
|
2603
|
+
actorId,
|
|
2604
|
+
actorName,
|
|
2605
|
+
type: "verification-override",
|
|
2606
|
+
meta: {
|
|
2607
|
+
verificationResultId: String(blockingVerification.id || "").trim(),
|
|
2608
|
+
outcome: String(blockingVerification.outcome || "").trim()
|
|
2609
|
+
}
|
|
2610
|
+
});
|
|
2611
|
+
return [
|
|
2612
|
+
"<b>Verification overridden</b>",
|
|
2613
|
+
`latest outcome: <code>${escapeTelegramHtml(String(blockingVerification.outcome || "failed"))}</code>`,
|
|
2614
|
+
"Execution can proceed for now."
|
|
2615
|
+
].join("\n");
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2618
|
+
if (intent.action === "verification-rerun") {
|
|
2619
|
+
if (!project?.enabled) {
|
|
2620
|
+
return "This project is not shared.";
|
|
2621
|
+
}
|
|
2622
|
+
return this.handleStateIntent(message, sessionId, { action: "run-verification" });
|
|
2623
|
+
}
|
|
2624
|
+
|
|
2535
2625
|
if (intent.action === "run-verification") {
|
|
2536
2626
|
if (!project?.enabled) {
|
|
2537
2627
|
return "This project is not shared.";
|
|
@@ -4623,6 +4713,31 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
|
|
|
4623
4713
|
});
|
|
4624
4714
|
return;
|
|
4625
4715
|
}
|
|
4716
|
+
const blockingVerification = getBlockingVerificationResult(operatorGate.project);
|
|
4717
|
+
if (blockingVerification) {
|
|
4718
|
+
const followUp = "Reply with rerun verification to try again, or override verification to proceed anyway.";
|
|
4719
|
+
await this.sendMarkup(
|
|
4720
|
+
message.chat.id,
|
|
4721
|
+
[
|
|
4722
|
+
"<b>Blocking verification in effect</b>",
|
|
4723
|
+
`latest outcome: <code>${escapeTelegramHtml(String(blockingVerification.outcome || "failed"))}</code>`,
|
|
4724
|
+
blockingVerification.summary ? `summary: <code>${escapeTelegramHtml(String(blockingVerification.summary || ""))}</code>` : "",
|
|
4725
|
+
"Execution is paused until verification passes or the room overrides it.",
|
|
4726
|
+
followUp
|
|
4727
|
+
].filter(Boolean).join("\n"),
|
|
4728
|
+
message.message_id
|
|
4729
|
+
);
|
|
4730
|
+
await this.rememberContinuationWithOptions(message, followUp, {
|
|
4731
|
+
kind: "blocking-verification-override",
|
|
4732
|
+
source: "verification-policy-gate",
|
|
4733
|
+
context: {
|
|
4734
|
+
verificationResultId: String(blockingVerification.id || "").trim(),
|
|
4735
|
+
outcome: String(blockingVerification.outcome || "").trim()
|
|
4736
|
+
},
|
|
4737
|
+
force: true
|
|
4738
|
+
});
|
|
4739
|
+
return;
|
|
4740
|
+
}
|
|
4626
4741
|
const liveHosts = await this.getLiveBridgeHosts({ cwd: operatorGate.session?.cwd || this.cwd });
|
|
4627
4742
|
const host = await this.getLiveBridgeHost();
|
|
4628
4743
|
const activeExecutor = {
|
|
@@ -4689,6 +4804,39 @@ Ask them to run <code>/whoami</code> and then <code>/accept-invite ${escapeTeleg
|
|
|
4689
4804
|
sourceHost: typeof result === "string" ? null : (result?.sourceHost || null)
|
|
4690
4805
|
});
|
|
4691
4806
|
await this.rememberContinuation(message, finalContent);
|
|
4807
|
+
if (["auto", "blocking"].includes(String(operatorGate.project?.verificationMode || "manual").trim())) {
|
|
4808
|
+
const verificationMarkup = await this.handleStateIntent(message, sessionId, { action: "run-verification" });
|
|
4809
|
+
if (verificationMarkup) {
|
|
4810
|
+
await this.sendMarkup(message.chat.id, verificationMarkup, message.message_id);
|
|
4811
|
+
}
|
|
4812
|
+
if (String(operatorGate.project?.verificationMode || "manual").trim() === "blocking") {
|
|
4813
|
+
const nextProject = await loadSharedProject(operatorGate.session?.cwd || this.cwd);
|
|
4814
|
+
const nextBlockingVerification = getBlockingVerificationResult(nextProject);
|
|
4815
|
+
if (nextBlockingVerification) {
|
|
4816
|
+
const followUp = "Reply with rerun verification to try again, or override verification to proceed anyway.";
|
|
4817
|
+
await this.sendMarkup(
|
|
4818
|
+
message.chat.id,
|
|
4819
|
+
[
|
|
4820
|
+
"<b>Blocking verification in effect</b>",
|
|
4821
|
+
`latest outcome: <code>${escapeTelegramHtml(String(nextBlockingVerification.outcome || "failed"))}</code>`,
|
|
4822
|
+
nextBlockingVerification.summary ? `summary: <code>${escapeTelegramHtml(String(nextBlockingVerification.summary || ""))}</code>` : "",
|
|
4823
|
+
"Further execution is paused until verification passes or the room overrides it.",
|
|
4824
|
+
followUp
|
|
4825
|
+
].filter(Boolean).join("\n"),
|
|
4826
|
+
message.message_id
|
|
4827
|
+
);
|
|
4828
|
+
await this.rememberContinuationWithOptions(message, followUp, {
|
|
4829
|
+
kind: "blocking-verification-override",
|
|
4830
|
+
source: "verification-policy-gate",
|
|
4831
|
+
context: {
|
|
4832
|
+
verificationResultId: String(nextBlockingVerification.id || "").trim(),
|
|
4833
|
+
outcome: String(nextBlockingVerification.outcome || "").trim()
|
|
4834
|
+
},
|
|
4835
|
+
force: true
|
|
4836
|
+
});
|
|
4837
|
+
}
|
|
4838
|
+
}
|
|
4839
|
+
}
|
|
4692
4840
|
} catch (error) {
|
|
4693
4841
|
await this.deliverPromptFailure(message.chat.id, message.message_id, previewMessage, error);
|
|
4694
4842
|
} finally {
|