Download the PHP package byjesper/laravel-decision-support without Composer

On this page you can find all versions of the php package byjesper/laravel-decision-support. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package laravel-decision-support

Laravel Decision Support

Read-only, DB-backed decision-support guide engine for Laravel — graph-first, with a resumable evaluator, structured & expression conditions, publish-time validation, and Mermaid rendering.

A decision-support guide is a directed graph that asks questions, resolves domain facts, branches on conditions, and ends in an outcome (a verdict plus reasoning and warnings). This package is the engine that evaluates such guides. It is deliberately read-only: it advises, it does not act — no status mutations, no jobs, no writes to your data. Side effects belong in your application, wired through events.

It is built graph-first with a resumable interpreter, so a run can pause to ask the user something and resume later from a serialized state — perfect for a Livewire wizard, an API, or a fully headless/offline evaluation.

Looking for the in-app tree editor and runner UI? That ships separately as byjesper/laravel-decision-support-filament (built on this engine).

Requirements

Installation

The service provider is auto-discovered. Publish the config and/or migrations if you need them:

The package also loads its migrations automatically, so for app-internal use you can just run php artisan migrate without publishing them.

Concepts at a glance

Concept What it is
Node type A kind of node the engine can evaluate. Built-ins: question, fact, decision, outcome. Custom types are registered by hosts.
Fact provider The developer-owned boundary. Declares the vocabulary of facts a guide may branch on, and resolves them at run time. One per guide.
Condition An edge guard: structured (fact + operator + value) by default, or an expression (symfony/expression-language) as an advanced escape hatch.
Guide definition The immutable, runtime-facing snapshot of a guide (nodes + edges + entry). The runner only ever reads this.
Run state A serializable value object capturing where a run is: current node, status, answers/facts, reached path, pending interaction, or final outcome.
Profile A publish-time shape constraint: phased (questions → facts → decisions → outcomes) or freeform.

Quick start (headless)

Everything below works without a database or UI — ideal for tests and code-authoring consumers.

1. Implement a fact provider

Register it (one provider per guide key) in a service provider's boot():

2. Author a guide

GuideBuilder assembles a definition fluently. The entry node defaults to the first node added.

3. Run it

start() and advance() drive the run forward through automatic nodes (fact, decision, outcome) and only hand control back when they need input (a suspension) or finish (an outcome).

Persisting a run across requests

RunState is a plain serializable value object — store it anywhere:

Required (mandatory) questions

A free-input question (text, date, number) can be marked required so a run cannot advance past it on a blank answer:

The flag rides on the suspension, so a host UI can react (e.g. show a validation message):

When a required question is answered with a null/whitespace value the interpreter re-suspends on the same node instead of routing an empty value onward. It is ignored for boolean/select, which are always answered by the choice itself.

Multi-language content

Guide content — an outcome's verdict/text/warnings, a question's prompt, and select-option labels — can be authored in several languages. Keep the plain string field as the source/default language and add an optional sibling *_i18n map keyed by locale:

The engine is framework-agnostic, so you tell it the locale rather than it reading app()->getLocale(). Pass an active locale (and an optional fallback) to start(); it is carried on the run and survives serialization:

Resolution is *_i18n[$locale] ?? *_i18n[$fallbackLocale] ?? <base string>. With no locale (the default) the base strings are used — fully backward compatible.

Conditions

Edges are guarded by conditions. The default is structured; expressions are opt-in and sandboxed to the fact vocabulary.

Operators: =, !=, >, >=, <, <=, in, not_in, is_true, is_false.

A decision node emits a single out port and lets its outgoing edges decide the target: the first matching condition wins, with an always edge as the default. Provide a default or unknown branch so unresolved facts always route somewhere.

Working with the database

Model a guide as Guide → GuideVersion → GuideNode/GuideEdge, then validate and publish a draft. Publishing freezes the draft rows into the immutable definition snapshot and points the guide's active_version_id at it.

Extra attributes (consumer metadata)

Both Guide and GuideVersion carry a nullable extra_attributes JSON column (cast to array) for arbitrary consumer-defined metadata — the headline use case is the permissions required to see or run a guide:

