Quiote for VS Code
Route explorer, triad navigation, and live introspection for apps built on the
Quiote PHP framework.
This is an early 0.1.0 release: core navigation, route exploration,
diagnostics, and scaffolding all work end-to-end, but some polish (hover
previews, telemetry-informed defaults, deeper Marketplace integration) is
still ahead. See Known limitations for what's missing
today.
Features
- Triad navigation — jump between an Action, its View, and its Template
(
Modules/{Module}/Actions/{Action}Action.php ↔ Views/{Action}{View}View.php
↔ Templates/{Action}{View}.{php,tal,xsl,twig}, matching whichever
renderer the app configures per output type — PHPTAL, XSLT, and Twig
templates are recognized alongside plain PHP). Available via:
- right-click → Quiote: Go to Related in the editor (or the default
keybinding
Alt+O), while a triad file is open
- CodeLens links at the top of any triad file (needs
editor.codeLens: true,
VS Code's default)
- right-click an Action node in the Route Explorer → Open View / Open
Template / Describe Action — Open View/Open Template prefer real,
per-output-type paths from live introspection (Artifact/Console/Probe,
whichever answers) over convention-guessing, and prompt with a picker
when a view renders more than one output type's template (e.g.
html
via PHPTAL alongside xml via plain PHP)
- a status-bar breadcrumb showing
Module · Action · Role for the active file
$(list-tree) Quiote status bar item — always visible (not gated on
having a triad file open); click it for a QuickPick of every Quiote command
(List Routes, Refresh, Validate Config, the four scaffolding commands, Go
to Related). This — plus the Command Palette (Quiote: ...) — is the
answer to "how do I do anything with this extension."
- Route Explorer — a
Quiote activity-bar view listing every route the app
knows about, grouped Module → Action → Route. Backed by a four-rung
introspection ladder (fastest first) that degrades gracefully:
- Artifact — reads
cache/introspection/app.json straight off
disk, zero PHP spawn. Written by the framework's own routes:compile
command — no assistant needed, just a Quiote app.
- Probe — the quiote-mcp-assistant's
probe.php, batched via its overview/diagnostics capabilities (one
app bootstrap for routes+modules+triads+diagnostics together). Auto-detected
if the target app has it installed via
composer require --dev quioteframework/quiote-mcp-assistant (searched
from the app dir upward, since vendor/ isn't always a direct child of
the app dir); override with quiote.probePath otherwise.
- Console — the app's own
vendor/bin/quiote routes:compile --json
(framework-only, no assistant needed — this also refreshes the Artifact
as a side effect).
- Static — a filesystem convention scan (no PHP invoked at all), used
for instant paint and as the last-resort fallback.
- Problems panel diagnostics — route/triad problems (
MISSING_VIEW,
SHADOWED_CONFIG, duplicate routes, ...) plus config validation where the
Probe rung is available, via Quiote: Validate Config or automatically on
save.
- Scaffolding —
Quiote: New Module / New Action / New Plugin /
New DB Connection, each a dry-run preview → confirm → write flow that
never overwrites an existing file. Needs the Probe rung. New Action
resolves the target app's real configured renderer for the html
format and writes a minimal, engine-correct starter template in whichever
syntax that renderer actually uses — PHPTAL, Twig, XSLT, or plain PHP —
rather than assuming PHP. Only a renderer with no starter to offer (a
fully custom, app-registered one) is skipped, reported back in the
confirm dialog/completion message with the extension to author by hand.
- Tasks —
routes:list, cache:warmup, and about show up under
Tasks: Run Task as quiote tasks (needs the Console rung —
vendor/bin/quiote found). No problem matcher is attached: these commands'
diagnostics render as Symfony Console's boxed, colored text, not a
reliable regex target — use Quiote: Validate Config (or the automatic
Problems-panel refresh) for structured diagnostics instead.
- Cassette Explorer — a
Cassettes activity-bar view listing recorded
replay (VCR-style record/replay) cassettes, backed by the target app's
own cassette:list/cassette:show --json (needs the Console rung —
vendor/bin/quiote). Clicking a cassette opens a tabbed, Postman-style
detail view (Overview, Request, Session/User, Effects, Response,
Exception, Log) with a per-body "Load full body" action for anything the
console excerpted. Quiote: Analyze Cassette with Copilot builds a prompt
from the cassette and opens it in Copilot Chat — referencing the app's own
MCP server (mcp:serve, auto-registered to Copilot Chat when the target
app has McpPlugin active) when available, or embedding the cassette JSON
directly otherwise. Pre-fills the prompt for review by default; see
quiote.copilot.autoSendPrompt to send immediately instead.
- File decorations — Action/View/Template files get an
A/V/T badge in
the explorer.
- Snippets — PHP (action/view/config), XML (settings/route), and YAML
(settings/module) snippets for common Quiote authoring patterns.
Requirements
- VS Code
^1.101.0 (the Cassette Explorer's Copilot integration needs the
stable Language Model/MCP-provider APIs; everything else works on older
VS Code too, but the extension declares one floor).
- A workspace containing a Quiote app, detected via
.quiote.json (an
{"app_dir": "..."} marker, resolved relative to the marker file) or a
Config/settings.{php,yaml,yml,xml} file.
- PHP on
PATH (or configured via quiote.phpPath) if you want the
Artifact/Console/Probe rungs — the extension works without PHP at all via
the Static rung, just with less detail (no route paths/methods).
quioteframework/quiote-mcp-assistant as a dev dependency of the target
app (composer require --dev quioteframework/quiote-mcp-assistant) — this
is required for the Probe rung, which in turn is required for
scaffolding (New Module/New Action/New Plugin/New DB Connection)
and config-validation diagnostics. Without it, everything else still works
at the Artifact/Console/Static rungs, but those commands report "needs the
assistant."
phpstan/phpstan as a dev dependency of the target app (with
vendor/bin/phpstan present) if you want to enable
quiote.phpstan.enable, which cross-checks Action/View execute*()
declared return types against what they actually return. Off by default;
see Configuration.
Installing it locally
This extension isn't published to the Marketplace yet, so install it from
source:
Option A — Run it from source (fastest, for trying it out or developing)
- Clone this repo and install dependencies:
git clone <this-repo-url>
cd quiote-vscode
npm install
- Open the folder in VS Code.
- Press F5 (or Run → Start Debugging). This launches an Extension
Development Host window — a second VS Code instance with the extension
loaded. Open a Quiote app folder in that window to try it.
Changes to src/ are picked up after re-running npm run compile (or
npm run watch in a terminal) and reloading the dev host window
(Cmd/Ctrl+R inside it, or Developer: Reload Window from the command palette).
Option B — Install a packaged .vsix into your everyday VS Code
This installs it into your real VS Code, not just a throwaway dev host:
npm install
npx @vscode/vsce package
This produces quiote-vscode-<version>.vsix in the project root. Then either:
Reload VS Code (or just restart it) afterwards. To update after pulling new
changes, repackage and reinstall the same way — VS Code overwrites the
previous version.
To remove it: Extensions view → find "Quiote" → Uninstall.
Configuration
| Setting |
Default |
Description |
quiote.phpPath |
"php" |
PHP executable used for the Console/Probe rungs. |
quiote.appDir |
"" (auto-detect) |
Quiote app root, relative to the workspace. |
quiote.probePath |
"" (auto-detect) |
Path to the assistant's probe.php. Auto-detects a composer require --dev-installed assistant first. |
quiote.introspection.mode |
"auto" |
Pin a rung (auto|artifact|probe|console|static) for debugging. |
quiote.introspection.timeoutMs |
20000 |
Timeout for probe/console spawns — generous by default since a large app's first cold-cache bootstrap can take a while. On timeout you're prompted to keep waiting 30s more rather than failing immediately. |
quiote.diagnostics.enable |
true |
Enable the Problems-panel integration. |
quiote.diagnostics.requireReturnType |
true |
Warn when an Action's/View's execute*() has no declared return type. |
quiote.cache.regenerateOnSave |
true |
Re-query routes/diagnostics in the background when watched files change. |
quiote.phpstan.enable |
false |
Cross-check declared vs. actual execute*() return types via PHPStan. Needs vendor/bin/phpstan in the target app (see Requirements) — off by default, and turning it on prompts for consent before creating phpstan-return-type.neon if it doesn't exist yet. |
quiote.phpstan.configPath |
"" (auto-detect) |
Path to the isolated PHPStan return-type config. Auto-detected next to vendor/bin/phpstan. |
quiote.phpstan.timeoutMs |
60000 |
Timeout for PHPStan return-type check invocations. |
quiote.copilot.autoSendPrompt |
false |
Submit the Analyze Cassette with Copilot prompt immediately instead of only inserting it into the Chat input for review. |
Commands
| Command |
Works today? |
Quiote: Go to Related |
Yes |
Quiote: Refresh Routes |
Yes |
Quiote: Warm Introspection Cache |
Yes (currently an alias for refresh) |
Quiote: List Routes |
Yes |
Quiote: Describe Action |
Yes (from a Route Explorer action node) |
Quiote: Open View / Open Template |
Yes (from a Route Explorer route node) |
Quiote: New Module / New Action / New Plugin / New DB Connection |
Yes — needs the Probe rung (assistant installed). Dry-run preview → confirm → write; never overwrites an existing file. |
Quiote: Validate Config |
Yes — works at the Artifact/Console/Probe rungs (route/triad diagnostics); config-validation diagnostics specifically need the Probe rung. Populates the Problems panel. |
Quiote: Refresh Cassettes |
Yes — needs the Console rung. |
Quiote: Show Cassette |
Yes — from a Cassette Explorer node, or a Command Palette picker. Needs the Console rung. |
Quiote: Analyze Cassette with Copilot |
Yes — from a Cassette Explorer node, or a Command Palette picker. Needs the Console rung and an active GitHub Copilot session. |
Development
npm run compile # typecheck + bundle
npm run lint
npm run test-unit # pure-logic tests, no VS Code needed
npm run test-integration # runs in a real headless VS Code instance
npm test # both
Known limitations
quiote.cache.regenerateOnSave invalidates unconditionally on any matching
save rather than rehashing the artifact's dependency manifest to check
real staleness — cheaper, and the next live rung recomputes anyway.
- Scaffolding needs the Probe rung (the assistant installed via Composer) —
Console/Static/Artifact have no equivalent, so these commands show "needs
the assistant" without it. Config-validation diagnostics specifically are
also Probe-only; route/triad diagnostics work at every rung down to Console.
- Route Explorer targets the first detected Quiote app in a multi-root
workspace.
- Template-extension detection without a live rung (CodeLens, Go to Related,
file decorations, and the Alt+O index all work purely off disk, no PHP
round-trip) only recognizes the framework's four built-in renderer
extensions (
.php, .tal, .xsl, .twig) — an app-registered custom
renderer with a different extension won't be picked up there. Any rung
with a live introspection artifact (Artifact/Console/Probe) instead
reports the app's real configured extension per output type, no
guessing involved.
- No hover previews yet, and no telemetry to inform future defaults — both
are planned but not implemented in
0.1.0.
| |