# Xcratch Extension Debug Auto

> Autonomously debug an Xcratch extension by loading it via the ?extension= query parameter into either the public xcratch.github.io editor or a local scratch-editor dev-server, with the extension served from a local HTTPS live server (https://0.0.0.0:5500/*). Use when: verifying an extension loads, checking console errors, inspecting extension blocks in the Scratch editor UI, or reproducing runtime failures with a specific extension URL — against the published editor (no local checkout needed) or against a local scratch-editor build on port 8601.

- Skill: `xcratch/xcratch-extension-debug-auto` (Agent Skill)
- Install (CLI): `npx skillmds@latest add xcratch/xcratch-extension-debug-auto`
- Raw SKILL.md: https://api.skillmd.com/api/skills/xcratch/xcratch-extension-debug-auto/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: xcratch (https://skillmd.com/u/xcratch)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/xcratch/xcratch-extension-debug-auto

---


# Debug Extension with Query Parameter

Autonomously load and inspect an Xcratch extension by appending it as the `?extension=`
query parameter of a Scratch editor. The extension's build output is served by a local HTTPS
live server; the editor fetches it from `https://0.0.0.0:5500`.

Two editor targets are supported — pick one:

| Target | Editor base URL | Use when |
|--------|-----------------|----------|
| **public** (default) | `https://xcratch.github.io/editor/` | Test the extension against the **published** editor. No local `scratch-editor` checkout needed. |
| **local** | `https://localhost:8601/` | Test against a **local (possibly modified) scratch-editor build** — e.g. developing scratch-editor itself, or the extension depends on unreleased editor changes. |

The procedure is identical for both targets except for the editor base URL (Step 2) and the
live-server root that determines the extension path (Step 1). A single launch config (Step 3)
handles the certificate and Local Network Access barriers for both.

## When to Use

- Verify that a built extension loads without errors
- Inspect browser console output after extension load
- Check that extension blocks appear in the Scratch editor toolbox
- Reproduce a runtime failure triggered by loading via URL

## Prerequisites

Common to both targets:

| Requirement | Detail |
|-------------|--------|
| Live server running | port 5500, serving the extension build over HTTPS |
| Extension built | `npm run build` or `npm run watch` ran in the extension repo |

Target-specific:

| Target | Extra requirement |
|--------|-------------------|
| **public** | mkcert certs in `<extension-repo>/.vscode/`. Start the live server via the `start live server` task in the extension's VS Code workspace (or the `debug extension on xcratch.github.io editor` launch config, which starts it via `preLaunchTask`). |
| **local** | A local `scratch-editor` checkout running scratch-gui on port 8601, plus mkcert certs in `scratch-editor/.vscode/`. Start both servers via the `start debug servers` task in the scratch-editor workspace. |

## Procedure

### Step 1 — Resolve the extension URL

The extension is served by the live server at `https://0.0.0.0:5500/<path>`, where `<path>` is
relative to **whatever directory the live server was told to serve**:

- **public target** — the live server runs in the extension repo and serves its root, so the path
  is the dist file relative to the repo root:

  ```
  https://0.0.0.0:5500/dist/xcratchExample.mjs
  ```

- **local target** — the scratch-editor `start live server` task serves `..` (the parent workspace
  that also contains your extension repos), so the path includes the extension repo directory:

  ```
  https://0.0.0.0:5500/xcx-my-extension/dist/myExtension.mjs
  ```

Confirm the dist file exists on disk before navigating.

### Step 2 — Compose the editor URL

Combine the target's editor base URL with the extension query parameter:

```
# public
https://xcratch.github.io/editor/?extension=https://0.0.0.0:5500/<path-to-dist-file>

# local
https://localhost:8601/?extension=https://0.0.0.0:5500/<path-to-dist-file>
```

### Step 3 — Configure playwright-cli to allow the local HTTPS extension

Loading the extension crosses **two** browser barriers that block the fetch and **cannot be
clicked away from playwright** (they are native browser UI, not in-page elements):

1. **Self-signed certificate** rejection for `https://0.0.0.0:5500` (and, for the local target, for
   `https://localhost:8601` as well — both use mkcert self-signed certs that playwright's bundled
   browser does not trust).
2. **Local Network Access (LNA) permission prompt** — only for the **public** target. Because
   `https://xcratch.github.io` is a public origin fetching from the `0.0.0.0:5500` loopback address,
   Chrome shows "xcratch.github.io is requesting permission to access other apps and services on
   this device". If not granted, the fetch fails with `Permission was denied for this request to
   access the 'loopback' address space` and the extension never loads. The **local** target does
   not trigger this (loopback→loopback), but disabling the check is harmless there too.

Both barriers are bypassed by launching the browser with a config file. Create
`playwright-cli.json` (auto-loaded from the current directory, or pass it via `--config`) — the
**same config works for both targets**:

```json
{
  "browser": {
    "launchOptions": {
      "args": [
        "--disable-features=LocalNetworkAccessChecks,BlockInsecurePrivateNetworkRequests,PrivateNetworkAccessSendPreflights,PrivateNetworkAccessRespectPreflightResults"
      ]
    },
    "contextOptions": {
      "ignoreHTTPSErrors": true
    }
  }
}
```

- `contextOptions.ignoreHTTPSErrors: true` → accept the self-signed certs (no "Advanced → Proceed").
- `launchOptions.args` `--disable-features=...` → disable the Local Network Access / Private Network
  Access prompt so a public→loopback fetch is allowed without the (unclickable) permission dialog.
  Multiple feature names are listed for cross-version safety; harmless extras are ignored.

### Step 4 — Open the browser and navigate

The config must be applied at **browser launch time**, so kill any stale session first, then `open`:

```bash
playwright-cli kill-all
playwright-cli open --headed --config ./playwright-cli.json
playwright-cli goto "<composed editor URL from Step 2>"
```

If `playwright-cli.json` sits in the current directory it is auto-loaded and `--config` can be
omitted. With this config the extension loads with **no manual clicks** — no cert warning, no LNA
prompt, no reload.

### Step 5 — Wait for the editor to load

Take a snapshot and confirm the Scratch editor UI is visible (stage, toolbox, sprite list):

```bash
playwright-cli snapshot
```

If the editor is still loading, wait and snapshot again.

### Step 6 — Check the browser console for errors

```bash
playwright-cli console
```

Look for:
- `Failed to load extension` messages
- Network errors (CORS, 404, certificate rejection)
- JavaScript exceptions thrown by the extension

### Step 7 — Verify extension blocks appear in the toolbox

Take a screenshot of the full editor UI:

```bash
playwright-cli screenshot
```

Inspect the snapshot for a custom category block corresponding to the extension. If not found, the extension likely failed to register — check the console output from Step 6.

### Step 8 — Collect network diagnostics (if needed)

```bash
playwright-cli network
```

Confirm the `.mjs` dist file was fetched with HTTP 200 from `https://0.0.0.0:5500`.

### Step 9 — Report findings

Summarize:
1. Which target was used (public / local) and whether the extension URL loaded successfully (HTTP status)
2. Any console errors and their messages
3. Whether the extension's blocks appeared in the toolbox (with screenshot)
4. Suggested fix if an error was identified

## Common Errors and Fixes

| Symptom | Likely Cause | Fix |
|---------|-------------|-----|
| Certificate warning on `0.0.0.0:5500` or `localhost:8601` | Live server / dev-server cert not trusted by playwright's browser | Launch with the Step 3 config (`contextOptions.ignoreHTTPSErrors: true`); run `playwright-cli kill-all` then re-`open` so it applies |
| Extension never loads; console shows `Permission was denied for this request to access the 'loopback' address space` (no fetch to `0.0.0.0:5500`) | Chrome **Local Network Access** prompt blocking public→loopback (public target only); the native dialog can't be clicked from playwright | Launch with the Step 3 config (`launchOptions.args` `--disable-features=...`); run `playwright-cli kill-all` then re-`open` so the flag applies |
| 404 on ext URL | Build output missing, or wrong live-server root for the target | Run `npm run build` in the extension repo; re-check the Step 1 path for the chosen target |
| CORS error | Live server not started with `--cors` | Check that the `start live server` task is running |
| Extension blocks not shown | Extension threw at registration | Check console for JS errors in extension source |

## Related Skills

- [xcratch-extension-debug](../xcratch-extension-debug/SKILL.md) — full VS Code launch config and source map setup
- [playwright-cli](../../../../../../../../.claude/skills/playwright-cli/SKILL.md) — browser automation commands reference

