front/xhs-agent-desktop/engine/extension/popup.js
zzh 5a26ae0048 feat: 小红书模块迁移、登录重构与 xhs-agent-desktop 桌面 Agent
- 新增小红书前端模块(启动服务、内容分析、爆款创作、发布记录、技能卡片、拟人设置、AI 助手)

- 新增 xhs-agent-desktop 独立桌面 Agent,对接 OMS 任务调度

- 登录页重构,整合微信登录与 OMS JWT 认证

- 订单、渠道、用户中心等页面与 API 增强

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 16:13:13 +08:00

152 lines
3.7 KiB
JavaScript

const BRIDGE_URL = "ws://localhost:9333";
const REFRESH_MS = 2000;
const badgeBridge = document.getElementById("badge-bridge");
const badgeExtension = document.getElementById("badge-extension");
const badgeLogin = document.getElementById("badge-login");
const hintText = document.getElementById("hint-text");
const btnRefresh = document.getElementById("btn-refresh");
const btnOpenXhs = document.getElementById("btn-open-xhs");
let timerId = null;
function setBadge(el, kind, text) {
el.textContent = text;
el.className = `badge ${kind}`;
}
function pingBridgeServer() {
return new Promise((resolve) => {
let settled = false;
const finish = (value) => {
if (settled) return;
settled = true;
resolve(value);
};
let ws;
try {
ws = new WebSocket(BRIDGE_URL);
} catch (err) {
finish({ server: false, extension: false, error: String(err) });
return;
}
const timer = setTimeout(() => {
try {
ws.close();
} catch (_) {
/* ignore */
}
finish({ server: false, extension: false });
}, 2500);
ws.onopen = () => {
ws.send(JSON.stringify({ role: "cli", method: "ping_server" }));
};
ws.onmessage = (event) => {
clearTimeout(timer);
try {
const data = JSON.parse(event.data);
finish({
server: true,
extension: !!(data.result && data.result.extension_connected),
});
} catch (_) {
finish({ server: true, extension: false });
}
try {
ws.close();
} catch (_) {
/* ignore */
}
};
ws.onerror = () => {
clearTimeout(timer);
finish({ server: false, extension: false });
};
});
}
async function getExtensionWsStatus() {
try {
return await chrome.runtime.sendMessage({ type: "monitor_bridge_ws" });
} catch (_) {
return { extension_connected: false };
}
}
async function checkXhsLogin() {
try {
return await chrome.runtime.sendMessage({ type: "monitor_check_login" });
} catch (err) {
return { logged_in: false, error: String(err) };
}
}
async function refreshStatus() {
const now = new Date().toLocaleTimeString("zh-CN", { hour12: false });
hintText.textContent = `更新于 ${now}`;
setBadge(badgeBridge, "idle", "检测中…");
setBadge(badgeExtension, "idle", "检测中…");
setBadge(badgeLogin, "idle", "检测中…");
const [bridge, wsStatus, login] = await Promise.all([
pingBridgeServer(),
getExtensionWsStatus(),
checkXhsLogin(),
]);
if (bridge.server) {
setBadge(badgeBridge, "ok", "运行中");
} else {
setBadge(badgeBridge, "err", "未启动");
}
const extOk = bridge.extension || wsStatus.extension_connected;
if (extOk) {
setBadge(badgeExtension, "ok", "已连接");
} else if (bridge.server) {
setBadge(badgeExtension, "warn", "未连上");
} else {
setBadge(badgeExtension, "err", "未连接");
}
if (login.logged_in) {
setBadge(badgeLogin, "ok", "已登录");
} else if (login.uncertain) {
setBadge(badgeLogin, "warn", "不确定");
} else {
setBadge(badgeLogin, "warn", "未登录");
}
if (login.hint) {
hintText.textContent = `${login.hint} · ${now}`;
}
}
function startAutoRefresh() {
if (timerId) clearInterval(timerId);
timerId = setInterval(refreshStatus, REFRESH_MS);
}
btnRefresh.addEventListener("click", () => {
refreshStatus();
});
btnOpenXhs.addEventListener("click", () => {
chrome.tabs.create({ url: "https://www.xiaohongshu.com/" });
});
refreshStatus();
startAutoRefresh();
document.addEventListener("visibilitychange", () => {
if (document.visibilityState === "visible") {
refreshStatus();
}
});