- Auto-connect WebSocket on page load in service console - Settings modal for editing sgclaw_config.json (API key, base URL, model, skills dir, etc.) - UpdateConfig/ConfigUpdated protocol messages for remote config save - save_to_path() for SgClawSettings serialization - ConfigUpdated handler in sg_claw_client binary - Protocol serialization tests for new message types - HTML test assertions for auto-connect and settings UI - Additional pending changes: deterministic submit, org units, lineloss xlsx export, browser script tool, and docs 🤖 Generated with [Qoder][https://qoder.com]
3.2 KiB
Remove mac Guard from validatePageContext
Date
2026-04-13
Problem
tq-lineloss-report skill execution reports status=blocked rows=0 reasons=page_context_unavailable.
Diagnostic instrumentation confirmed:
href=http://20.76.57.61:18080/gsllys
host=20.76.57.61
port=18080
title=台区线损大数据分析模块
mac=false
The script executes on the correct domain but globalThis.mac does not exist, triggering the page_context_unavailable guard.
Root Cause
window.mac is a Vue instance created by the original scene page (index.html), assigned via window.mac = this in mounted(). The original scene page acts as a controller that injects JS into the business page via BrowserAction('sgBrowserExcuteJsCode', exactURL, jsCode).
In the skill execution model, there is no scene page. The script is injected directly via sgBrowserExcuteJsCodeByDomain onto a page matching the domain. No Vue instance is created, so globalThis.mac is always undefined. The mac check is architecturally invalid for the skill model.
Additionally, sgBrowserExcuteJsCodeByDomain("20.76.57.61") matches the parent frame page (/gsllys) rather than the business sub-page (/gsllys/tqLinelossStatis/tqQualifyRateMonitor). This is acceptable because the skill script makes direct HTTP requests with absolute URLs and does not depend on page-local state.
Design
Remove the globalThis.mac existence check from validatePageContext in collect_lineloss.js. Retain the host matching check as a basic domain guard.
Also clean up the temporary diagnostic code (diag variable, console.log statements, enriched reason strings) added during debugging.
Before
validatePageContext(args) {
const host = normalizeText(globalThis.location?.hostname);
const port = normalizeText(globalThis.location?.port);
const href = normalizeText(globalThis.location?.href);
const title = normalizeText(globalThis.document?.title);
const expected = normalizeText(args.expected_domain);
const hasMac = !!globalThis.mac;
const diag = 'href=' + href + '|host=' + host + '|port=' + port + '|title=' + title + '|mac=' + hasMac;
console.log('[validatePageContext] ' + diag);
if (!host) {
return { ok: false, reason: 'page_context_unavailable:host_empty|' + diag };
}
if (host !== expected) {
return { ok: false, reason: 'page_context_mismatch:host=' + host + ',expected=' + expected + '|' + diag };
}
if (!hasMac) {
return { ok: false, reason: 'page_context_unavailable:mac_missing|' + diag };
}
return { ok: true };
},
After
validatePageContext(args) {
const host = normalizeText(globalThis.location?.hostname);
const expected = normalizeText(args.expected_domain);
if (!host) {
return { ok: false, reason: 'page_context_unavailable' };
}
if (host !== expected) {
return { ok: false, reason: 'page_context_mismatch' };
}
return { ok: true };
},
Files Changed
claw/claw/skills/skill_staging/skills/tq-lineloss-report/scripts/collect_lineloss.js—validatePageContextfunction only
No Recompilation Required
The JS file is read at runtime via fs::read_to_string. No Rust code changes.