The guide-level copy is the source of truth. The version-level copy is an editable working copy that travels with a version; publishing seeds the guide's copy from the version that becomes active (alongside active_version_id). An admin may also edit the guide copy directly between publishes, and that edit takes effect immediately.

The engine stores and copies these attributes but enforces nothing — gating is the host's job. Read them from your Guide policy:

Publish validation

PublishValidator rejects a draft loudly rather than letting a broken guide reach the runtime. It checks:

Safety rails

The runtime never throws on bad guide data. Exactly one termination rail is active per profile:

An unknown outcome ($state->outcome->unknown === true) signals a rail fired, with the reason in its text/warnings.

Free-form (cyclic) guides

A guide whose profile implements SupportsCycles may contain cycles — e.g. loop back and re-ask a question. The freeform profile ships with this. Re-entering an already-answered question re-asks it (the run re-suspends and the new answer overwrites the stored one); a cycle through only fact/decision nodes re-evaluates identical state each lap and will spin until the step budget, so a useful loop must pass through a question.

Rendering a diagram

MermaidRenderer is a pure function from a definition (plus an optional run state) to Mermaid flowchart source — the same renderer powers an editor preview and a runner view. Pass a RunState to highlight the reached path.

Node text is localized through the same locale chain as the runner (locale → fallback → base). A run state carries its own locale, so a highlighted diagram localizes automatically; for a diagram with no run state (e.g. a pre-start preview) pass the locale explicitly:

Each node resolves its display text from an explicit label (with an optional label_i18n map) first, then the type's content field (prompt/prompt_i18n for a question, verdict/verdict_i18n for an outcome, the fact name for a fact/decision), then the node key. GuideBuilder::fact()/decision() take an optional $label and $labelI18n so authored graphs show friendly labels instead of raw keys.

Edge labels follow the same rule: by default an edge shows its derived condition/port text (tenure >= 5, else, a boolean port…), but giving the edge a label (and optional labelI18n) overrides that with humanised, localized text. GuideBuilder::edge() accepts $label/$labelI18n.

Extending the engine

Register everything on the DecisionSupportManager (typically in boot()):

A custom node type implements ByJesper\DecisionSupport\Contracts\NodeType and returns NodeResult::advance(), ::suspend(), or ::terminate() from evaluate() — that is all the engine needs to fold it into the same resumable loop as the built-ins. Its configSchema() drives the Filament editor form; each field may include an optional help string the editor renders as hint text (the engine itself does not interpret the schema).

Events (host seams)

The engine emits events instead of depending on your audit/authorization stack. Listen to these to wire side effects:

Event When Dispatched by
GuideRunStarted A run begins (carries the initial RunState). the engine (GuideRunner)
GuidePublished A version is published. the engine (GuidePublisher)
GuideDrafted A draft version is created. the engine, via a GuideVersion model observer — fires for any writer (editor, seeder, artisan)
NodeChanged A node is edited. editors (e.g. the Filament package) — core has no editing code path, so it cannot honestly fire this

Testing your guides

The package ships first-class test helpers (no DB, no editor required):

Helpers: decisionRunner(), assertReachesOutcome(), assertReachesUnknown(), assertSuspendsForQuestion(), plus FakeFactProvider (->with(), ->pending(), ->declare()) and GuideBuilder. Outside PHPUnit, GuideTester exposes the same helpers as a standalone object.

Laravel Boost

This package ships a Laravel Boost skilldecision-support-development (resources/boost/skills/decision-support-development/SKILL.md). When a consuming app runs php artisan boost:install (or boost:update --discover), Boost offers to install it. It is loaded on-demand — only when the agent is actually authoring guides, fact providers, node types, or conditions — so it adds no upfront context cost to apps that aren't touching this engine.

Testing

This runs the full gate: guideline check, lint (Pint + Rector), static analysis (Larastan level 8), 100% type coverage, and the unit, parallel, and integration suites. Database-bound tests are tagged ->group('integration') and run against an in-memory SQLite connection.

License

The MIT License (MIT). See LICENSE.md.


All versions of laravel-decision-support with dependencies

PHP Build Version
Package Version
Requires php Version ^8.4
illuminate/contracts Version ^13.0
illuminate/support Version ^13.0
symfony/expression-language Version ^7.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package byjesper/laravel-decision-support contains the following files

Loading the files please wait ...