source-map-php scans a Laravel or Hyperf repository, writes source-code metadata to Meilisearch, and answers search from the command line. Symbols, routes, tests, package ownership, schema hints, and comments stay. Strings that look like secrets or personal data are dropped before they are stored.
The project README documents the two-line install. The single line is the same formula by its full Homebrew name.
The query, the symbol, and the validate command are the examples in the project README. The email is only a shape the sanitizer drops. This slip is not a live search result.
Run it in this order.
Nothing stays running between commands. There is no app server. search and validate both accept --json.
init
init writes config/indexer.toml, .env.example, docker-compose.meilisearch.yml, and ~/.config/meilisearch/connect.json with placeholder values when that file is missing. It will not overwrite a connect file you already have. Commands that use --config load <project-root>/.env before resolving Meilisearch settings. The default config path is config/indexer.toml.
source-map-php init --dir .
cp .env.example .env
Fill .env for credentials that belong to this repo. change-me below is the placeholder from the README. Skip .env when ~/.config/meilisearch/connect.json already has the shared credentials.
Check the environment for a repository. doctor expects Phpactor to be installed, even though symbol extraction can fall back without it.
source-map-php doctor --repo /path/to/php-repo
index
Build an index. --framework is auto, laravel, or hyperf. --mode clean replaces the index. The project name in this example is the one the README uses.
source-map-php index --repo /path/to/php-repo --project-name ****-api --framework auto --mode clean
search
--project is the saved project name or the full repository path, for example /Users/you/work/****-api. Omit --index and the CLI searches every saved index type and prints grouped results. You can also pass symbols, routes, tests, packages, or schema.
Use --mode staged when you want a run you can check before it replaces the live index. verify checks the staged indexes. promote takes the run id.
source-map-php index --repo /path/to/php-repo --framework auto --mode staged
source-map-php verify
source-map-php promote --run-id <run-id>
Remove a saved project
remove deletes the project entry from ~/.config/meilisearch/project.json and the matching Meilisearch indexes for that project prefix. --keep-indexes forgets the saved name and leaves the indexes in place.
The tool detects Laravel and Hyperf repositories. It extracts symbols, comments, package ownership, tests, and schema metadata, plus framework routes. Search targets these index names.
symbols
routes
tests
packages
schema
Laravel
Route extraction is in place. Fixtures cover symbol, route, schema, and test extraction for one Laravel repository.
Hyperf
Route extraction is in place. Fixtures cover route and test extraction for one Hyperf repository. Real-world route edge cases are still being hardened.
How an index is built
Scan allowlisted project paths.
Export Composer package ownership metadata.
Extract symbols and docs from PHP files.
Enrich with framework-specific route and schema metadata.
Link tests and generate validation commands.
Apply Meilisearch settings and write documents.
Save project metadata to ~/.config/meilisearch/project.json.
Emit a run manifest to build/index-runs/<run_id>.json.
Metadata in. Secrets out.
If it smells like secrets or PHI, it should not reach Meilisearch.
Project README, safety model
The index is source-code metadata: symbols, routes, tests, package ownership, schema hints, comments, and PHPDoc. It is explicitly not a production data search engine. Before strings are indexed, the sanitizer drops values that look like:
API keys
JWTs
private keys
passwords and DSNs
email addresses
phone numbers
long numeric IDs
date-of-birth-like strings
medical-record-style identifiers
What the scan touches.
These are the default allow and deny rules from the project README. Vendor indexing is on by default, and only for allowlisted vendor paths.
Version 0.1.3. The formula homepage is the GitHub repository. Crate documentation is on docs.rs.
Homebrew
The formula is source-map-php in dickwu/tap. It depends on Rust at build time and installs every binary the crate builds.
brew tap dickwu/tap
brew install source-map-php
brew install dickwu/tap/source-map-php
crates.io
cargo install source-map-php
From source
git clone git@github.com:dickwu/source-map-php.git
cd source-map-php
cargo build --release
The binary is at ./target/release/source-map-php.
What Homebrew installs
Two binaries: source-map-php and phpantom_lsp. phpantom_lsp speaks Language Server Protocol on stdio. It answers document symbols, definitions, and references with the fallback PHP parser. Reference search walks PHP files under the workspace root and skips .git, vendor, and node_modules. It does not replace Phpactor. doctor still expects Phpactor.
What you still need
The README lists these build requirements. Indexing also needs a Meilisearch instance. Phpactor on PATH is the recommended extractor.
Rust toolchain
PHP 8.3+
Composer
Meilisearch
Phpactor on PATH, for the best extraction quality
Host order: MEILI_HOST, then meilisearch.host in config/indexer.toml when you override the default, then ~/.config/meilisearch/connect.json, then http://127.0.0.1:7700. Key order: MEILI_MASTER_KEY by default, or the env var named by meilisearch.master_key_env, then ~/.config/meilisearch/connect.json.
The project says so itself. CI runs cargo fmt --check, cargo clippy --all-targets --all-features -- -D warnings, and cargo test on Linux and macOS. Tagged pushes matching v* build x86_64-unknown-linux-gnu and aarch64-apple-darwin.
Hyperf routes
Extraction still needs hardening for large repositories, mixed file encodings, and route organization. The README calls out config/routers/*.php and grouped route trees as next work.
Phpactor and fallback parsingdoctor expects Phpactor even though the extractor can fall back. Multiline method signatures in that fallback are listed as next work.
Live Meilisearch in CI
End-to-end indexing against a live Meilisearch instance is not covered in CI. Non-UTF-8 junk files inside scanned trees are still being hardened.
Release policy
Release artifacts are wired in CI. The README says no versioning policy is documented yet, and it still lists a first tagged binary release as next work. Install from Homebrew or crates.io.
Questions.
What does source-map-php index?
It indexes PHP source-code metadata from Laravel and Hyperf repositories into Meilisearch: symbols, comments, routes, tests, package ownership, and schema hints. It does not index production application data.
How do I install it with Homebrew?
Run brew tap dickwu/tap, then brew install source-map-php. The fully qualified command brew install dickwu/tap/source-map-php installs the same formula.
Which frameworks does it detect?
It detects Laravel and Hyperf repositories. The index command accepts --framework auto, --framework laravel, or --framework hyperf.
Where does the CLI read Meilisearch settings?
The host is resolved from MEILI_HOST, then meilisearch.host in config/indexer.toml when you override the default, then ~/.config/meilisearch/connect.json, then the built-in default http://127.0.0.1:7700. The API key is resolved from MEILI_MASTER_KEY by default, or the env var named by meilisearch.master_key_env, then ~/.config/meilisearch/connect.json.
What does the sanitizer drop before indexing?
API keys, JWTs, private keys, passwords and DSNs, email addresses, phone numbers, long numeric IDs, date-of-birth-like strings, and medical-record-style identifiers.
Does it run an application server?
No. source-map-php is a command-line tool, and no always-on app server is required.
How do I choose a project when I search?
Pass --project the saved project name or the full repository path. Omit --index to search symbols, routes, tests, packages, and schema and print grouped results.
What else does the Homebrew formula install?
It installs the source-map-php and phpantom_lsp binaries. phpantom_lsp is a stdio language server for document symbols, definitions, and references, using the fallback PHP parser.
What is still unfinished?
The project describes itself as a working baseline. Hyperf route extraction still needs hardening on large repositories with mixed file encodings and route organization. The doctor command expects Phpactor even though extraction can fall back. End-to-end indexing against a live Meilisearch instance is not covered in CI.