fix(runtime): fix early control return and update lifecycle

This commit is contained in:
Ljy-0827
2026-07-24 14:07:33 +08:00
parent c8963e3a68
commit 4e44fb2823
17 changed files with 1002 additions and 262 deletions
@@ -1,10 +1,17 @@
import { describe, expect, it } from "vitest";
import {
HELP_ACK,
HELP_CANCEL,
HELP_FINISH,
HELP_QUERY,
HELP_REQUEST,
HELP_RESPONSE,
isHelpAckMessage,
isHelpCancelMessage,
isHelpFinishMessage,
isHelpQueryMessage,
isHelpRequestMessage,
isHelpResponseMessage,
} from "../help-bridge";
describe("help-bridge", () => {
@@ -12,6 +19,9 @@ describe("help-bridge", () => {
expect(HELP_REQUEST).toBe("bsk-help-request");
expect(HELP_RESPONSE).toBe("bsk-help-response");
expect(HELP_CANCEL).toBe("bsk-help-cancel");
expect(HELP_ACK).toBe("bsk-help-ack");
expect(HELP_QUERY).toBe("bsk-help-query");
expect(HELP_FINISH).toBe("bsk-help-finish");
});
it("type-guards a help-request message", () => {
@@ -55,4 +65,18 @@ describe("help-bridge", () => {
expect(isHelpCancelMessage({ type: HELP_REQUEST, requestId: "r1" })).toBe(false);
expect(isHelpCancelMessage(null)).toBe(false);
});
it("type-guards lifecycle messages", () => {
expect(isHelpAckMessage({ type: HELP_ACK, ok: true })).toBe(true);
expect(isHelpQueryMessage({ type: HELP_QUERY })).toBe(true);
expect(isHelpFinishMessage({ type: HELP_FINISH, requestId: "r1", outcome: "continued" })).toBe(
true,
);
expect(isHelpResponseMessage({ type: HELP_RESPONSE, outcome: "cancelled", note: "no" })).toBe(
true,
);
expect(isHelpFinishMessage({ type: HELP_FINISH, requestId: "r1", outcome: "weird" })).toBe(
false,
);
});
});
+58 -1
View File
@@ -6,12 +6,15 @@
* Mirrors the borrow-confirmation message style (see
* `@/tools/borrow-confirmation`). The background asks a specific tab to
* enter "help mode" (render HelpRequestOverlay + hide ControlOverlay);
* the content script replies once the user clicks Continue / Cancel.
* the content script acks display, then later reports Done / Cancel.
*/
export const HELP_REQUEST = "bsk-help-request";
export const HELP_RESPONSE = "bsk-help-response";
export const HELP_CANCEL = "bsk-help-cancel";
export const HELP_ACK = "bsk-help-ack";
export const HELP_QUERY = "bsk-help-query";
export const HELP_FINISH = "bsk-help-finish";
export interface HelpRequestMessage {
type: typeof HELP_REQUEST;
@@ -24,6 +27,11 @@ export interface HelpRequestMessage {
timeoutMs: number;
}
export interface HelpAckMessage {
type: typeof HELP_ACK;
ok: true;
}
export interface HelpResponseMessage {
type: typeof HELP_RESPONSE;
outcome: "continued" | "cancelled";
@@ -35,6 +43,22 @@ export interface HelpCancelMessage {
requestId: string;
}
export interface HelpQueryMessage {
type: typeof HELP_QUERY;
}
export interface HelpQueryResponse {
active: boolean;
request?: Omit<HelpRequestMessage, "type">;
}
export interface HelpFinishMessage {
type: typeof HELP_FINISH;
requestId: string;
outcome: "continued" | "cancelled";
note?: string;
}
export function isHelpRequestMessage(msg: unknown): msg is HelpRequestMessage {
if (typeof msg !== "object" || msg === null) {
return false;
@@ -58,3 +82,36 @@ export function isHelpCancelMessage(msg: unknown): msg is HelpCancelMessage {
const m = msg as Record<string, unknown>;
return m.type === HELP_CANCEL && typeof m.requestId === "string";
}
export function isHelpResponseMessage(msg: unknown): msg is HelpResponseMessage {
if (typeof msg !== "object" || msg === null) return false;
const m = msg as Record<string, unknown>;
return (
m.type === HELP_RESPONSE &&
(m.outcome === "continued" || m.outcome === "cancelled") &&
(m.note === undefined || typeof m.note === "string")
);
}
export function isHelpAckMessage(msg: unknown): msg is HelpAckMessage {
if (typeof msg !== "object" || msg === null) return false;
const m = msg as Record<string, unknown>;
return m.type === HELP_ACK && m.ok === true;
}
export function isHelpQueryMessage(msg: unknown): msg is HelpQueryMessage {
if (typeof msg !== "object" || msg === null) return false;
const m = msg as Record<string, unknown>;
return m.type === HELP_QUERY;
}
export function isHelpFinishMessage(msg: unknown): msg is HelpFinishMessage {
if (typeof msg !== "object" || msg === null) return false;
const m = msg as Record<string, unknown>;
return (
m.type === HELP_FINISH &&
typeof m.requestId === "string" &&
(m.outcome === "continued" || m.outcome === "cancelled") &&
(m.note === undefined || typeof m.note === "string")
);
}