Skip to content

Repository files navigation

copilot-js

Inspect and execute JavaScript in Microsoft Office Copilot WebViews. Attaches to a running Word process via Frida, discovers embedded WebView instances, and provides single-shot JS execution and an interactive REPL with live tab completion.

Setup

uv sync

Usage

# List all WebView instances in Microsoft Word
uv run python3 copilot_js.py list

# Execute JavaScript on the Copilot WebView
uv run python3 copilot_js.py exec --js "document.title"
uv run python3 copilot_js.py exec --js "JSON.stringify({host: Office.context.host})"

# Execute a script file
uv run python3 copilot_js.py exec --file scripts/probe-bridge.js

# Start an interactive REPL with live tab completion
uv run python3 copilot_js.py repl

# Target a specific process
uv run python3 copilot_js.py --pid 12345 list
uv run python3 copilot_js.py --name "Microsoft Word" repl

# Override JS execution timeout (default 5000ms)
uv run python3 copilot_js.py --timeout 10000 exec --js "document.title"

REPL Commands

Command Description
.help Show all commands and tab completion usage
.quit / .exit / .q Exit the REPL
.url Show the current page URL
.title Show the current page title
.dom [path] Save full DOM HTML to file (default: /tmp/copilot-dom.html)
.file <path.js> Execute a JavaScript file
.import <path.js> Alias for .file
.views Re-enumerate all WebViews
.clear Clear the completion cache

Tab Completion

On startup the REPL eagerly loads all enumerable objects from the WebView's global scope (walking the full prototype chain). Every global variable, DOM API, Office JS object, and built-in is immediately completable. The completion popup shows the typeof each name.

  • doc<TAB>document (object)
  • document.get<TAB>getElementById (function), getElementsByClassName (function), ...
  • Off<TAB>Office (object), OfflineAudioContext (function), ...
  • After var myObj = {alpha: 1}, typing myObj.<TAB> shows alpha (number)

Completions are fetched by evaluating Object.getOwnPropertyNames() in the running process. The cache is invalidated after every user eval so newly created variables are immediately completable. Property access (e.g. document.<TAB>) walks the full prototype chain (HTMLDocument → Document → Node → EventTarget → Object).

Architecture

copilot_js.py (Python CLI)
    │
    ├── frida.attach(pid / name)
    │
    └── session.create_script(agent.js)
            │
            └── agent.js (injected into Word)
                    │
                    ├── objc_msgSend → NSApp.windows → view hierarchy walk
                    │   └── Finds WKWebView / AgaveView instances
                    │
                    └── evaluateJavaScript:completionHandler:
                        └── Manual ObjC block construction
                        └── Results via Frida RPC

The agent uses Frida's NativeFunction API to call objc_msgSend directly — the Copilot WebView (AgaveView, a WKWebView subclass) is discovered by walking the NSApp window hierarchy via ObjC runtime calls. JavaScript is executed via evaluateJavaScript:completionHandler: with a manually constructed ObjC block for the completion handler.

Scripts

See scripts/README.md for documentation on all available probe scripts, their output, and security implications.

Requirements

  • macOS (arm64 or x86_64) with Frida 17.x
  • Python 3.10+
  • uv for dependency management
  • Microsoft Word running with Copilot panel open
  • SIP disabled or appropriate debugging entitlements for process attachment

Project Structure

copilot-js/
├── copilot_js.py          # Python CLI (list, exec, repl)
├── agent.js               # Frida agent injected into Word
├── pyproject.toml          # Python dependencies (frida, prompt-toolkit)
├── uv.lock                 # Locked dependency versions
├── scripts/                # 17 JavaScript probe scripts
│   ├── README.md           # Script documentation with output and implications
│   ├── probe-bridge.js     # WebKit message handlers + Office JS API
│   ├── probe-dom.js        # DOM element counts
│   ├── probe-office-api.js # Office context properties
│   ├── probe-storage.js    # Storage sizes
│   ├── probe-message-handlers.js  # Deep handler enumeration
│   ├── enumerate-msal-tokens.js   # OAuth token scope enumeration
│   ├── extract-responses.js       # data-testid values
│   ├── extract-copilot-response.js # Latest AI response text
│   ├── extract-document-content.js # Full document text via Word JS API
│   ├── capture-injection-results.js # Injection marker detection
│   ├── write-document-test.js      # Document write test
│   └── ...                 # Additional probes
├── test-docs/              # Test Word documents for injection scenarios
├── CLAUDE.md               # Development guide
└── SPECIFICATION.md        # Formal specification

Test Documents

The test-docs/ directory contains Word documents designed for testing Copilot injection scenarios.

About

Inspect and execute JavaScript in remote WebViews (Office Copilot on macOS)

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages