PangoLint v0.7.29

PangoLint User Manual

Developer tooling for Pangolin BEYOND PangoScript: a VS Code extension and a companion pangolint-mcp server for AI coding agents.

PangoLint icon
Document
User manual, end-user reference
Date
2026-05-22
Independent software PangoLint is independent software and is not affiliated with, endorsed by, or sponsored by Pangolin Laser Systems, Inc. "Pangolin," "BEYOND," and "PangoScript" are referenced for descriptive interoperability; all trademarks remain the property of their respective owners.
Reference data PangoLint ships a curated knowledge base of command names, signatures, and object-tree property paths. It does not redistribute Pangolin manuals, help files, BEYOND command exports, OSC HTML, or any other verbatim Pangolin reference material.

This manual is the end-user reference for everything the project ships: the VS Code extension and the companion pangolint-mcp server for AI coding agents.

Quick orientation

If you write .BeyondCode files in VS Code, install the extension. If you also work with an AI coding agent (Claude, Codex, Cursor, etc.) and want it to verify command names against PangoLint's curated catalog and lint generated PangoScript, also install the MCP server. Both ship from the same repo and read the same curated knowledge base.


§ 01Quick start

VS Code with the PangoLint extension active: a syntax-highlighted .BeyondCode file in the editor on the left, the PangoLint sidebar on the right showing the Commands, Objects, Diagnostics, and BEYOND Watcher panels.
Fig 01The full layout: editor with syntax highlighting and color decorators, plus the PangoLint sidebar's Commands, Objects, Diagnostics, and BEYOND Watcher panels.
  1. Install the VS Code extension from the Marketplace:
    code --install-extension jd3lasersllc.pangolint
  2. Open any .BeyondCode file. Syntax highlighting, diagnostics, completions, and the activity-bar sidebar light up automatically.
  3. Open the PangoLint view container (laser-warning icon in the activity bar) to browse commands and objects.
  4. To enable BEYOND runtime features, configure pangolint.beyond.talkTcpHost to point at your dev BEYOND machine (and pangolint.beyond.talkTcpPort if needed), then run PangoLint: Test BEYOND Connection from the Command Palette.

That's it for the extension. For the MCP server, see The PangoLint MCP server below.


§ 02The editor

Syntax & semantic highlighting

PangoLint registers .BeyondCode as the pangoscript language. You get:

  • TextMate grammar with scopes for labels, commands, expression functions, variables, object paths, operators, OSC addresses, and string/comment forms.
  • Semantic tokens so commands that PangoLint actually knows about render differently from unknown identifiers - useful for spotting typos at a glance.
  • A document outline (Outline view, breadcrumbs) generated from script labels.
A PangoScript file showing semantic-token highlighting: known commands like ColorChannel, COLORPICKER and SATSLIDER render in their canonical colors; labels, keywords, numbers, and comments are each distinctly styled.
Fig 02.1Semantic highlighting on a real .BeyondCode file. Known commands and object roots take catalog-aware colors; unknown identifiers stay neutral so typos are easy to spot.

Diagnostics

PangoLint ships 22 diagnostic codes. The full reference with cause and how-to-fix lives in docs/references/diagnostics/README.md; this is the summary.

