Skip to content

fix(extension): recover blank side panel + contrast hardening (v1.0.7)#11

Open
arnaudassoumani-collab wants to merge 3 commits intoOpenBrowserAI:mainfrom
arnaudassoumani-collab:soca/v1.0.7-panel-recovery
Open

fix(extension): recover blank side panel + contrast hardening (v1.0.7)#11
arnaudassoumani-collab wants to merge 3 commits intoOpenBrowserAI:mainfrom
arnaudassoumani-collab:soca/v1.0.7-panel-recovery

Conversation

@arnaudassoumani-collab
Copy link

Summary

This PR fixes a production usability regression where the OpenBrowser side panel could appear blank/non-usable, and hardens toolbar click behavior.

What changed

  • Added SidebarErrorBoundary to prevent full blank panel on runtime render errors.
  • Added in-panel recovery actions:
    • Reload panel
    • Reset local panel state + reload
  • Hardened sidebar keepalive startup to avoid failing hard when chrome.runtime.connect is unavailable/transient.
  • Hardened theme contrast fallback parsing:
    • Supports 8-digit hex colors
    • Adds computed-style parsing fallback for unusual theme color formats
    • Enforces readable text fallback by color scheme
    • Sets explicit --chrome-bg-secondary
  • Manifest cleanup:
    • Remove side_panel.openPanelOnActionClick (to reduce manifest warnings)
    • Keep toolbar metadata under action.default_title
  • Version bump to 1.0.7.

Why

Users reported the panel opening but showing no usable controls/content. This change ensures the UI fails safe and remains recoverable with explicit user actions.

Validation

  • pnpm -C chromium-extension build
  • pnpm -C chromium-extension check:drift

Both pass locally (existing webpack warnings unrelated to this patch remain).

arnaud assoumani and others added 3 commits January 27, 2026 12:34
- Add 5 YAML workflow templates (preflight, vps-capsule, clawdbot-deploy, openbrowser-setup, evidence-bundle)
- Add 5 vault templates for SOCA_HOLOBIONT_OS Obsidian vault
- Add 3 agent prompts (workflow-executor, openbrowser-observer, vps-operator)
- Add workflow documentation README

Part of Constitution Rule 66: OpenBrowser Automation Workflows
@arnaudassoumani-collab
Copy link
Author

Tracking issues:\n- #12 (user-facing blank panel bug)\n- #13 (automated side-panel smoke-test gap)

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a fix for a production usability regression where the OpenBrowser side panel could appear blank, along with significant architectural changes to move towards a fail-closed, bridge-based architecture with offline-first operation.

Changes:

  • Added error boundary and recovery UI for blank panel issues
  • Implemented fail-closed write gates for browser automation (pageSigHash/pinHash verification)
  • Migrated from models.dev API to local bridge-based model management with SOCA lane support
  • Hardened theme contrast calculations with 8-digit hex support and computed style fallback
  • Added service worker keepalive mechanism
  • Changed default LLM provider from Anthropic to local Ollama
  • Added extensive workflow templates for VPS setup and app builder automation
  • Added declarativeNetRequest permissions and host_permissions for specific domains

Reviewed changes

