js-eyes

Install, configure, verify, and troubleshoot JS Eyes browser automation for OpenClaw.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "js-eyes" with this command: npx skills add imjszhang/js-eyes

JS Eyes

Use this skill to turn a ClawHub-installed js-eyes bundle into a working OpenClaw browser automation stack.

Treat {baseDir} as the installed skill root. The plugin path that must be registered in OpenClaw is {baseDir}/openclaw-plugin, not {baseDir} itself.

Use This Skill When

  • The user wants to install or configure JS Eyes from a ClawHub skill bundle.
  • js_eyes_* tools are missing after installation.
  • The browser extension is installed but still shows Disconnected.
  • The user wants to verify the built-in server, plugin config, or extension connection.
  • The user wants to discover or install JS Eyes extension skills after the base stack is working.
  • The user wants to mount a custom / external extension skill (a directory outside the bundle that contains a skill.contract.js) into a running OpenClaw, or to verify that such a skill is actually loaded.
  • The user wants to author a new extension skill from scratch — in that case, point them at the starter template and authoring guide (see Authoring A New Extension Skill below) rather than writing files from nothing.

What Success Looks Like

A successful setup has all of the following:

  1. npm install has been run in {baseDir} with Node.js 22 or newer.
  2. OpenClaw loads {baseDir}/openclaw-plugin via plugins.load.paths.
  3. plugins.entries["js-eyes"].enabled is true.
  4. tools.alsoAllow (preferred) or tools.allow includes js-eyes, so the plugin's optional tools are actually exposed to the model.
  5. The user can run openclaw js-eyes status.
  6. The browser extension is connected to http://<serverHost>:<serverPort>, the popup Server Token field is populated (2.2.0+), and js_eyes_get_tabs returns real tabs.
  7. The bundled first-party extension skills under {baseDir}/skills are enabled by default in the JS Eyes host config, and the main plugin auto-loads enabled skills from {baseDir}/skills or the configured skillsDir (primary), plus any read-only directories listed in extraSkillDirs (extras). The user can later run js_eyes_discover_skills / js_eyes_install_skill to add more extension skills dynamically.
  8. js-eyes doctor reports an acceptable security posture for this skill's deployment (token present, allowAnonymous=false, allowRawEval=true in ~/.js-eyes/config/config.json, host bound to loopback, skill integrity OK). doctor will still label raw eval as insecure — that is expected when following this skill.

Deployment Modes

Treat {baseDir} as the bundle or repository root that contains openclaw-plugin/, skills/, and the package manifests.

