Skip to content

Repository files navigation

hermes-js-plugin-builder

A Hermes agent plugin written in Python that gives the agent the ability to run JavaScript files through a controlled Node.js process interface — plus the original web-UI plugin toolchain (scaffold / validate / build / test / pack) and the sandboxed host loader those artifacts run under.

Three deliverables in one repository:

  1. Native Hermes plugin (plugin.yaml + hermes_js_plugin_builder/): seven tools registered via the official register(ctx) entry point — run_javascript, js_runtime_info, create_plugin, validate_plugin, build_plugin, test_plugin, pack_plugin.
  2. Web-UI plugin spec (docs/PLUGIN_SPEC.md + src/spec/): manifest format, activate/deactivate lifecycle, ctx host API, RPC wire shapes.
  3. Sandboxed host loader (src/host/): PluginHost runs each web-UI plugin in an iframe sandbox="allow-scripts" (Worker fallback) with a permission-gated postMessage RPC bridge.

Architecture

┌─────────────────────────────┐        ┌────────────────────────────────┐
│ Hermes agent (Python)       │        │ Web UI (browser)               │
│                             │        │                                │
│  plugin.yaml + register(ctx)│        │  PluginHost                    │
│    ├─ run_javascript ───────┼──node──┼─► executes .js/.mjs/.cjs file  │
│    ├─ js_runtime_info       │        │                                │
│    ├─ create_plugin         │        │   ├─ iframe sandbox            │
│    ├─ validate_plugin       │        │   │    └─ guest bootstrap      │
│    ├─ build_plugin ──esbuild┼────────┼──►│    └─ plugin bundle        │
│    ├─ test_plugin           │        │         ▲                      │
│    └─ pack_plugin ──► .hpkg │        │   └─ postMessage RPC bridge ───┘
└─────────────────────────────┘        └────────────────────────────────┘

The agent can execute arbitrary JavaScript files via run_javascript (subprocess, never a shell) and produce web-UI plugin packages (plugin.json + src/ + tests → bundled dist/ → .hpkg). A web UI embeds PluginHost and loads the bundle — plugin code only ever runs inside the sandbox and reaches host capabilities through declared permissions.

Requirements

  • Python ≥ 3.10 (the plugin itself; zero runtime dependencies)
  • Node.js ≥ 20 on PATH — required for run_javascript, build_plugin, test_plugin, and js_runtime_info. Override the binary with the node_binary plugin setting.

Install

As a directory plugin:

git clone https://github.com/CommunityPokeOrg/hermes-js-plugin-builder \
  ~/.hermes/plugins/hermes-js-plugin-builder
hermes plugins enable hermes-js-plugin-builder

Or as a pip package (registers the hermes_agent.plugins entry point):

pip install git+https://github.com/CommunityPokeOrg/hermes-js-plugin-builder
hermes plugins enable hermes-js-plugin-builder

See docs/HERMES_INTEGRATION.md for the full loading contract, settings, and references to the official Hermes plugin documentation.

Tool reference

Tool Input Result
run_javascript file (required .js/.mjs/.cjs), args?[], cwd?, timeout? (s, ≤600, default 30), env?{}, allow_outside_workdir? Exit code, stdout/stderr (64 KB caps), timeout/truncation flags, duration.
js_runtime_info — Node.js path + version; ok:false if Node is missing.
create_plugin name, id?, template (basic|panel), outputDir?, description?, permissions?, force? Scaffolded web-UI plugin dir; refuses non-empty dirs without force.
validate_plugin dir? Manifest schema check, entry existence, known permissions, forbidden-globals scan (eval, new Function → errors; document.write → warning).
build_plugin dir?, outDir?, minify? esbuild ESM bundle dist/<id>.js + resolved dist/plugin.json (copies verbatim when the entry has no relative imports).
test_plugin dir?, runner? (auto|vitest|node) Runs the plugin's tests; structured exit code, counts, output tail.
pack_plugin dir?, outDir? Deterministic <id>-<version>.hpkg ZIP (manifest + dist/); auto-builds if needed.

Every tool returns a JSON string of { ok: boolean, summary: string, details: object } and never raises on user errors.

Security model

run_javascript executes files through subprocess with an argument vector (shell=False), stdin closed, a new process group (start_new_session=True), and SIGKILL on the whole group at timeout. Additional guards:

  • The interpreter is never selected from tool input — node resolves from PATH or the operator-controlled node_binary plugin setting only.
  • The child environment is scrubbed to a minimal base (PATH, HOME, temp dirs, locale) plus explicit env entries; secrets and ambient variables are not forwarded.
  • Paths are confined to the working directory unless the caller (the agent, with user-facing approval) sets allow_outside_workdir.
  • Output and execution time are bounded (64 KB per stream, ≤600 s).

This is contained execution, not a security sandbox: the JavaScript file runs with the privileges of the Hermes process. Do not run untrusted code without an external sandbox (container, VM, seccomp profile).

Development

python -m venv .venv && source .venv/bin/activate
pip install -e '.[dev]'
pytest -q                     # Python tests (48)

npm ci                        # eslint for the JS library surface
npm run lint
npm test                      # node --test tests-js/ (38)

Docs

License

MIT — CommunityPokeOrg contributors.

About

Hermes agent plugin that lets Hermes scaffold, build, validate, and test JavaScript plugins for web UIs (manifest spec, sandboxed host loader, tooling, templates).

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages