Fix Tinker execution and PsySH lifecycles - #570
Merged
Conversation
Treat every non-null --execute value as one-shot code, including zero and the empty string. Preserve PsySH exit codes, contain ordinary execution failures, and stop mutating Symfony Console's shared exception policy. Use a small execute-only shell that omits PsySH's interactive signal listener while keeping the normal interactive shell unchanged. Tighten configured command and alias inputs, keep loader cleanup exception-safe, and cover falsey code, signals, exit behavior, disabled commands, coroutine dispatch, and the disposable application subprocess path.
Normalize configured class and namespace names once, then match only exact classes or real namespace descendants. This prevents a prefix such as App\Nova from also admitting App\NovaThing. Apply the same boundary rule to exclusions and require vendor paths to be actual children of the configured vendor directory. Add coverage for exact matches, descendants, prefix siblings, trailing separators, exclusions, vendor children, and vendor-prefix siblings.
Keep application presentation best-effort when one optional getter throws an Error or TypeError. Each property is resolved independently, so a failing value is omitted without hiding the remaining useful application details. Retain null filtering and caster output order, and add a regression that proves later virtual properties are still rendered after an earlier getter fails.
Remove the unused Contracts dependency and align the split package's direct external constraints with the monorepo root. Keep Database as the one optional package that enables documented Tinker behavior and preserve provider discovery metadata. Add focused metadata coverage so dependency constraints, the Database suggestion, and automatic provider discovery cannot drift. Complete return types in the neighboring provider tests while keeping their behavior unchanged.
Link the split package to Laravel Tinker, which remains its upstream source. Keep the README deliberately small so the Boost guide remains the single user-documentation surface.
Document one-shot execution and exit codes, positional includes, alias controls, custom casters, project trust, and Hypervel's process-forking limit in the same plain style as the surrounding Artisan guide. Keep the section focused on supported user behavior. It avoids internal listener details and does not document direct include execution until the required public PsySH lifecycle ships in a stable release.
Record the verified Tinker command, alias, caster, metadata, and documentation findings together with their final designs, performance limits, rejected alternatives, and regression coverage. Route the core audit and ledger to this work unit while keeping Tinker open for the one remaining release dependency: a stable PsySH version containing the public, exception-safe include lifecycle. Record the related upstream signal and full-run corrections without making them Hypervel completion gates.
…ss-lifecycle-parity # Conflicts: # docs/plans/2026-07-12-0900-framework-coroutine-state-lifecycle-audit.md # docs/plans/2026-07-12-0915-framework-coroutine-state-lifecycle-audit-ledger.md
Use PsySH dev-main while Hypervel 0.4 is under development and remove the obsolete local shell subclass from the final design. Drop completed upstream PR history, preserve the newer Tinker work already on 0.4, point the guide at its current location, and keep only the dependency behavior needed to finish implementation and validation.
Bring the branch onto the current framework while preserving the newer Tinker command lifecycle, optional configuration, configured casters, public model-appends access, and relocated documentation. Resolve the overlapping audit records without dropping later 0.4 work, and layer the existing Tinker correctness changes onto the newer source and test coverage.
Use PsySH's normal Shell for both direct and interactive execution now that the dependency owns include loading and paired signal cleanup. Remove the temporary local shell subclass, preserve exact exit codes, keep caller-owned Console policy unchanged, and retain disabled-command filtering. Point both manifests at PsySH dev-main until the required behavior has a stable release. Remove metadata that no longer reflects the dependency graph, register built-in casters without dead class checks, and cover includes, process state, nullable trust, command selection, and split-package metadata.
Exercise vendor exclusion through the loader without creating a permanent PHP class alias. Remove the unused classmap fixture so the test remains isolated in normal, reverse, and randomized execution order.
Explain one-shot execution, exit statuses, positional includes, alias controls, custom casters, and project trust in the Artisan guide. Record the user-visible no-fork difference in the package README while keeping detailed usage in the main documentation.
Record the final execution, include, alias, caster, metadata, and documentation design together with its focused regression coverage and performance limits. Mark the Tinker work complete after validation and review, while keeping the stable PsySH release requirement explicit as a Hypervel 0.4 release gate.
Use PsySH's prompt mode by default so Tinker does not silently execute .psysh.php from an unfamiliar working directory. The existing trust_project setting and all supported values remain available for applications that want a different policy. Keep the trusted include test explicit about its policy, add a regression proving non-interactive execution skips untrusted project configuration, and pin the shipped default in the provider test.
Explain how Tinker handles unfamiliar project configuration in interactive and non-interactive sessions. Show the supported environment override for trusted automation and the never mode for disabling local configuration. Record the intentional Laravel default difference in the package README and porting guide so applications that rely on .psysh.php know when to opt into always.
Add the approved project-trust finding and final treatment to the Tinker plan and audit ledger. Record the compatibility boundary, rejected alternatives, focused regression, and load-bearing old-default counterfactual. Also repair the malformed findings table cell and close the work unit after validation, self-review, and final review.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes Tinker's one-shot execution path and brings it onto PsySH's current include and signal lifecycles.
It also corrects alias boundaries, keeps caster failures local, removes stale package metadata, and completes the Tinker documentation.
Motivation
Tinker's direct execution path had several behaviors that differed from both its public options and current PsySH:
--execute=0and--execute=''opened the interactive shell instead of executing the supplied value;null;The alias loader also treated raw string prefixes as namespace and directory matches. A configured
App\Novaalias could matchApp\NovaThing, and a vendor path could match a sibling with the same prefix.Execution and PsySH
Direct and interactive execution now use PsySH's normal
Shell.PsySH loads configured includes at the outermost execution boundary, restores the caller's error handler after include failures, and pairs signal setup with cleanup. Hypervel keeps process forking disabled before the shell is created because
pcntl_forkis incompatible with Swoole.Every non-null
--executevalue selects direct execution. Requested exit codes are returned unchanged, ordinary failures return status 1, and the alias loader is unregistered on every exit path. Tinker no longer changes the Console application's exception policy.The PsySH dependency temporarily tracks
dev-mainbecause the required lifecycle changes have been merged but are not in a stable release yet. Hypervel 0.4 must move to the first compatible stable release before it ships.Aliases and casters
Configured aliases and exclusions are normalized once and matched as exact classes or real namespace descendants. Vendor exclusions require a real directory-child boundary.
Application presentation now contains failures per property, including native PHP errors, so one unavailable value does not hide the remaining application details.
The built-in Collection, HtmlString, Stringable, Model, ProcessResult, and Application casters are registered directly. Database and Process are already hard transitive dependencies through Foundation, so the old class checks and Database suggestion were misleading and have been removed. Application-defined casters still take precedence.
Documentation and metadata
The Artisan guide now covers:
The package README records the user-visible difference from Laravel and links back to its upstream source. Split-package metadata now matches the code and provider discovery is covered directly.
Performance and compatibility
These changes run only while starting or using the developer command. They add no request, queue, database, network, or worker hot-path work.
The final implementation removes the local shell subclass and two unnecessary autoload checks. It adds no locks, retries, polling, caches, context storage, or retained worker state.
Laravel-facing Tinker options and configuration remain compatible. Hypervel's coroutine execution and no-fork Swoole behavior remain intact.
Validation
The final tree passes formatting, both PHPStan configurations, Composer manifest validation, and the complete Tinker suite in normal and randomized order. Focused regressions cover direct execution, include loading and failure recovery, process-global cleanup, command filtering, alias boundaries, caster failures, nullable project trust, metadata, and coroutine execution.
For more details, see:
docs/plans/2026-08-09-0219-tinker-correctness-psysh-lifecycles-and-current-parity.mdSummary by CodeRabbit
New Features
--executemode now supports falsey values, preloaded files, and reliable exit statuses.Bug Fixes
Documentation