CodeSeverityWhat it catches
analysis-limitedwarningPangoLint skipped a full-file pass or unusually long line because the input exceeds bounded-analysis limits. Runtime sends are blocked until the file can be fully checked.
unclosed-stringerrorA line opens " with no closing quote.
unbalanced-parentheseswarningUnequal ( / ), or )( order.
unknown-commandwarningIdentifier isn't in the curated catalog and isn't a recognized control-flow keyword.
wrong-arg-countwarningCurated command called with the wrong number of arguments. Includes the zero-arity case (EnableLaserOutput 1).
missing-labelwarningGoto X jumps to a label that doesn't exist in the file.
unsupported-quoted-goto-labelwarningGoto "X" - quoted labels aren't recognized by BEYOND.
uninitialized-variablehintvar is read before any assignment.
unsupported-loophintWhile / Do / Repeat / Until / Loop - points to the label + If <cond> Goto <label> pattern.
unsupported-for-range-syntaxhintfor x = a to b - BEYOND only supports for x = a, b.
unsupported-logical-operatorhint&& / || - BEYOND uses and / or only.
unsupported-bang-not-equal-operatorhint!= - BEYOND uses <>.
unsupported-property-index-accesswarningDirect reads of Zone.0.Points[0].X - BEYOND reports invalid array index.
unsupported-deltavalue-assignmentwarningDeltaValue = … outside its allowed editor context.
unsupported-deltavalue-command-argumentwarningDeltaValue passed as a command argument outside trigger handlers.
deltavalue-midi-slot-contexthintDeltaValue MIDI slot context misalignment.
unsupported-exit-semicolonhintexit; - BEYOND wants bare exit.
missing-terminal-exithintScript doesn't end with exit.
extvalue-define-midi-trigger-defaulthintExtValue editor default in a DefineMidiTrigger body.
unused-variablehintvar x declared but never referenced.
unused-labelhintLabel declared but never Goto'd.
property-typohintObject.PropertyName doesn't match a known property; suggests the closest valid name.

PangoLint biases permissive - most rules are warning or hint level. Real errors are reserved for unambiguous syntax failures (unclosed-string, unbalanced parens). Click any diagnostic in the Diagnostics sidebar panel and use the Why? action to open the bundled reference scrolled to that rule's section.

Run PangoLint: Validate Current Script from the Command Palette to refresh diagnostics for the active .BeyondCode buffer and write a portable report to the PangoLint: Validation Output channel. The report lists severity, rule code, line / column, and the same human-readable explanation shown by the editor hover. The completion toast offers shortcuts to the Diagnostics sidebar, the Output channel, and the Problems panel.

A test file demonstrating an unsupported While/Loop construct, with the offending lines flagged in the editor and a corresponding red marker in the minimap.
Fig 02.2aThe unsupported-loop diagnostic on a candidate While/Loop file. The minimap on the right surfaces a red marker for at-a-glance navigation; the matching entry appears in the sidebar's Diagnostics panel (Fig 03.3b).
The PangoLint: Validation output channel showing four diagnostic entries: WARNING unbalanced-parentheses [Ln 21, Col 1] - Parentheses are not balanced on this line; WARNING missing-label [Ln 28, Col 1] - Goto target 'DefinitelyNotALabel' does not match a label in this file; WARNING uninitialized-variable [Ln 32, Col 22] - Variable 'zoneName' is read before a local assignment in this file; HINT missing-terminal-exit [Ln 42, Col 1] - BEYOND accepts this shape, but `exit` is recommended to prevent fall-through between script sections. The Problems tab shows a badge of 5.
Fig 02.2bThe PangoLint: Validation output channel after Validate Current Script. Each entry carries severity, rule code, source location, and the same explanation the editor shows on hover, so the channel doubles as a portable transcript of the file's diagnostics.

Completions, hover, signature help

  • Command completions - type a command name and PangoLint suggests matches from the bundled catalog (529 command entries). Each suggestion carries a description, syntax form, and safety tier.
  • Property completions - type Master. (or Zone.0., FX.0., etc.) and PangoLint suggests properties from the schemas.
  • Goto label completions - after Goto or If ... Goto , PangoLint suggests labels declared in the current file. Declared variable goto targets keep their variable-reference behavior.
  • Hover tooltips - hover any command name for a Markdown card with the syntax form, parameters, safety tier, and a primary example. Hover an object path for property listings, with segment-aware detail (root, array index/button name, property segment).
  • Signature help - start typing a command's arguments to get an inline signature panel with parameter names, types, and ranges.
A completion popup over a partial 'chan' identifier: ChannelOut, SetChannelToChannelRatio, WaitForChannel, SetDmxToChannelRatio, SetFFTToChannelRatio, MeshPointChan, SetEffectChannelAction, WaitForPageChange, SetDmxEditorChannel - the first entry shows ChannelOut 1, 1000 in the inline detail panel.
Fig 02.3aCommand completions ranked from the curated catalog. The right-hand detail strip shows the canonical signature for the highlighted entry.
A Markdown hover card over the COLORPICKER root: 'folder-scoped universe panel  COLORPICKER - 49 discovered controls. Inherits the canonical UniversePanel schema (17 properties). Auto-discovered from 39 sibling .BeyondCode files; classify it explicitly with the lightbulb code action to lock the type in, or run Validate objects against BEYOND to confirm against a live host.'
Fig 02.3bHover tooltip on a folder-scoped universe panel. PangoLint reports both the inherited schema and how it inferred the type, with a pointer to the lightbulb code action that locks classification in.
A property path being typed: color.channel. - with the rest of the path '1.color = 255' shown as italic ghost text inline.
Fig 02.3cInline ghost-text suggestions for property paths. Press Tab to accept.
A line reading OscOutTTS ("/colorpicker/bluebutton2/click", "i", 1) - the trailing 1 argument is shown in italic, as a parameter placeholder hint, with a yellow squiggle on the OscOutTTS call signaling a wrong-arg-count diagnostic.
Fig 02.3dA function template inserted from the completion list. PangoLint expands the call with parameter placeholders (italic) so you can Tab through them; if the count is wrong for the call site, the diagnostic surfaces immediately.

Quick fixes

Click the lightbulb (or Cmd+. / Ctrl+.) on:

  • An unknown-command warning - accept a Levenshtein-ranked replacement.
  • A property-typo hint - accept the closest valid property name.
  • An unknown property-path root - register it as a user universe (inherits UniversePanel), a zone alias (inherits Zone), or a master alias (inherits Master). See User objects.
A line flagged with a yellow gutter dot. The Quick Fix popover offers two actions: 'Fix' and 'Explain'.
Fig 02.4Quick fixes on a flagged line. Cmd+. opens the menu; pick Fix to apply the suggested replacement, or Explain to surface the rule's reference entry.

Formatting

Run Format Document (Shift+Alt+F) or wire format-on-save:

// .vscode/settings.json
{
  "[pangoscript]": {
    "editor.defaultFormatter": "jd3lasersllc.pangolint",
    "editor.formatOnSave": true
  }
}

The formatter is intentionally conservative:

  • Preserves command order, strings, comments, labels, and unknown syntax verbatim.
  • Normalizes whitespace and indentation only where it can do so safely.
  • Will not collapse, reorder, or transform any line it doesn't fully recognize.

Snippets

Type the prefix and press Tab. All 10 snippets:

PrefixInserts
loopLabel + if (cond) goto label loop scaffold with exit.
forCounted i = 1; loop; i = i + 1; if (i <= 10) goto loop pattern.
ifguardif (cond) goto afterBlock; … afterBlock: skip pattern.
oscreadOscOutTTS readback skeleton with a typed return.
oscfeedbackRegisterOscFeedback with a run-prefixed cleanup.
scriptBeginScript / EndScript wrapper.
onclickOnClick: handler with an init guard.
varvar name; name = 0 declaration + initial assignment.
selectzoneSelectZone + ControlZone destination prefix.
zonewriteDirect Zone.0.Brightness = 50 property assignment (recommended over the destination-prefix form).
The completion list after typing 'loop' on a fresh line. The first entry, 'loop', carries a snippet icon (a small square) and the inline description 'Label and goto loop'. Below it, three command suggestions - LoadWorkspace, PlayersSetLoop, ProTrackSetLoop - show with the standard command (cube) icon.
Fig 02.6The loop snippet ranks above unrelated command matches. The square icon distinguishes snippets from catalog commands; press Tab to expand and tab through the placeholders.

Color decorators

Inline color swatches appear next to the value for:

  • ColorBGR <hex> literals
  • ColorRGB <hex> literals
  • <Object>.Color = <int> literal assignments

Click the swatch to open VS Code's color picker. The picker round-trips the change back into the source format (BGR stays BGR, RGB stays RGB, integer literals stay integer literals).

A ColorChannel.1.Color = 16711680 line with its inline blue swatch, and VS Code's color picker open above it. The picker shows the hex value 16711680, a square saturation/value field, and a vertical hue slider on the right.
Fig 02.7Click a swatch to open VS Code's color picker. PangoLint round-trips the change back into the source format - BGR stays BGR, RGB stays RGB, integer literals stay integer literals.
  • Go to Definition (F12) on Goto MyLabel jumps to MyLabel:.
  • Cursor on a label (declaration or any Goto reference) highlights every other occurrence in the file.
  • Optional References code lens above each label declaration - enable with pangolint.codeLens.labelReferences: true.
A PangoScript file with the cursor on a 'goto Blue2Off' on line 9. The 'Blue2Off' identifier is highlighted there and again at its declaration 'Blue2Off:' near line 35.
Fig 02.8Label-aware highlighting. With the cursor on a Goto reference, every other occurrence of the same label - including its declaration - is highlighted in the editor.

§ 03The sidebar

Click the laser-warning icon in the activity bar. The PangoLint view container has four stacked panels: Commands, Objects, Diagnostics, and the BEYOND Watcher.

Commands view

A webview browser over 521 browsable PangoScript commands plus 7 expression functions. Prototype, internal, and do-not-use commands remain known for diagnostics and direct lookup, but stay out of the browsable list.

  • Full-text search across canonical name, aliases, description, and BEYOND category. Type into the search box at the top.
  • Category groups partition the catalog into 35 BEYOND-style categories (General, Cue Clicking, Main Toolbar, Transition, Live Control, FX, and more). Click a category header to collapse / expand its commands; Expand All opens every group at once.
  • Click any command row to expand the inline detail panel - signature, BEYOND category, primary example.
  • Detail-panel actions:
    • Insert at cursor - drops the example into the active editor.
    • Copy signature - copies the syntax form to clipboard.
    • View in full reference - opens the bundled offline PangoScript reference site in your default browser, deep-linked to that command.
  • Keyboard insert. With a row focused, press Cmd+Enter (macOS) / Ctrl+Enter (Windows / Linux) to insert the example at the cursor - no mouse needed.
  • Cross-link from the editor. In any .BeyondCode file, hover a command name and click View in Commands sidebar, or right-click → View in Commands sidebar. The Commands view scrolls to that command and expands its detail panel.
The Commands panel with the General category expanded. Visible entries include AddSms, BlackOut, CaptureToClipboard, DisableLaserOutput, DisplayPopup, DisplayPopupOnTop, DisplayPreview, EnableLaserOutput, HtmlBody, HtmlClearBody, HtmlClearHead, HtmlHead - each with a one-line description and a 'General' chip on the right. Footer reads '521 commands + 7 functions'.
Fig 03.1aCommands panel with a category expanded. Each row shows the canonical name, a one-line description, and the BEYOND category chip.
A command detail panel for MasterEffectMetroShift. The card shows a paragraph description, two SIGNATURE blocks listing the available forms (MasterEffectMetroShift 0; MasterEffectMetroShift <beats>), parameter rows with name/type/required/range/description columns, MASTER / FX / TIMING tags, and 'Insert at cursor' / 'Copy signature' action buttons.
Fig 03.1bClick any row to drill into its detail panel. Both signature forms are shown with parameter tables; Insert at cursor drops the canonical example into the active editor.

Objects view

A webview browser over BEYOND's object surface, organized into three sections:

  1. FX Effects - every visualizer FX category and effect.
  2. Cue Types - every cue-type code with its description.
  3. Objects - Master, Zone, UniversePanel, ColorChannel, DmxOutput, Projector, ProTrack, QShift, and the rest of the bundled schemas with their property listings.

Search filters across all three sections in one pass. Right-click any property path:

  • If a setter command is mapped, Insert drops it at the cursor (e.g. right-click Master.BPM → inserts SetBpm).
  • View in Commands sidebar - jump to the matching command in the Commands view.

The Objects view reads only bundled data - no network access, no live BEYOND inspection. (For live values, see Live hover values and the Watcher.)

The Objects panel drilled into FX Effects → Oscillating effect → Geometric → Size X. The expanded Size X effect lists its full property surface: .Enabled, .Oscillator.Absinvert, .Oscillator.Absrevwave, .Oscillator.CENTERX, .Oscillator.Channel, .Oscillator.Damping, .Oscillator.Finish, .Oscillator.Period, .Oscillator.Phase, .Oscillator.Secondwave, .Oscillator.Start, .Oscillator.Waveform, .Oscillator.Waveperiod, .Oscillator.Wavespeed, .Oscillator.Width, .RouterInZone, .RouterMode, .RouterOutZone, .TimeActive, .TimeClock, .TimeDuration, .TimeDurationInBeat, .TimeEnabled, .TimeMetro, .TimeName, .TimeStateCanRestart. Sibling effects Size Y, Size Z, Roto Y, Roto X, Roto Z, Position X, Position Y, Position Z are shown collapsed below.
Fig 03.2aThe Objects panel drilled into a specific FX effect (Oscillating effect → Geometric → Size X). Every leaf is a real OSC-addressable property - right-click to Insert the matching setter command, or jump to the corresponding entry in the Commands view.
The Objects panel with the OSC toggle in the top-right active (highlighted blue). FX Effects, Cue Types, ActGridFocusedCue, and Beam are shown collapsed; Channels is expanded and its properties render as OSC addresses: /b/Channels/N/Attraction, /b/Channels/N/Color, /b/Channels/N/Friction, /b/Channels/N/Mass, /b/Channels/N/Name, /b/Channels/N/PhActive, /b/Channels/N/Reflection, /b/Channels/N/Value.
Fig 03.2bClick the OSC toggle (top-right) to flip the entire tree from PangoScript paths to the equivalent OSC addresses - useful when wiring up external OSC senders. Click again to flip back.

Diagnostics view

Issues in the active .BeyondCode file, grouped by rule. Each rule group has:

  • A row per diagnostic. Click to jump to the source range.
  • A Why? action that opens the bundled diagnostics reference scrolled to that rule's section - works offline, no internet needed.
The Diagnostics panel showing 'No diagnostics in the active file.' with an info icon.
Fig 03.3aClean file - empty state.
The Diagnostics panel showing one rule group titled 'unsupported-loop' with 2 issues: 'While' and 'Loop' are not PangoScript constructs. A 'Why? Open docs' action sits below the entries.
Fig 03.3bActive file with diagnostics. Click any row to jump to its source range; Why? opens the bundled rule reference offline.

§ 04BEYOND runtime integration

PangoLint can talk to a developer-local BEYOND for connection checks, property readbacks, and gated script-batch sends. All runtime features require a trusted workspace. Readback-only features require an explicit command or pangolint.beyond.liveHoverValues: true. Write/script execution features additionally require pangolint.beyond.allowScriptExecution: true and an in-app confirmation prompt. Runtime target settings are machine-scoped so a workspace cannot silently repoint PangoLint at a different BEYOND host.

Operator responsibility · Laser safety

Runtime integration is intended for developer-local testing only. Users remain responsible for validating all scripts inside BEYOND and for following all laser safety, zoning, output, and show-control procedures. PangoLint's lint gate is a syntax check, not a safety check - it cannot reason about beam paths, audience separation, scan-fail behavior, or any other operational laser-safety concern.

Test BEYOND connection

Command Palette → PangoLint: Test BEYOND Connection.

PangoLint sends a small OscOutTTS ping over the configured BEYOND Talk path, then waits for the OSC echo on oscListenHost:oscListenPort. The status bar reports success or the specific failure mode (DNS lookup, bind, no callback, etc.). Readback-only - no projector, output, geometry, or zoning state is touched.

The VS Code Command Palette with '>pangolint: te' typed. The top match - 'PangoLint: Test BEYOND Connection' - is highlighted; below it are other PangoLint commands: Clear all watched properties, Focus on BEYOND Watcher View, Focus on Commands View, Focus on Diagnostics View, Focus on Objects View.
Fig 04.1aReach the connection check from the Command Palette - every PangoLint command is prefixed PangoLint: for fast filtering.
A VS Code notification toast: 'BEYOND readback succeeded: pangolint-1778279554896-3937963a - Source: PangoLint'.
Fig 04.1bA successful round-trip surfaces as a notification carrying the unique request id. Failures use the same toast slot with the specific failure mode (DNS lookup, bind, no callback, etc.).

User objects (register a universe / zone alias)

PangoScript code commonly references workspace-scoped identifiers like MyUniverse.Button1.X or MainStage.Brightness. PangoLint doesn't know these out of the box. When such a path appears, PangoLint surfaces a code action lightbulb:

  • Register <Root> as a user universe - inherits the UniversePanel schema, with workspace-scanned button names merged in as arrayIndices.
  • Register <Root> as a zone alias - inherits the Zone schema.
  • Register <Root> as a master alias - inherits the Master schema.
A line of PangoScript reading 'COLORPICKER.SECONDARYCOLOR.ColorOff = colourSat' with a lightbulb in the gutter. The Quick Fix menu is open and shows three options, each marked with its own lightbulb: 'PangoLint: add COLORPICKER as user universe' (highlighted), 'PangoLint: add COLORPICKER as zone alias (inherits Zone schema)', and 'PangoLint: add COLORPICKER as Master alias (inherits Master schema)'.
Fig 04.2The user-objects code action menu. Pick the schema that matches your runtime object - the choice persists in .pangolint/user-objects.json and immediately rescopes diagnostics, completions, and hovers for that root.

Registry persists at .pangolint/user-objects.json (workspace-rooted). View / remove entries via PangoLint: Show User Objects and PangoLint: Remove User Object in the Command Palette.

When pangolint.folderScopedUniverses: true (default), PangoLint also auto-discovers universe panels by scanning sibling .BeyondCode files - if an unknown root appears in 2+ files in the same parent folder, it's treated as a universe panel without explicit classification. This mirrors BEYOND's workspace-scoped object visibility.

Send Talk batch to BEYOND

Two commands send straight-line PangoScript over BEYOND Talk:

  • PangoLint: Send Talk Batch to BEYOND - sends the entire active .BeyondCode file.
  • PangoLint: Send Selection as Talk Batch - sends just the highlighted selection. Right-click → Send Selection as Talk Batch works inside any .BeyondCode editor.

Both gates:

  1. pangolint.beyond.allowScriptExecution: true - explicit opt-in.
  2. Workspace must be trusted.
  3. Confirm modal - by default, confirmRunEachSession: true shows the modal every run, not just the first. Recommended on for safety.
  4. Lint-before-send refuses any text that fires an error-severity diagnostic, or any text where PangoLint's analysis limits prevent a full lint pass. Hint and warning diagnostics surface in the response but don't block.
  5. Control-flow blocked - BEYOND Talk isn't editor-equivalent. PangoLint blocks labels, goto, if, loops, waits, and exit in this path. Paste full control-flow scripts directly into BEYOND's PangoScript editor instead.

After a successful send, PangoLint: Re-send last Talk Batch replays the same batch (skips the lint, keeps the gates) - useful for tight iteration when nothing's changed.

Talk TCP can show BEYOND command replies and parser errors in the PangoLint: Run Output channel. Talk UDP is a valid primary transport, but it is send-only from PangoLint's side, so the Output channel reports datagram send status instead of BEYOND parser replies.

A modal warning dialog with a yellow caution triangle, a BEYOND Talk command-batch confirmation message, and Cancel and Run buttons.
Fig 04.3aThe Talk-batch confirmation modal. The header carries the line count and exact host:port; the body re-states the control-flow restriction so it's impossible to miss before clicking Run.
A red-bordered error notification explaining that BEYOND Talk command transport refused a script with control flow.
Fig 04.3bIf a script contains control flow, PangoLint refuses the send with a precise message - the first offending line, the count of additional offenders, and a pointer at the right runner (BEYOND's PangoScript editor).
CRLF reminder

BEYOND's PangoScript editor paste path treats LF-only clipboard text as one logical line. .BeyondCode files intentionally check out with CRLF endings. Confirm CRLF before copying when you bypass PangoLint and paste directly.

Fetch / set object values

  • PangoLint: Fetch object value from BEYOND - Command Palette or right-click → reads a property path you enter (e.g. Master.Brightness). Sends OscOutTTS with a typed return tag, awaits the OSC callback, and shows the value inline.
  • PangoLint: Set object value on BEYOND - Command Palette or right-click → writes a value to a property path. Gated like Send Talk batch. String values are entered without wrapping quotes; PangoLint serializes exactly one assignment line before sending.
The PangoLint: Run output channel showing two log lines: '[2026-05-08T22:50:53.047Z] fetch ColorChannel.1.Color ← <beyond-host>:16062' and 'ok - ColorChannel.1.Color = 29051'.
Fig 04.4A successful Fetch object value round-trip in the PangoLint: Run output channel. The first line records the request, the source, and the listening port; the ok line reports the resolved value.

Watcher: pin a property

The BEYOND Watcher is the bottom panel of the PangoLint sidebar. It's always visible; pinned properties appear inside it. Pin / unpin from the editor:

  • Right-click a property path → Pin property to BEYOND Watcher.
  • Right-click a watched item in the view → Unpin from Watcher.

Watcher view actions:

  • Refresh Watcher - re-reads every pinned property in one batch.
  • Clear all watched properties.

The watcher does not poll automatically - refreshes are explicit. This keeps network traffic predictable.

The BEYOND Watcher panel showing one pinned property - ColorChannel.1.Color = 29051 - with refresh and unpin actions.
Fig 04.5The BEYOND Watcher with a live readback. After Refresh Watcher, each pinned property shows its current BEYOND value; until then it stays as not yet fetched. The panel never polls on its own.

Validate objects in this file against BEYOND

Command Palette → PangoLint: Validate objects in this file against BEYOND.

PangoLint walks every property path referenced in the active file and issues a readback against BEYOND. Paths that resolve are cached as live-confirmed; paths that time out or return an error are reported in the PangoLint: Run Output channel and summarized in a notification. Useful as a pre-flight before sending a script, especially when you've added new universes / zone aliases since the last verified send.

Live hover values

Set pangolint.beyond.liveHoverValues: true to augment property-path hover tooltips with the current BEYOND value. Cached for 30 seconds per path. Off by default - generates network traffic on every hover. A nice quick-glance feature when actively tuning, but unnecessary the rest of the time.

A hover popup over Master.BPM. Header: 'Master.BPM'. Body: 'Verified property on Master.' followed by 'Live value: 120'.
Fig 04.7A live-hover tooltip on Master.BPM. The static schema info (verified property on Master) is augmented with the current BEYOND readback - here, the metronome is at 120 BPM.

§ 05The PangoLint MCP server

pangolint-mcp is a Model Context Protocol stdio server that exposes the same curated knowledge to AI coding agents. It ships from the mcp/ workspace in this repo and reads from the same data/pangoscript/ knowledge base the extension uses, so upgrades stay in lockstep.

When to use it

  • You ask Claude / Codex / Cursor / another agent to write or edit PangoScript and you want command-name verification against PangoLint's curated catalog, not hallucinated names from training data.
  • You want the agent to lint generated PangoScript before showing you the result.
  • (Opt-in) You want the agent to send lint-clean PangoScript to a developer-local BEYOND for fast visual feedback.

If you don't use AI agents in your PangoScript workflow, you don't need the MCP server.

Install & configure

Install the published package from npm:

npm install -g pangolint-mcp
which pangolint-mcp

Or install the pangolint-mcp tarball attached to a GitHub Release:

npm install -g ./pangolint-mcp-0.7.29.tgz
which pangolint-mcp

For local development, build the same tarball from this repo:

npm run package:mcp
npm install -g ./mcp/pangolint-mcp-0.7.29.tgz
which pangolint-mcp

Wire it into your MCP-aware client by adding a stdio entry:

Use PangoLint as the client-side server key when your client allows mixed-case names. Some clients show this key in tool-call UI.

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "PangoLint": { "command": "pangolint-mcp" }
  }
}

