suzumaze / bear-phpactor-extension
BEAR.Sunday extension for phpactor
Package info
github.com/suzumaze/bear-phpactor-extension
Type:phpactor-extension
pkg:composer/suzumaze/bear-phpactor-extension
Requires
- php: ^8.2
Requires (Dev)
- phpactor/language-server-protocol: 3.17.4
- phpactor/phpactor: ^2026.07
- phpstan/phpstan: ^2.2
- phpunit/phpunit: ^10.0
- squizlabs/php_codesniffer: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
- dev-main
- v0.2.0
- v0.1.9
- v0.1.8
- v0.1.7
- v0.1.6
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- dev-codex/refine-resource-reference-analysis
- dev-codex/di-aop-source-inventory
- dev-codex/lsp-diagnostics
- dev-codex/resource-response-shape
- dev-codex/semantic-quality-ci
- dev-codex/release-v0.1.9
- dev-codex/fix-empty-semantic-query-params
- dev-codex/address-extension-review
- dev-codex/release-v0.1.8
- dev-codex/contract-coverage
- dev-codex/release-v0.1.7
- dev-codex/project-diagnostics
- dev-codex/address-mcp-feedback
- dev-codex/release-v0.1.5
- dev-codex/resource-semantic-query
- dev-codex/document-vscode-twig-association
- dev-codex/add-template-path-navigation
- dev-codex/add-twig-qiq-definition
This package is auto-updated.
Last update: 2026-09-24 12:44:51 UTC
README
English | 日本語
Adds BEAR.Sunday semantics to Phpactor, so standard LSP operations understand Resource URIs, SQL, JSON Schema, ALPS, Router, Twig, and Qiq conventions.
BEAR.Sunday semantics
↓
bear-phpactor-extension
↓
Phpactor / LSP
↓
VS Code / Neovim / Emacs / other LSP clients
This package registers Phpactor locators, providers, and completors. It does not implement editor-specific APIs, render templates, execute application PHP, or provide MCP tools.
Requirements
- PHP 8.2 or later
- Composer
- Phpactor compatible with the versions in
composer.json - A BEAR.Sunday project with
autoload.psr-4configured
Features
| BEAR.Sunday semantic | LSP operation and result |
|---|---|
| Resource URI | Definition, References, Hover, URI Completion, and Document Link for app://self/user |
| SQL | Definition, References, and Hover for #[DbQuery('point_distance')] and @Query("point_distance") |
| JSON Schema | Definition, Type Definition, References, Hover, and body-property Completion |
| ALPS | Definition, References, and Hover for descriptors selected through apidoc.xml |
| Twig and Qiq | Definition, References, Hover, and Document Link for static template references; Definition from #[Embed] relations |
| Aura Router | Definition, References, and Hover from a route name to its Page Resource |
| Static inconsistencies | Standard LSP diagnostics for broken explicit BEAR references in the current editor buffer |
Project roots and namespace prefixes come from the project's composer.json. Normal PHP definitions remain handled by Phpactor.
Editor diagnostics
Phpactor publishes warning diagnostics with source bear for direct static Resource calls,
Route, SQL, JSON Schema, ALPS, Twig, and Qiq references that are statically missing,
ambiguous, invalid, or malformed. The provider analyzes only the current editor buffer
and resolves its targets from saved workspace files; it does not rescan the project on
each edit. Files that have not yet been saved once are not analyzed.
The full saved-project query bear/project/diagnostics additionally checks Resource
parse failures, Link/Embed target methods, and contract-name differences. The editor
provider intentionally omits those project-wide checks. It is named bear and follows
Phpactor's standard language_server.diagnostics_* settings; include or exclude it
through language_server.diagnostic_providers when selecting providers explicitly.
Headless semantic queries
Standard position-based LSP methods remain the primary interface. For clients that
already have a BEAR identifier but no open document position, the Language Server also
provides 23 read-only bear/* requests for project, Resource, Route, SQL, Template,
ALPS, Schema, DI, and AOP facts. Resource attribute facts and their workspace inventory are
available without executing application PHP. bear/project/diagnostics aggregates
evidence-backed problems in explicit saved-source references while keeping per-item
failures out of the outer query status. bear/project/contractCoverage reports where
request/response JSON Schema and ALPS contract surfaces are available, absent, dynamic,
or unresolved without treating optional adoption gaps as project errors.
Its scheme selector and whole-project summary.schemes split app and page
URIs without claiming either scheme proves public exposure or JSON rendering.
bear/project/info reports the stable bear-semantic protocol name, its
available requests, and its capabilities. The additive contract is documented in
docs/lsp-semantic-requests.md.
bear/resource/describe keeps declarative #[Link]/#[Embed] relations in
relationsOut and reports direct static $resource/$this->resource calls separately
as referencesOut; coverage fields make both boundaries explicit.
bear/di/bindings inventories direct static $this->bind(X)->to(Y) declarations,
and bear/aop/pointcuts inventories static bindInterceptor declarations and their
matcher syntax trees. They report saved-source declarations, not the active application
context, winning DI binding, evaluated pointcut, or woven runtime behavior. Dynamic or
unsupported forms remain visible as reasoned unresolved items.
An IDE is not required. The included client starts a real Phpactor stdio process:
php tools/semantic-lsp-query.php /path/to/bear-project \
bear/resource/describe \
'{"uri":"app://self/user","contextPath":"src/Resource/App/User.php"}'
For an AI client auditing cache and Resource metadata across a workspace:
php tools/semantic-lsp-query.php /path/to/bear-project \
bear/resource/attributeIndex \
'{"scheme":"app","limit":50,"offset":0}'
To compare exact request-name presence across a Resource method, JSON Schema, and ALPS descriptor without claiming type or semantic equivalence:
php tools/semantic-lsp-query.php /path/to/bear-project \
bear/contract/compare \
'{"uri":"app://self/user","method":"onPost","schemaKind":"request"}'
Response comparison can also include statically proven $this->body keys. It
accepts only straight-line literal-key array assignments; dynamic or conditional
body construction remains explicitly unsupported instead of being guessed.
To inspect bounded project-wide diagnostics without booting the application:
php tools/semantic-lsp-query.php /path/to/bear-project \
bear/project/diagnostics \
'{"limit":100,"offset":0}'
To find Resource methods that can benefit from JSON Schema or ALPS adoption:
php tools/semantic-lsp-query.php /path/to/bear-project \
bear/project/contractCoverage \
'{"limit":100,"offset":0,"gapsOnly":true,"scheme":"page"}'
To inspect statically declared DI bindings without creating a container:
php tools/semantic-lsp-query.php /path/to/bear-project \
bear/di/bindings \
'{"limit":50,"offset":0}'
Both project-wide reports use stable offset pagination and an approximate serialized-byte
budget; a page can be shorter than the requested limit. Advance offset by the actual
number of returned items while truncated is true. Diagnostics accepts its published
1–200 limit range (default 100); contract coverage accepts 1–100 (default 100).
The budget is not a strict wire-size guarantee for an unusually large single item.
These requests inspect saved workspace files only. They do not execute the BEAR application, modify files, access the network, or provide an MCP server.
Twig and Qiq
Template navigation implements only confirmed BEAR.Sunday relationships from the standard Qiq and Twig layouts.
| Reference | Supported cursor position | Target |
|---|---|---|
| Twig path | Static string in the first argument of extends, include, or include(), or the second argument of block() |
Existing template under src/Resource, then var/templates |
| Qiq path | Static string in setLayout(), render(), or extends(), in Qiq helper syntax or native PHP |
Existing .php template under var/qiq/template; ./ and ../ are relative to the current template |
| Twig Embed relation | Leading variable in {{ rel }} or `{{ rel |
raw }}undervar/templates/{App,Page}/.../*.html.twig` |
| Qiq Embed relation | $rel in {{= $rel }} or {{h $rel }} under var/qiq/template/{App,Page}/.../*.php; legacy $this->rel is also accepted |
Qiq template for the Resource declared by the parent Resource's #[Embed] |
Embed navigation reads only named static string arguments rel: and src:. Absolute app://self/... and page://self/... URIs are supported. A relative /... source inherits the parent Resource scheme and resolves against self.
Dynamic expressions, Twig imports and property expressions, unknown Qiq/PHP calls, imported-app Resources, custom template roots, and ambiguous conventions are not resolved.
Installation
Phpactor and this package must share one Composer autoloader.
Commands in this section run in a terminal, not in an editor command palette.
VS Code
Use Phpactor Setup for BEAR.Sunday. It installs a tested Phpactor/core combination outside the project, configures the official VS Code client, and provides commands to inspect or update this core package.
Manual global installation
Phpactor recommends installing the language server outside project dependencies. The following creates a dedicated installation:
mkdir -p ~/.local/share/phpactor-bear cd ~/.local/share/phpactor-bear composer init --no-interaction --name=local/phpactor-bear composer config minimum-stability dev composer config prefer-stable true composer require \ phpactor/phpactor:2026.07.22.0 \ phpactor/language-server-protocol:3.17.4 \ suzumaze/bear-phpactor-extension
Generate Phpactor's global extension list while preserving other keys in an existing valid config:
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/phpactor" cd "${XDG_CONFIG_HOME:-$HOME/.config}/phpactor" PHPACTOR_BIN="$HOME/.local/share/phpactor-bear/vendor/bin/phpactor" \ "$HOME/.local/share/phpactor-bear/vendor/bin/bear-phpactor-init"
Point the editor's Phpactor path to:
~/.local/share/phpactor-bear/vendor/bin/phpactor
To update only this package within the compatible range:
cd ~/.local/share/phpactor-bear composer update suzumaze/bear-phpactor-extension --with-dependencies cd "${XDG_CONFIG_HOME:-$HOME/.config}/phpactor" PHPACTOR_BIN="$HOME/.local/share/phpactor-bear/vendor/bin/phpactor" \ "$HOME/.local/share/phpactor-bear/vendor/bin/bear-phpactor-init"
Project-local installation
If Phpactor is already managed by the project, install the packages together and run the initializer from the project root:
composer require --dev \ phpactor/phpactor:2026.07.22.0 \ phpactor/language-server-protocol:3.17.4 \ suzumaze/bear-phpactor-extension vendor/bin/bear-phpactor-init vendor/bin/phpactor config:trust --trust
Set the LSP client to the same installation's vendor/bin/phpactor. Re-run bear-phpactor-init after changing Phpactor versions because container.extension_classes replaces, rather than extends, Phpactor's built-in list.
Editor requirements
An LSP client must start this Phpactor binary with language-server and send the relevant document to it.
Qiq templates use .php and normally reach Phpactor. The official Phpactor VS Code client does not select Twig documents by default. For the BEAR standard .html.twig layout, VS Code users can apply this workspace-local workaround:
{
"files.associations": {
"*.html.twig": "php"
}
}
This sends Twig as PHP and can affect highlighting, diagnostics, formatting, and other Twig extensions. Clients with configurable document selectors should attach Phpactor directly to Twig instead.
Resolution rules
- Definitions are returned only when the cursor is on a supported reference and the target exists.
- Targets must remain inside the workspace; traversal and arbitrary external paths are rejected.
Editor navigation may additionally follow an ImportApp package root recorded by Composer in
vendor/composer/installed.json, including a path-repository symlink. Read-onlybear/*requests keep the stricter workspace-only boundary. - Invalid syntax, missing files, and unsupported expressions return no result instead of throwing.
- Static analysis only is used. Templates are not rendered and application PHP is not executed.
- Multiple Resource candidates are sorted and presented by fully qualified name for definitions. Ambiguous reference-search sites are treated as unresolved.
- Repeated Embed relations resolve only when every occurrence points to the same normalized Resource URI.
Definition behavior
- Resource URI, SQL, attribute-based JSON Schema, ALPS, Router, and template relationships use Go to Definition.
- A Resource class declaration uses Go to Type Definition for its convention-based JSON Schema. Normal Go to Definition remains owned by Phpactor.
- Router navigation uses the first argument as the route name. The second argument is an HTTP path and is intentionally not a jump site;
$map->attach()is also excluded.
Known limitations
- Template paths follow only the default BEAR Twig and Qiq loader layouts.
- The official VS Code client needs the Twig workaround described above.
- SQL definitions land at the beginning of the
.sqlfile. - Reference search reads saved files only and scans only
autoload/autoload-devPSR-4 roots. - Resource completion uses a text scan for
extends ... ResourceObject, which can produce extra candidates. - Windows drive-letter paths are guarded for template resolution but remain incomplete in PSR-4 directory resolution.
Related projects
- Phpactor Setup for BEAR.Sunday: VS Code installation and update wrapper for this package
- BEAR.Sunday Extension Pack: earlier VS Code-specific implementation
- idea-php-bearsunday-plugin: PhpStorm plugin with JetBrains-specific features
These projects use different architectures and do not replace one another.
Development
composer check
The suite includes unit tests and real Phpactor stdio sessions from initialize through shutdown. The repository also ships standalone project-level verification tools:
tools/coverage.php: compare definition targets with independently computed conventions.--assert-clean --expect-sites=Nturns the report into a reproducible CI gate.tools/misfire.php: probe positions where the extension must remain silent.--assert-clean --expect-sites=N --expect-probes=Nfails on false positives, ambiguous pickers, missing responses, or a changed fixed corpus.
The scheduled regression job reads a pinned BEAR.Kata source snapshot without installing its dependencies or running the application. These measurements are regression oracles for the human-readable conventions documented here, not a replacement for those conventions.
tools/references.php: compare Resource references and verify definition round trips.tools/latency.php: measure cold and warm definition latency.tools/verify-invariants.php: check end-to-end LSP invariants mechanically.tools/verify-kata-conventions.php: measure convention-based Schema reach in BEAR.Kata.
These tools require an explicit target application and are not run by the normal unit-test suite.