There are two supported complete deployment modes:

  1. ClawHub / bundle deployment

    • {baseDir} is the installed JS Eyes bundle root.
    • Run npm install in {baseDir} so the plugin runtime can resolve its dependencies.
    • Register {baseDir}/openclaw-plugin in OpenClaw.
  2. Source-repo / development deployment

    • {baseDir} is the root of a local js-eyes git clone.
    • Run npm install in the repo root, not inside openclaw-plugin/.
    • Point OpenClaw plugins.load.paths at the repo-root openclaw-plugin directory.
    • If you are debugging the browser side, load the extension from extensions/chrome/ or extensions/firefox/manifest.json as appropriate.
    • Restart scope: only changes to files under openclaw-plugin/ itself (or any packages/* module the plugin imports directly) require restarting / refreshing OpenClaw so the plugin module is re-required. Edits to individual skill files (skills/<id>/skill.contract.js, an extraSkillDirs entry's contract, etc.) are picked up hot by the SkillRegistry + chokidar watcher — no restart needed.

For both deployment modes above, treat host-side raw eval as part of the default install: merge security.allowRawEval: true into ~/.js-eyes/config/config.json (Windows: %USERPROFILE%/.js-eyes/config/config.json) during deployment — not in openclaw.json. The js-eyes server reads this file; the browser extension syncs the value on WebSocket handshake (2.5.1+). Restart the server / OpenClaw after changing it so execute_script raw JavaScript is not blocked with RAW_EVAL_DISABLED.

Also for both modes, if the operator will use the extension popup Sync Token From Host / 从本机同步 (2.4.0+), register the Native Messaging host on that machine. Preferred (local launcher, no network): from the checked-out repo run bin/js-eyes-native-host-install.sh --browser all (macOS/Linux) or ./bin/js-eyes-native-host-install.ps1 -Browser all (Windows); both forward to node apps/cli/bin/js-eyes.js native-host install, which never touches the npm registry. Since 2.6.3 the launchers also run js-eyes server token init (idempotent) at the end, so the host has a token file to read on the very first popup sync attempt — without that step the host returns token-missing until the operator either runs js-eyes server token init manually or starts OpenClaw / the server (ensureToken() runs on server boot). Pass --skip-token-init (-SkipTokenInit on Windows) to opt out of the auto-init. Fallback: npx js-eyes native-host install --browser all — only recommended when js-eyes is globally installed and the operator trusts the npm registry at install time; this fallback does not seed the token, so pair it with npx js-eyes server token init explicitly. Confirm with node apps/cli/bin/js-eyes.js native-host status (manifest + launcher must exist; on Windows the .bat lives under %LOCALAPPDATA%\js-eyes\native-host\). Then restart the browser or reload the extension. Skipping this step leaves manual token paste as the only path and often surfaces native-messaging-disconnected in the popup. See docs/native-messaging.md.

Safe Default Mode (no raw eval)

This section is informational — the default Setup Workflow below still opts into allowRawEval=true for full compatibility with the 2.6.x SKILL contract. If an operator explicitly wants the host-hardened posture (ClawHub's security.allowRawEval=false default), use the guidance here; nothing outside this section changes.

  • What still works without allowRawEval: js_eyes_open_url, js_eyes_get_tabs, js_eyes_screenshot, js_eyes_xpath*, js_eyes_click, js_eyes_type, js_eyes_hover, js_eyes_scroll, js_eyes_press_key, js_eyes_execute_action (declarative action DSL), js_eyes_find_element, js_eyes_reload_skills, js_eyes_reload_security, plus every extension-skill tool that goes through execute_action. For the vast majority of browsing / form-filling / data-extraction flows this is sufficient.
  • What gets refused with RAW_EVAL_DISABLED: js_eyes_execute_script and js_eyes_execute_script_async — the raw-JS entry points. Sensitive tools that also happen to run raw JS (e.g. some inject_css variants when a skill passes inline scripts) will soft-fail the same way; the dispatcher prints reason: RAW_EVAL_DISABLED in the audit log.
  • doctor output differs: when allowRawEval=false, js-eyes doctor / js-eyes doctor --json reports no "expected insecure" footnote on that row — the default value is the safe value, so the tool treats it as a clean posture. Everything else (token presence, allowAnonymous=false, loopback bind, skill integrity, extraSkillDirs integrity if verifyExtraSkillDirs=true) is reported identically to the standard SKILL deployment.
  • How to opt in: omit the security.allowRawEval: true merge from step 5 of the Setup Workflow (or set it to false in an existing ~/.js-eyes/config/config.json), restart the js-eyes server / OpenClaw, and optionally flip security.verifyExtraSkillDirs=true to close the extraSkillDirs gap described in SECURITY_SCAN_NOTES.md.
  • Behaviour guarantee: if an operator follows the default SKILL workflow below without any of these tweaks, the runtime behaviour in 2.6.3 is identical to 2.6.1 — Safe Default Mode is purely additive guidance. (2.6.3 only changes the install-time UX around server.token seeding; it does not alter the policy / consent / egress runtime.)

Setup Workflow

When the user asks to install, configure, or repair JS Eyes, follow this exact order:

  1. Determine the operating system first and choose commands accordingly.

  2. Resolve the OpenClaw config path before editing anything.

  3. Verify prerequisites:

    • node -v must be >= 22
    • if the user expects OpenClaw plugin mode, openclaw --version should work
  4. From {baseDir}, run npm install if dependencies are missing or if the user just installed the bundle.

  5. Update the resolved openclaw.json:

    • ensure plugins.load.paths contains the absolute path to {baseDir}/openclaw-plugin
    • ensure plugins.entries["js-eyes"].enabled is true
    • ensure tools.alsoAllow contains js-eyes (preferred additive mode), or ensure tools.allow includes js-eyes
    • if needed, create plugins.entries["js-eyes"].config with:
      • serverHost: "localhost"
      • serverPort: 18080
      • autoStartServer: true
    • merge or create the JS Eyes host config at ~/.js-eyes/config/config.json (Windows: %USERPROFILE%/.js-eyes/config/config.json) with security.allowRawEval: true and default-enable the bundled first-party skills under skillsEnabled so deployment matches this skill (see Host security config below). Restart the js-eyes server after edits (or restart OpenClaw if it auto-starts the server).
  6. Restart or refresh OpenClaw so the plugin is reloaded.

  7. Verify with openclaw js-eyes status.

  8. Make sure ~/.js-eyes/runtime/server.token exists before anyone clicks the popup's Sync Token From Host / 从本机同步 button — otherwise the native host replies token-missing and the popup falls back to manual paste. Three ways to create it, any one is enough:

    • Run js-eyes server token init directly (idempotent — no-op if the file already exists).
    • Run the local launcher bin/js-eyes-native-host-install.sh --browser all (macOS/Linux) / ./bin/js-eyes-native-host-install.ps1 -Browser all (Windows) — since 2.6.3 it does the token init for you (skip with --skip-token-init).
    • Start OpenClaw (with autoStartServer: true) or js-eyes server start once — the server calls ensureToken() on boot.

    Then run the local launcher above (or the equivalent node apps/cli/bin/js-eyes.js native-host install --browser all) to register the Native Messaging manifest without hitting the npm registry. npx js-eyes native-host install remains as a fallback when the operator already has js-eyes globally installed; the npx path does not seed the token, so pair it with npx js-eyes server token init. If the operator can't or won't use Native Messaging at all, run js-eyes server token show --reveal and paste the value into the extension popup Server Token field under Advanced.

  9. If the server is healthy but no browser is connected, guide the user through browser extension installation, server-token entry, and connection.

  10. After the base setup works, pick the right path for extension skills:

    • Registry / first-party skills: prefer js_eyes_discover_skills + js_eyes_install_skill — 2.2.0+ writes a plan under runtime/pending-skills/<id>.json; finalize with js-eyes skills approve <id> then js-eyes skills enable <id>.
    • Custom / external skills (a directory the user already has on disk): prefer js-eyes skills link <abs-path> — it appends the path to extraSkillDirs, auto-enables it on first discovery, and the running plugin hot-loads it within ~300 ms via the config watcher. Reverse with js-eyes skills unlink <abs-path>. No OpenClaw restart is needed for either direction; see the Dynamic Extension Skills section for the full zero-restart contract.
  11. Run js-eyes doctor to confirm the deployment posture (token present, allowAnonymous=false, allowRawEval enableddoctor may still print it as insecure, which is expected here, loopback-bound, skill integrity OK) before handing off.

When asked to fix a broken setup, prefer repairing the existing config instead of repeating the whole installation.

Resolve The OpenClaw Config Path

Use this precedence order:

  1. OPENCLAW_CONFIG_PATH
  2. OPENCLAW_STATE_DIR/openclaw.json
  3. OPENCLAW_HOME/.openclaw/openclaw.json
  4. Default:
    • macOS / Linux: ~/.openclaw/openclaw.json
    • Windows: %USERPROFILE%/.openclaw/openclaw.json

Do not assume ~/.openclaw/openclaw.json if any of the environment variables above are set.

Recommended Config Shape

Update the resolved OpenClaw config so it contains the plugin path and enablement entry. Append to existing arrays and objects; do not remove unrelated plugins.

{
  "tools": {
    "alsoAllow": ["js-eyes"]
  },
  "plugins": {
    "load": {
      "paths": ["/absolute/path/to/js-eyes/openclaw-plugin"]
    },
    "entries": {
      "js-eyes": {
        "enabled": true,
        "config": {
          "serverHost": "localhost",
          "serverPort": 18080,
          "autoStartServer": true
        }
      }
    }
  }
}

Host security config (~/.js-eyes/config/config.json)

This file is not openclaw.json. For deployments following this skill, ensure at least:

{
  "skillsEnabled": {
    "js-bilibili-ops-skill": true,
    "js-browser-ops-skill": true,
    "js-github-ops-skill": true,
    "js-jike-ops-skill": true,
    "js-reddit-ops-skill": true,
    "js-wechat-ops-skill": true,
    "js-x-ops-skill": true,
    "js-xiaohongshu-ops-skill": true,
    "js-youtube-ops-skill": true,
    "js-zhihu-ops-skill": true
  },
  "security": {
    "allowRawEval": true
  }
}

Merge with existing keys (for example skillsDir, skillsEnabled). The bundled first-party skills above are part of the default install and should be enabled unless the operator explicitly opts out of a platform. Operators who do not need raw execute_script may set allowRawEval to false instead; optional plugin tools then still work, but raw JS payloads are rejected until enabled.

Important details:

  • The path must end in openclaw-plugin.
  • On Windows JSON paths, prefer forward slashes such as C:/Users/name/skills/js-eyes/openclaw-plugin.
  • If paths or entries already exist, merge rather than overwrite.
  • js-eyes registers its tools as optional plugin tools, so a complete deployment also needs tools.alsoAllow: ["js-eyes"] or an equivalent tools.allow entry.
  • skillsEnabled lives in the JS Eyes host config, not in openclaw.json. Enabling a bundled skill registers its extension tools through the main js-eyes plugin; disabling it leaves the files on disk but skips loading it.
  • To mount extension skills from outside {baseDir}/skills (e.g. a user's private ~/my-skills/js-foo-ops-skill), either add absolute paths to plugins.entries["js-eyes"].config.extraSkillDirs: [...] directly, or let the CLI handle it: js-eyes skills link <abs-path> does the dedup append and also triggers an in-memory reload on the running plugin. Entries are read-only to js-eyes (no install / approve / verify / integrity check).
  • Two new optional plugin config booleans control the hot-reload watchers (both default true): watchConfig (listen on ~/.js-eyes/config/config.json) and devWatchSkills (listen on discovered skill directories). Turn them off only if fs-watch load is a concern or in sandboxed environments.

Host security hot-reload (2.5.2+)

Some security.* fields can be swapped into the running JS Eyes server without restarting OpenClaw or the server. The server-core ships its own chokidar watcher on ~/.js-eyes/config/config.json (separate from the plugin's skill watcher) and a reloadSecurity() handle that the built-in js_eyes_reload_security tool calls on demand.

  • Hot-reloadable (swap takes effect on the next automation call, ~500 ms from fs write; also immediately via js_eyes_reload_security):
    • security.egressAllowlist
    • security.toolPolicies
    • security.sensitiveCookieDomains
    • security.allowedOrigins
    • security.enforcement
  • Not hot-reloadable — server restart required (changing these appears under ignored in the reload summary, with a one-line warning in the gateway log): serverHost, serverPort, allowAnonymous, allowRemoteBind, allowRawEval, requireLockfile, and anything outside security.* (token rotation, requestTimeout, etc.).
  • Caveat — session-level egress approvals reset: when the allowlist flips, each live automation connection rebuilds its PolicyContext, which means per-session js-eyes egress approve <id> grants are dropped. Agents re-issue the approval on the next pending-egress response; no action needed for standard allow <domain> edits because those are part of the static allowlist and get picked up automatically.
  • Operator triggers (any one is sufficient):
    1. Edit ~/.js-eyes/config/config.json and save — chokidar debounces 300 ms and fires reloadSecurity({ source: 'fs-watch' }).
    2. Agent call: js_eyes_reload_security built-in tool (returns { changed, applied, ignored, generation, egressAllowlist }).
    3. CLI preview: js-eyes security reload — read-only dry run that prints what would be applied (CLI does not own the server event loop, so trigger #1 or #2 is required for the actual swap).
  • Observability: the audit log (~/.js-eyes/logs/audit.log) gains three new events — config.hot-reload, config.hot-reload.error, automation.policy-rebuilt — and GET /api/browser/status now includes data.policy.generation / data.policy.egressAllowlist so operators can externally confirm the live generation.

Verification Workflow

After setup, verify the stack in this order:

  1. openclaw plugins inspect js-eyes
  2. openclaw js-eyes status
  3. Check whether the built-in server is reachable and reports uptime.
  4. Confirm that at least one browser extension client is connected.
  5. Ask the agent to use js_eyes_get_tabs or run openclaw js-eyes tabs.
  6. If the user wants extension skills, call js_eyes_discover_skills only after the base stack works.

Expected status checks:

  • openclaw plugins inspect js-eyes shows the plugin as loaded.
  • Server responds on http://localhost:18080 by default.
  • openclaw js-eyes status shows uptime and browser client counts.
  • js_eyes_get_tabs returns tabs instead of an empty browser list.

Verifying A Specific Extension Skill Is Loaded

When the user asks "did my skill get picked up?", check all four:

  1. ~/.js-eyes/config/config.json has skillsEnabled["<id>"]: true and (for externals) the skill's directory or a parent is listed in extraSkillDirs.
  2. Tail the gateway log and look for one of these lines from [js-eyes]:
    • Skill sources: primary=<dir> extras=<N> — confirms extras were seen at startup.
    • Loaded local skill "<id>" with K tool(s) — initial load at plugin boot.
    • Hot-loaded skill "<id>" with K tool(s) — loaded at runtime by the config / skill-dir watcher.
    • Discovered <N> skill(s): <K> active — gives a numeric sanity check.
  3. Ask the agent to call the built-in tool js_eyes_reload_skills; the returned summary must contain the id under added or reloaded, and failedDispatchers must be empty.
  4. Run js-eyes skills list from the host shell; each entry is annotated with Source: primary or Source: extra (<path>).

If steps 2-4 all fail for a freshly linked external skill, see the Custom Extension Skill Not Picked Up troubleshooting entry below.

Browser Extension Connection

If the plugin is enabled but no browser is connected:

  1. Install the JS Eyes browser extension separately from GitHub Releases or the website.
  2. Make sure the host has a token to share: confirm ~/.js-eyes/runtime/server.token exists (Windows: %USERPROFILE%/.js-eyes/runtime/server.token). If it doesn't, run js-eyes server token init, or start OpenClaw / js-eyes server start once so the server's ensureToken() creates it. Without this file the native host returns token-missing and the popup sync silently falls back to manual paste.
  3. (Preferred, 2.4.0+) Run the local launcher bin/js-eyes-native-host-install.sh --browser all (macOS/Linux) or ./bin/js-eyes-native-host-install.ps1 -Browser all (Windows) — equivalent to node apps/cli/bin/js-eyes.js native-host install --browser all; this never contacts the npm registry. Since 2.6.3 the launcher also runs js-eyes server token init for you (skip with --skip-token-init / -SkipTokenInit), so steps 2 and 3 collapse into one command in the common case. npx js-eyes native-host install --browser all remains as a fallback but does not seed the token — pair it with npx js-eyes server token init explicitly. Either path sets up Native Messaging so the extension auto-syncs server.token and the HTTP URL; restart the browser (or reload the extension) so it picks up the new manifest, then open the popup and click Sync Token From Host.
  4. Manual fallback: open the extension popup, expand Advanced, set the server address to http://<serverHost>:<serverPort>, paste the output of js-eyes server token show --reveal into the Server Token (2.2.0+) field, and click Connect.
  5. Re-run openclaw js-eyes status.

The browser extension is not bundled inside the main ClawHub skill. It must be installed separately. Connections without a matching server token are rejected unless the operator has set security.allowAnonymous=true.

Authoring A New Extension Skill

When the user wants to create a brand-new extension skill (not install / mount an existing one), do not scaffold files from scratch. Guide them through the canonical starter flow:

  1. Copy the reference starter examples/js-eyes-skills/js-hello-ops-skill/ to a directory of their choice (typically ~/my-skills/js-<domain>-ops-skill/). Point out that the starter already ships a working skill.contract.js, package.json, an async runtime.dispose() hook, a sample tool, and a SKILL.md frontmatter.
  2. Rename the three identifiers in lockstep: package.json.name, SKILL.md frontmatter name:, and skill.contract.jsid + name. Discovery resolves id via contract.id || pkg.name || path.basename(skillDir) (see normalizeSkillMetadata in packages/protocol/skills.js), so mismatches do not break load — but skillsEnabled.<id>, js-eyes skills link/enable/disable <id>, and log messages all key off whatever the contract finally resolves to. Keeping directory name / pkg name / contract id identical is the only reliable way to keep CLI and config references coherent.
  3. Read the authoring guides before wiring real logic — the canonical references are:
    • docs/dev/js-eyes-skills/authoring.zh.md — directory layout, discovery rules, quick-start.
    • docs/dev/js-eyes-skills/contract.zh.mdskill.contract.js surface (tools / runtime / runtime.dispose() lifecycle).
    • docs/dev/js-eyes-skills/deployment.zh.md — the zero-restart deployment flow the skill will end up in.
  4. Install local deps with npm install inside the new skill directory so ws / @js-eyes/client-sdk resolve at load time.
  5. Mount it zero-restart with js-eyes skills link <abs-path>; the running plugin auto-discovers it within ~300 ms. Iterate on skill.contract.js in place — saves are hot-reloaded by the SkillRegistry skill-dir watcher; no OpenClaw restart is needed until the skill introduces a brand-new tool name the host has never registered (rare, and the reload diff will say so via failedDispatchers).
  6. When ready to publish, decide between contributing it back to the first-party skills/ directory (registry / ClawHub distribution) or keeping it external via extraSkillDirs / link forever — both paths are supported and zero-restart after mount.

Do not invent a different layout. Extension skills are discovered only if they satisfy the exact contract the starter demonstrates.

Dynamic Extension Skills

The main js-eyes bundle ships first-party extension skills under {baseDir}/skills. A complete default install enables those bundled skills through ~/.js-eyes/config/config.jsonskillsEnabled, so they load through the main plugin without separate OpenClaw child-plugin entries.

Bundled first-party skills:

  • js-bilibili-ops-skill
  • js-browser-ops-skill
  • js-github-ops-skill
  • js-jike-ops-skill
  • js-reddit-ops-skill
  • js-wechat-ops-skill
  • js-x-ops-skill
  • js-xiaohongshu-ops-skill
  • js-youtube-ops-skill
  • js-zhihu-ops-skill

There are two complementary discovery surfaces — pick the right one when the user asks "what skills do I have?":

  • Local / installed view (what is actually mounted right now): js-eyes skills list from the host shell, or js_eyes_reload_skills which returns a live diff. Each entry carries a Source: primary vs Source: extra (<path>) annotation.
  • Registry / installable view (what could be installed from skills.json): js_eyes_discover_skills (agent tool). Installed rows are marked ✓ 已安装, installable rows ○ 未安装.

After the base plugin works:

  • Bundled first-party skills should already be enabled by the default host config above; use js-eyes skills list or js_eyes_reload_skills to verify they are loaded.
  • Use js_eyes_discover_skills to list registry skills when the user wants to install a skill that is not already present in {baseDir}/skills, or to compare installed versions with the registry.
  • Use js_eyes_install_skill to stage a plan — 2.2.0+ downloads the bundle, verifies its sha256 against skills.json, and writes runtime/pending-skills/<id>.json without installing.
  • Finalize the plan with js-eyes skills approve <id>, then enable it with js-eyes skills enable <id>.
  • Use js-eyes skills verify (or js-eyes doctor) to confirm .integrity.json still matches the on-disk skill files.
  • Since 2026-04-19 the main plugin hot-loads newly enabled or linked skills (and hot-disposes disabled ones) via SkillRegistry + a chokidar watcher on the host config — no OpenClaw restart needed. For external custom skills, prefer js-eyes skills link <abs-path> / js-eyes skills unlink <abs-path>; to force a refresh, call js-eyes skills reload or have the agent invoke the js_eyes_reload_skills tool (it returns an added / removed / reloaded / toggledOff / conflicts / failedDispatchers diff).
  • Recommend an OpenClaw restart only when js_eyes_reload_skills reports non-empty failedDispatchers — that means the host refused to register a brand-new tool name at runtime, which a restart will resolve. Everything else (install, enable, disable, replace, unlink) is zero-restart.

Skill Lifecycle Cheat Sheet

Use this table to pick the correct command for any user intent. All rows are zero-restart unless otherwise noted.

IntentRegistry skill (shipped in skills.json)External skill (arbitrary directory on disk)
Inspect what is installed locallyjs-eyes skills listsame (entries annotated Source: extra (<path>))
Browse what can be installedjs_eyes_discover_skillsN/A (externals are out-of-registry by definition)
Install / mountjs_eyes_install_skilljs-eyes skills approve <id>js-eyes skills enable <id>js-eyes skills link <abs-path> (auto-enables on first discovery)
Upgrade to the latest registry versionjs-eyes skills update <id> (preserves skillsEnabled, honors minParentVersion); js-eyes skills update --all for every primary-source skill; rerunning curl … | JS_EYES_SKILL=<id> bash works tooN/A — externals are managed in their source tree; pull/rebuild there
Temporarily stop without removingjs-eyes skills disable <id>runtime.dispose() fires, tools stop responding, files stay on diskjs-eyes skills disable <id> (works the same; the link path stays in extraSkillDirs)
Re-enablejs-eyes skills enable <id>js-eyes skills enable <id>
Replace / edit in placeEdit {baseDir}/skills/<id>/skill.contract.js and save — picked up by the skill-dir watcher, or call js-eyes skills reloadSame, against the external directory
Verify integrityjs-eyes skills verify [<id>] — checks .integrity.jsonN/A — integrity manifests only exist for registry installs
Remove / uninstallThe CLI intentionally has no uninstall subcommand. Soft-remove: js-eyes skills disable <id> (recommended). Hard-remove: after disable, delete {baseDir}/skills/<id>/ manually, then optionally clear the skillsEnabled.<id> key from ~/.js-eyes/config/config.json to keep it tidy.js-eyes skills unlink <abs-path> — removes the path from extraSkillDirs and hot-unloads every skill that was sourced from it
Force a re-scanjs-eyes skills reload or js_eyes_reload_skills (agent tool)Same

The agent SHOULD execute these commands directly when it has shell access. If it does not (read-only / "ask" mode), it SHOULD print the exact command for the user to run and then re-verify via js-eyes skills list or js_eyes_reload_skills afterwards.

Do not instruct the user to register child-skill plugin paths manually. Child skills no longer ship their own openclaw-plugin wrappers.

Prefer the built-in install flow over manual zip extraction when the user wants additional JS Eyes capabilities.

Troubleshooting

Cannot find module 'ws'

Run npm install in {baseDir}. The bundle expects dependencies to be installed from the skill root.

js_eyes_* tools do not appear

Check:

  1. plugins.load.paths points to {baseDir}/openclaw-plugin.
  2. plugins.entries["js-eyes"].enabled is true.
  3. tools.alsoAllow or tools.allow includes js-eyes.
  4. For items 1-3 (OpenClaw-level plugin config), OpenClaw has been restarted or refreshed since the config change — the plugin module itself is loaded once per OpenClaw process. Skill-level changes (skillsEnabled.<id>, extraSkillDirs, edits to a skill.contract.js) do not need a restart; they are applied by the SkillRegistry config / skill-dir watcher.
  5. If this is an extension skill, confirm it is not disabled in the JS Eyes host config (skillsEnabled.<id>: true) and that legacy OpenClaw child-plugin entries are removed.

Custom Extension Skill Not Picked Up

For a custom external skill mounted via js-eyes skills link <abs-path> where no tools appear and the log has no Loaded local skill "<id>" / Hot-loaded skill "<id>" line, check in order:

  1. Path actually landed in config: ~/.js-eyes/config/config.jsonextraSkillDirs contains the path; skillsEnabled["<id>"] is true.
  2. Skill is self-contained: cd <abs-path> && ls skill.contract.js package.json succeed, and npm install has been run inside that directory so transitive deps like ws / @js-eyes/client-sdk resolve.
  3. Contract actually loads: the gateway log contains no Failed to load skill "<id>" entry; if it does, the error message identifies the offending require or syntax issue. Fix in place and call js-eyes skills reload (or js_eyes_reload_skills) — no OpenClaw restart needed.
  4. Id conflict with primary: look for Skipping extra skill ... same id already loaded from primary. Primary wins by design; rename the custom skill's id in its package.json / skill.contract.js or move it into primary.
  5. Brand-new tool name refused by host: if js_eyes_reload_skills returns a non-empty failedDispatchers, OpenClaw refused to register a tool name post-boot. This is the one case that needs a one-shot OpenClaw restart; after the restart the skill loads normally.
  6. Plugin is running an outdated version (after a git pull / upgrade but before restart): the running plugin may predate SkillRegistry. In the gateway log look for [js-eyes] Watching host config: ... — if it is missing, restart OpenClaw once to pick up the new plugin code; subsequent skill changes stay zero-restart.

Browser Extension Stays Disconnected

Check:

  1. openclaw js-eyes status
  2. serverHost / serverPort in plugin config
  3. The extension popup server URL
  4. Whether autoStartServer is true
  5. (2.2.0+) The popup Server Token field matches js-eyes server token show --reveal. On 2.4.0+ installs, prefer re-running the popup's Sync Token From Host button (powered by the Native Messaging host — see docs/native-messaging.md). Tail logs/audit.log via js-eyes audit tailconn.reject with reason: token or reason: origin points to token/Origin mismatches.
  6. Sync Token From Host reports token-missing: the manifest is registered but ~/.js-eyes/runtime/server.token doesn't exist yet. Either run js-eyes server token init (idempotent), start OpenClaw / js-eyes server start once so ensureToken() creates it, or re-run the local launcher bin/js-eyes-native-host-install.sh / .ps1 (2.6.3+ seeds the token automatically). Tail ~/.js-eyes/logs/native-host.log to confirm — a get-config: token-missing line on every popup click is the smoking gun.
  7. Sync Token From Host does nothing / errors with Could not establish connection: the manifest isn't actually registered for this browser, or the browser was open before native-host install ran. Re-run node apps/cli/bin/js-eyes.js native-host status to confirm the manifest + launcher exist for the right browser, then fully restart the browser (not just reload the extension) so it re-scans the NativeMessagingHosts directory.

Sensitive Tool Calls Hang Without Output (2.2.0+)

execute_script*, get_cookies*, upload_file*, inject_css, and install_skill default to the confirm policy and wait for operator approval.

  1. js-eyes consent list to see pending requests.
  2. js-eyes consent approve <id> or js-eyes consent deny <id> to resolve.
  3. To disable the gate for a specific tool, set security.toolPolicies.<tool>=allow in config.json (logs an audit event).

Open URL or automation tools fail with egress / policy messages (2.3.0+)

If js_eyes_open_url or other browser tools return text mentioning pending-egress, 出站策略, or POLICY_SOFT_BLOCK, the server applied the policy engine before the extension ran the action (navigation may never reach the browser).

  1. Run js-eyes security show and inspect egressAllowlist and taskOrigin (hosts must be in static allowlist, session scope, or task-origin scope — see SECURITY.md Policy Engine).
  2. Run js-eyes egress list; use js-eyes egress approve <id> for a queued host or js-eyes egress allow <domain> to append to security.egressAllowlist.
  3. If you rely on active-tab scope, call js_eyes_get_tabs (or ensure the automation client has seeded tab state) so the active tab’s host is in scope before opening URLs on that host.

This is separate from consent (js-eyes consent …) and from extension disconnect issues.

Skill Fails to Load With Integrity Error (2.2.0+)

The main plugin refuses to register skills whose files no longer match .integrity.json.

  1. js-eyes skills verify <id> to see which files drifted.
  2. Re-install: js-eyes skills install <id>js-eyes skills approve <id>js-eyes skills enable <id>.
  3. If the drift was expected (manual patch), re-generate the manifest by reinstalling; do not edit .integrity.json by hand.

Custom OpenClaw Config Location

Always resolve OPENCLAW_CONFIG_PATH, OPENCLAW_STATE_DIR, and OPENCLAW_HOME before editing config or telling the user where to look.

Notes For The Agent

  • Prefer performing the setup steps for the user instead of only explaining them.
  • Modify existing OpenClaw config carefully; preserve unrelated plugin entries.
  • For plugin setup, edit JSON directly rather than asking the user to do it manually unless you are blocked by permissions.
  • Once setup is complete, switch from installation guidance to normal use of js_eyes_* tools.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

mano-cua

Computer use for GUI automation tasks via VLA models. Use when the user describes a task in natural language that requires visual screen interaction and no A...

Registry SourceRecently Updated
Automation

Huo15 Wecom Plugin

火一五·企业微信(WeCom)OpenClaw 插件 v2.8.25 — 默认走 Bot WebSocket(响应快、配置简单),自带加密媒体解密 / Agent 主动发消息 / 微信客服三通道接入 / 多账号切换。v2.8.25 重点:GUIDANCE 优先级翻转回 MEDIA: 直发——v2.8.22 当时担...

Registry SourceRecently Updated
Automation

Personal Memory Layer

Create and maintain a persistent personal memory layer for OpenClaw to build deep understanding of the human over time. The agent actively learns from intera...

Registry SourceRecently Updated
Automation

AgentOctopus

Use when you need to route a user query to the best specialized skill — AgentOctopus semantically matches queries against installed skills, executes the top...

Registry SourceRecently Updated
1450Profile unavailable