Claude Code (.claude/mcp.json or your CLI's MCP config)

{
  "mcpServers": {
    "PangoLint": { "command": "pangolint-mcp" }
  }
}

Codex CLI

codex mcp add PangoLint -- "$(which pangolint-mcp)"
codex mcp get PangoLint

If the old lowercase pangolint alias is already registered, run codex mcp remove pangolint first, then add it again.

To enable read runtime tools in Codex, add the startup env vars when you register the server:

codex mcp add PangoLint \
  --env PANGOLINT_MCP_RUNTIME_READ=enabled \
  --env PANGOLINT_MCP_BEYOND_TALK_TRANSPORT=tcp \
  --env PANGOLINT_MCP_BEYOND_TALK_TCP_HOST=127.0.0.1 \
  --env PANGOLINT_MCP_BEYOND_TALK_TCP_PORT=16063 \
  -- "$(which pangolint-mcp)"

Cursor / VS Code (with MCP)

{
  "servers": {
    "PangoLint": { "command": "pangolint-mcp" }
  }
}

To enable read runtime tools (network access to a local BEYOND), pass PANGOLINT_MCP_RUNTIME_READ=enabled and your BEYOND target as env vars. Add PANGOLINT_MCP_RUNTIME_WRITE=enabled only when you also want agents to send scripts through runScript.

{
  "mcpServers": {
    "PangoLint": {
      "command": "pangolint-mcp",
      "env": {
        "PANGOLINT_MCP_RUNTIME_READ": "enabled",
        "PANGOLINT_MCP_BEYOND_TALK_TRANSPORT": "tcp",
        "PANGOLINT_MCP_BEYOND_TALK_TCP_HOST": "127.0.0.1",
        "PANGOLINT_MCP_BEYOND_TALK_TCP_PORT": "16063"
      }
    }
  }
}

The full env-var list lives in mcp/README.md.

Knowledge tools (always on)

Eleven offline tools the agent can call without any opt-in:

ToolWhat it does
lookupCommandCurated entry for one command name (canonical or alias).
searchCommandsTask-intent search over names, aliases, descriptions, categories, forms, parameters, notes, and tags, with optional safetyTier filter.
lookupObjectUnified object lookup for canonical schemas and exact Object Tree paths (for example WS.N.N.Caption and FX.N.N.N.Oscillator.Period).
listObjectsObject roots from canonical schemas plus Object Tree-only families such as WS, FX, and DmxOutput.
searchObjectPropertiesRanked search over BEYOND Object Tree property paths (e.g. Master.ShowSpeed, FX.N.N.N.Oscillator.Period).
lookupObjectPropertyExact lookup for a single property path.
lookupPropertyControlsExact property lookup with Object Tree path, direct /b/ address, PangoScript command links, OSC routes, range data, readback, and behavior metadata.
searchPropertyControlsSearch property controls by path, OSC route, command name, context, and value metadata.
lintScriptRun PangoLint diagnostics over text and return the structured diagnostic list.
explainDiagnosticMarkdown documentation for one diagnostic code.
getServerConfigCurrent config and which tools are available. Agents are instructed to call this first.

Runtime tools (opt-in)

Four tools that talk to the configured BEYOND host. Read runtime and write runtime are separate opt-ins. Each tool returns { ok: false, blocked: true } unless the matching runtime tier was enabled at server startup.

ToolTierWhat it does
healthCheckT0Requires PANGOLINT_MCP_RUNTIME_READ=enabled. DNS + UDP-socket reachability of the configured BEYOND UDP target. Doesn't verify BEYOND accepts commands.
checkTalkConnectionT0Requires PANGOLINT_MCP_RUNTIME_READ=enabled. Opens Talk TCP and checks greeting, Echo 1, Hello, and Version replies.
readBeyondPropertyT1 (read)Requires PANGOLINT_MCP_RUNTIME_READ=enabled. Single readback of a property path (Master.Brightness, Zone.0.Red, …) and returns the value.
runScriptT2+ (write)Requires PANGOLINT_MCP_RUNTIME_WRITE=enabled. Lints the supplied text; refuses on any error-severity diagnostic; otherwise sends via configured BEYOND Talk transport.
Lint gate · syntax not safety

runScript's lint-before-send gate is the load-bearing developer behavior: runScript blocks script text that produces an error-severity PangoLint diagnostic before any BEYOND Talk send is attempted. Hint and warning diagnostics surface in the response but don't block the send. This is a syntax gate, not a safety gate - it does not validate operational laser-safety concerns.

MCP resources

Eight resources for browsing the bundled knowledge base directly:

URIContents
pangoscript://catalog/commandsCommand catalog (JSON).
pangoscript://schemas/objectsObject schema (JSON).
pangoscript://diagnostics/codesDiagnostics doc page (Markdown).
pangoscript://reference/operatorsOperator reference (Markdown).
pangoscript://reference/syntaxParser-shape reference (Markdown).
pangoscript://reference/command-referenceFull command reference (Markdown).
pangoscript://reference/master-object-treeObject Tree root reference (Markdown).
pangoscript://reference/object-modelObject model overview (Markdown).

Each advertises a size hint so MCP clients can budget context before fetching.


§ 06Reference: settings

All settings live under the pangolint.* namespace. The pangolint.beyond.* runtime settings are machine-scoped; configure them in user or machine settings, not workspace settings.

SettingDefaultPurpose
pangolint.beyond.talkTransportautoauto, tcp, or udp. Auto tries Talk TCP first and uses UDP only when fallback is explicitly allowed.
pangolint.beyond.talkTcpHost127.0.0.1BEYOND Talk TCP host.
pangolint.beyond.talkTcpPort16063BEYOND Talk TCP port.
pangolint.beyond.talkUdpHost127.0.0.1BEYOND Talk UDP host.
pangolint.beyond.talkUdpPort16062BEYOND Talk UDP port.
pangolint.beyond.talkUdpFallbackAllowedfalseAllow unauthenticated UDP fallback when TCP is unavailable before authentication or command send begins.
pangolint.beyond.talkTcpPassword""Optional BEYOND TCP Talk Server password. Redacted from runtime output.
pangolint.beyond.talkHost127.0.0.1UDP host alias.
pangolint.beyond.talkPort16062UDP port alias.
pangolint.beyond.oscListenHost0.0.0.0Local interface used for OSC callbacks from BEYOND.
pangolint.beyond.oscListenPort7000Local UDP port used for OSC callbacks from BEYOND.
pangolint.beyond.readbackTimeoutMs3000Timeout for OSC readback callbacks (ms).
pangolint.beyond.allowScriptExecutionfalseAllow sending BEYOND Talk command batches. Off by default.
pangolint.beyond.confirmRunEachSessiontrueConfirm modal before each script-run (recommended on).
pangolint.beyond.liveHoverValuesfalseAugment hover tooltips with live BEYOND values. Generates network traffic per hover.
pangolint.codeLens.labelReferencesfalseShow N references code lens above each label declaration.
pangolint.folderScopedUniversestrueAuto-discover universe panels by scanning sibling .BeyondCode files.
pangolint.diagnostics.highlightStylelineBackgroundControls extra editor emphasis for diagnostics: squiggle only, diagnostic-range background, or whole-line background.
pangolint.diagnostics.inlineMessagesoffAppends diagnostic messages after source lines when set to warningsAndAbove or all.

§ 07Reference: commands

Every command is also reachable from the Command Palette under PangoLint:.

Editor & validation

CommandWhat it does
pangolint.validateCurrentScriptRe-run diagnostics on the active .BeyondCode file and write a report to the PangoLint: Validation Output channel.

BEYOND runtime

CommandWhat it does
pangolint.checkBeyondConnectionTest BEYOND Connection (readback-only ping).
pangolint.runScriptSend the current file as a Talk batch (gated).
pangolint.runSelectionSend the current selection as a Talk batch (gated).
pangolint.replayLastScriptRe-send the last Talk batch verbatim.
pangolint.fetchObjectValueRead a property path from BEYOND.
pangolint.setObjectValueWrite a property path on BEYOND (gated).
pangolint.validateObjectsAgainstBeyondWalk every property path in this file and confirm it resolves on BEYOND.
pangolint.pinToWatcherPin a property path to the BEYOND Watcher.
pangolint.unpinFromWatcherUnpin a property from the Watcher.
pangolint.refreshWatcherRe-read every pinned property.
pangolint.clearWatcherUnpin all watched properties.

User objects

CommandWhat it does
pangolint.addUserObjectInternal - invoked by the code-action lightbulb.
pangolint.removeUserObjectRemove a registered universe / zone alias / master alias.
pangolint.showUserObjectsList currently registered user objects.

Sidebar

CommandWhat it does
pangolint.sidebar.refreshRefresh sidebar (Commands / Objects / Diagnostics).
pangolint.sidebar.filterCommandsOpen the filter prompt for the Commands view.
pangolint.sidebar.clearFilterClear the Commands filter.
pangolint.sidebar.insertAtCursorInsert the focused command's example at the cursor.
pangolint.sidebar.insertSelectedCommandSame, bound to Cmd+Enter / Ctrl+Enter when the Commands view is focused.
pangolint.sidebar.copySignatureCopy the focused command's signature to the clipboard.
pangolint.openReferenceSiteOpen the bundled offline PangoScript reference site in the default browser.
pangolint.sidebar.revealDiagnosticReveal the focused diagnostic at its source range.
pangolint.sidebar.openDiagnosticDocsOpen the bundled diagnostics doc scrolled to the focused rule.
pangolint.sidebar.showCommandAtCursorView the command at the editor cursor in the Commands sidebar.

§ 08Reference: keybindings

Combo (macOS / others)CommandWhen
Cmd+Enter / Ctrl+Enterpangolint.sidebar.insertSelectedCommandCommands view focused, editor open on a .BeyondCode file.
Cmd+. / Ctrl+.(VS Code default) Quick fixOn any diagnostic with a code action.
F12(VS Code default) Go to DefinitionOn a Goto MyLabel reference.
Shift+Alt+F(VS Code default) Format DocumentIn a .BeyondCode file.

§ 09Safety, privacy, and data

PangoLint biases conservative on three axes:

  • Network behavior. Nothing on the network unless you've explicitly configured a BEYOND host and invoked a runtime command.
    • Knowledge tools, sidebar, completions, hover (without liveHoverValues), formatting, diagnostics - all 100% offline.
    • Test BEYOND Connection is readback-only (an OscOutTTS ping).
    • Send Talk Batch, Set object value, and the MCP runScript require explicit opt-in (allowScriptExecution: true for the extension; PANGOLINT_MCP_RUNTIME_WRITE=enabled for the MCP server) and a trusted workspace.
  • Workspace mutations. PangoLint writes to two places only: .pangolint/user-objects.json (when you accept a register-as code action) and the active editor (when you explicitly insert a command / accept a quick fix). No silent edits.
  • What's bundled. The repo ships a curated knowledge base derived from BEYOND's published exports. Verbatim Pangolin reference materials (BEYOND command export .txt, OSC HTML, local help) are not in the public repo. End users get the pre-generated data/pangoscript/commands.merged.json and do not need private source inputs.

§ 10Troubleshooting

Test BEYOND Connection times out.

Confirm pangolint.beyond.talkTcpHost matches the BEYOND machine's IP (not 127.0.0.1 if BEYOND is on a separate box), and confirm pangolint.beyond.talkTcpPort matches the Talk TCP server port. If you explicitly use UDP, check pangolint.beyond.talkUdpHost and pangolint.beyond.talkUdpPort instead. Confirm BEYOND is configured to send OSC Out callbacks back to your laptop's IP on pangolint.beyond.oscListenPort. macOS / Windows firewall must allow the listener port.

Talk batch sent, BEYOND unchanged.

Check whether the script uses control flow (label: / goto / if / loops / waits / exit). BEYOND Talk is for straight-line command batches only; paste full scripts directly into BEYOND's PangoScript editor. The BEYOND Notification Center (in BEYOND itself) is the runtime oracle for failed sends; check it when a probe inexplicably no-ops.

Pasted script collapsed into one line.

BEYOND's paste path treats LF-only clipboard text as one logical line. .BeyondCode files intentionally check out with CRLF endings. Confirm CRLF before copying.

Property hover says "unknown root".

The root identifier isn't in the canonical schemas and hasn't been registered as a user object yet. Click the lightbulb on the unknown root to register it as a universe / zone alias / master alias, or enable pangolint.folderScopedUniverses so PangoLint auto-discovers universes from sibling files.

MCP runtime tool returns { ok: false, blocked: true }.

The server was started without the required runtime tier. Add PANGOLINT_MCP_RUNTIME_READ=enabled for healthCheck / readBeyondProperty, or PANGOLINT_MCP_RUNTIME_WRITE=enabled for runScript, then restart the client. The agent is instructed not to retry - it should tell you how to enable runtime instead.

Markdown reference link from Why? doesn't open.

The bundled diagnostics doc lives inside the VSIX. Reload the VS Code window after upgrading PangoLint so the new doc path resolves.