Copilot reviewed 64 out of 65 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
chromium-extension/src/sidebar/components/SidebarErrorBoundary.tsx New error boundary component with panel recovery actions
chromium-extension/src/sidebar/providers/ThemeProvider.tsx Enhanced color parsing with 8-digit hex, computed styles, and WCAG contrast checking
chromium-extension/src/sidebar/index.tsx Added service worker keepalive, error boundary integration, storage change monitoring
packages/extension/src/browser.ts Implemented fail-closed write gates with document/page/pin hash verification
packages/core/src/agent/browser/build-dom-tree.ts Added guard mode, pin hash generation, page signature hashing
chromium-extension/public/manifest.json Version bump, removed openPanelOnActionClick, added host_permissions for third-party domains
chromium-extension/src/background/bridge-client.ts New bridge client for token-gated local bridge communication
chromium-extension/src/llm/llm.ts Replaced models.dev with local bridge-based model discovery and SOCA lane support
chromium-extension/src/options/index.tsx Changed default provider to Ollama, added SOCA lane selector, bridge token management
workflows/templates/*.yaml Added extensive VPS setup and workflow execution templates
bridge/*.py New PromptBuddy bridge service with offline-only enhancement
app_builder/*.json New app builder automation framework with action specs

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 15 to 17
"side_panel": {
"default_path": "sidebar.html",
"openPanelOnActionClick": true
"default_path": "sidebar.html"
},
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of openPanelOnActionClick from side_panel is good for avoiding manifest warnings, but this changes the UX - users must now manually open the side panel instead of it opening automatically on toolbar click. This behavioral change should be documented and potentially communicated to users.

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +45
"https://aistudio.google.com/*",
"https://accounts.google.com/*",
"https://lovable.dev/*",
"https://antigravity.google/*",
"https://github.com/*"
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding hard-coded host_permissions for specific third-party domains (aistudio.google.com, lovable.dev, antigravity.google, github.com) significantly broadens the extension's access scope. This should be carefully reviewed from a security and privacy perspective. Consider whether these permissions are necessary for all users or if they should be optional/conditional.

Suggested change
"https://aistudio.google.com/*",
"https://accounts.google.com/*",
"https://lovable.dev/*",
"https://antigravity.google/*",
"https://github.com/*"
"https://accounts.google.com/*"

Copilot uses AI. Check for mistakes.
import { ThemeProvider } from "./providers/ThemeProvider";
import { message as AntdMessage } from "antd";
import React, { useState, useRef, useEffect, useCallback } from "react";
import { clampText } from "./utils/sanitize";
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code imports clampText from "./utils/sanitize" but this file doesn't exist in the diff. This will cause a build error. Either the file needs to be added to the PR or the import needs to be corrected/removed.

Copilot uses AI. Check for mistakes.
Comment on lines 43 to 51
const [config, setConfig] = useState({
llm: "anthropic",
llm: "ollama",
apiKey: "",
modelName: "claude-sonnet-4-5-20250929",
npm: "@ai-sdk/anthropic",
modelName: "qwen3-vl:2b",
npm: "@ai-sdk/openai-compatible",
options: {
baseURL: "https://api.anthropic.com/v1"
baseURL: "http://127.0.0.1:11434/v1"
}
});
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default LLM provider was changed from "anthropic" (claude-sonnet-4-5) to "ollama" (qwen3-vl:2b). This is a significant behavior change that affects all new installations and could confuse existing users. The change should be clearly documented in release notes, and existing user configurations should be preserved during updates.

Copilot uses AI. Check for mistakes.
SOCA_BRIDGE_TOKEN_SESSION_KEY
]);
const token = String(v[SOCA_BRIDGE_TOKEN_SESSION_KEY] || "").trim();
if (!token) throw new Error("bridge_token_missing");
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded token "soca" in the bridge client is a security concern. In production environments, this token should be configurable via environment variables or a more secure configuration mechanism rather than hardcoded in source code.

Copilot uses AI. Check for mistakes.
Comment on lines +28 to +36
// Keep MV3 service worker alive while the sidebar is open (active automation).
useEffect(() => {
let port: chrome.runtime.Port | null = null;
try {
port = chrome.runtime.connect({ name: "SOCA_KEEPALIVE" });
} catch (error) {
console.warn("sidebar_keepalive_connect_failed", error);
return;
}
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The keepalive connection failure is silently swallowed with only a console.warn. If the service worker keepalive is critical for preventing the blank panel issue, this might need more robust error handling or a UI indicator when the keepalive fails to connect.

Copilot uses AI. Check for mistakes.
Comment on lines +42 to +57
if (!rgbMatch && typeof document !== "undefined") {
const probe = document.createElement("span");
probe.style.color = input;
document.body.appendChild(probe);
const computed = getComputedStyle(probe).color;
document.body.removeChild(probe);
const normalized = computed.match(
/^rgba?\(\s*(\d{1,3})\s*[, ]\s*(\d{1,3})\s*[, ]\s*(\d{1,3})(?:\s*[,/]\s*[\d.]+)?\s*\)$/i
);
if (normalized) {
const [r, g, b] = normalized.slice(1, 4).map((v) => Number(v));
if (![r, g, b].some((v) => Number.isNaN(v) || v < 0 || v > 255)) {
return { r, g, b };
}
}
return null;
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parseColor function temporarily mutates the DOM by appending/removing elements for computed style parsing. While this works, it could theoretically cause issues if called frequently or during critical render phases. Consider caching parsed colors or using a more isolated approach.

Copilot uses AI. Check for mistakes.
areaName: string
) => {
if (areaName === "sync" && changes["llmConfig"]) {
if (areaName === "local" && changes["llmConfig"]) {
Copy link

Copilot AI Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The storage area was changed from 'sync' to 'local' for llmConfig monitoring. This is a breaking change that could affect users with synced settings across devices. Consider adding migration logic or documenting this behavior change in the PR description.

Copilot uses AI. Check for mistakes.
@i-m-sid
Copy link
Contributor

i-m-sid commented Feb 28, 2026

too many unnecessary changes and bloat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants