Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message
Agents
pentiminax/ux-driver
claude-code
cursor
onboarding
product-tour
symfony-ux
Driver.js

Welcome, AI assistant. Follow these guidelines when contributing to this repository.

Install
php artisan boost:add-skill pentiminax/ux-driver

Save this content to: AGENTS.md

# AI Contribution Guidelines

Welcome, AI assistant. Follow these guidelines when contributing to this repository.

## Project Overview

UX Driver is a third-party Symfony UX bundle that integrates [Driver.js](https://driverjs.com/) with
Symfony applications. It provides product tours, standalone highlights, and hints, authored either
with Twig Components, the `create_tour()` / `create_hints()` Twig builders, or the autowired PHP
builders.

**Requirements:** PHP 8.2+, Symfony 7.x/8.x, Symfony StimulusBundle 2.x/3.x, Symfony UX
TwigComponent 2.x/3.x, Twig 3.8+, Driver.js 1.8+

**PHP namespace:** `Pentiminax\UX\Driver\` maps to `src/`

**Test namespace:** `Pentiminax\UX\Driver\Tests\` maps to `tests/`

## General Rules

- Use American English for code, comments, documentation, commits, and branches.
- Use single quotes for PHP and TypeScript strings unless interpolation or escaping makes double
  quotes clearer.
- Keep changes focused, reviewable, and backward compatible.
- Treat popover titles and descriptions as a security boundary. Driver.js writes them with
  `innerHTML`, so they are escaped in PHP by `Html\PopoverContent`. Never bypass that treatment,
  and keep `Twig\Markup` / `ux_driver_html()` as the only opt-out for trusted markup.
- Keep the three authoring modes behaviorally identical. A feature added to Twig Components,
  Twig builders, or PHP builders must produce the same serialized payload in the others.
- Add dependencies only when the task explicitly requires them.

### Do Not Edit Directly

- `vendor/`, any `node_modules/` directory, and `var/` are managed dependencies or runtime output.
- `docs/dist/` and `docs/.astro/` are generated by Astro.
- `assets/dist/` is generated but versioned. Change `assets/src/`, then rebuild it with
  `npm run build` from `assets/`; never hand-edit compiled files or source maps. CI enforces this
  with `git diff --exit-code dist`.
- Update lock files only through their package manager. Keep the tracked `docs/package-lock.json`
  and `assets/package-lock.json` synchronized with their `package.json`.

## Architecture

### Core Data Flow

```text
Twig Components
  twig:Driver:Tour / twig:Driver:Step
  -> Twig\Components\* + templates/components/*.html.twig
  -> data-tour-* attributes (PopoverContent escaping)
  -> Stimulus controller (assets/src/controller.ts)
  -> driver.js

Builders (Twig create_tour() / PHP TourBuilder)
  -> Model\Tour + Model\Step
  -> UXDriverExtension::renderTour() + stimulus.helper
  -> serialized steps and options values
  -> Stimulus controller (assets/src/controller.ts)
  -> driver.js

Hints
  twig:Driver:Hints / create_hints() / HintsBuilder
  -> Model\Hints + Model\Hint
  -> assets/src/hints-controller.ts + hint-utils.ts
  -> driver.js/hints
```

Declarative tours collect their steps from Stimulus `step` targets in DOM order; builder-driven
tours embed the whole step list in the serialized `steps` value. Both paths converge on the same
Stimulus controller and the same driver.js configuration.

### Main Boundaries

- **User configuration** (`src/Model/`, `src/Builder/`, `src/Enum/`): `Tour`, `Step`, `Hints`,
  `Hint`, the fluent builders, and the option enums are the primary user-facing surface.
- **Twig integration** (`src/Twig/`, `templates/`): the Twig functions, the four Twig Components,
  and their templates. `UXDriverExtension` is the single place where Stimulus attributes are
  produced.
- **HTML safety** (`src/Html/PopoverContent.php`): the one treatment point for popover content in
  both authoring modes.
- **Bundle wiring** (`src/DriverBundle.php`, `config/services.php`, `config/reference.php`):
  services are registered explicitly; no implicit autowiring assumptions.
- **Frontend** (`assets/src/`): the tour controller, the hints controller, and their pure utility
  modules (`tour-utils.ts`, `hint-utils.ts`) which hold the persistence and resolution logic.

### Public API and Backward Compatibility

Treat documented entry points and downstream-consumed behavior as public contracts. This includes
`Tour`, `Step`, `Hints`, `Hint`, `TourBuilder`, `HintsBuilder`, the enums, the Twig functions
(`create_tour`, `ux_tour`, `ux_tour_action`, `ux_highlight`, `create_hints`, `ux_hints`,
`ux_hints_action`, `ux_driver_html`), the `Driver:*` component keys and their props, the emitted
`data-*` attribute names, the serialized frontend values, the dispatched Stimulus events, and the
published JavaScript entrypoints declared in `assets/package.json`.

- Prefer additive, backward-compatible changes.
- Deprecate an existing path before removing it, and document its replacement.
- Do not expose internal runtime objects or implementation details through user configuration.
- Keep fluent configuration consistent: chainable methods returning `static` or the model itself.
- Consider payload shape and the Stimulus values contract when changing PHP or TypeScript APIs.
- Keep `peerDependencies` and `symfony.importmap` driver.js ranges aligned; `tests/PackageMetadataTest.php`
  asserts it.
- Keep stylesheets out of the built controllers; they travel through the StimulusBundle
  `autoimport` declaration, as asserted by `tests/AssetsDistTest.php`.

## Commands

Use the repository manifests and CI workflows as the source of truth.

### Setup

```bash
composer install

cd assets
npm install

cd ../docs
npm ci
```

### PHP

```bash
composer audit
composer fix
composer analyse
vendor/bin/phpunit
vendor/bin/phpunit tests/Model/TourTest.php
vendor/bin/phpunit --filter=test_name
```

`composer fix` rewrites PHP files. Review its diff before committing.

### Frontend

Run from `assets/`:

```bash
npm run typecheck
npm test
npm run build
```

### Documentation

Run from `docs/`:

```bash
npm run check
npm run build
npm run test:build
```

### Before Creating a Pull Request

Run the relevant checks for every changed area:

| Changed area | Required checks |
| --- | --- |
| PHP source, config, or tests | `composer fix`, `composer audit`, `composer analyse`, `vendor/bin/phpunit` |
| TypeScript or frontend tests | `npm run typecheck`, `npm test`, `npm run build` in `assets/`, then commit `assets/dist/` |
| Twig templates or serialized payloads | Relevant PHPUnit tests and affected frontend tests |
| Astro/MDX documentation | `npm run check`, `npm run build`, `npm run test:build` in `docs/` |
| Contribution documentation | `git diff --check` and a manual diff review |

## PHP Code Standards

PHP-CS-Fixer (`.php-cs-fixer.dist.php`) is the formatting source of truth. Its rules include PSR-12,
Symfony conventions, strict types, single quotes, ordered imports, native function invocation, and
snake_case PHPUnit method names. PHPStan runs at level 8 over `src/` and `tests/`.

- Add `declare(strict_types=1);` to PHP files.
- Use PHP 8.2+ syntax and native types. Prefer constructor property promotion where it improves
  clarity. Do not use syntax that PHP 8.2 does not support.
- Register bundle services explicitly in `config/services.php`; do not introduce implicit
  autowiring assumptions.
- Prefer enums over groups of constants for closed sets of values, as `src/Enum/` already does.
- Return or throw early instead of nesting control flow.
- Handle exceptions explicitly; never add silent catches.
- Start exception messages with a capital letter and end them with a period.
- Add comments only for non-obvious constraints or decisions. Do not use comments as section
  separators.
- Keep properties before methods, then order methods public, protected, and private.
- Use PHPDoc for useful generic, iterable, array-shape, or behavioral information; PHPStan level 8
  relies on the declared array shapes. Avoid repeating native type declarations.

## TypeScript and Frontend Standards

- Use TypeScript and ES modules; `assets/src/` compiles to `assets/dist/` with `tsc`.
- Use 4-space indentation and single quotes, matching the existing controllers.
- Use `camelCase` for variables and functions and `UpperCamelCase` for classes and types.
- Import driver.js types rather than redeclaring them; when driver.js does not export a type,
  derive it from the public signature as `controller.ts` does for `HookOpts`.
- Keep controllers thin: resolution, persistence, and pure logic belong in `tour-utils.ts` and
  `hint-utils.ts`, which is where they are unit tested.
- Guard `localStorage` access; persistence must never break a tour when storage is unavailable.
- Add or update Vitest coverage for behavior changes.
- Rebuild and commit `assets/dist/` whenever published frontend source changes.

## Twig and Components

- Keep Twig auto-escaping enabled. Use raw HTML only when the value is intentionally trusted and
  already passed through `PopoverContent` or `ux_driver_html()`.
- Use semantic HTML, labels, and appropriate `aria-*` attributes for interactive controls.
- Emit Stimulus attributes through `stimulus.helper` and the `ux_tour_action()` /
  `ux_hints_action()` helpers instead of hardcoding controller identifiers in templates.
- Reuse the existing component templates before adding new variants.
- Keep component props aligned with the matching model setters so both authoring modes accept the
  same option names.

## Documentation

Documentation lives in `docs/` and uses Astro with MDX.

- Write concise American English for an international audience.
- Prefer realistic Symfony and driver.js examples over placeholder code.
- Include imports and relevant configuration context in code examples.
- Show the authoring modes consistently: Twig Component, Twig builder, and PHP builder.
- Keep security-sensitive examples aligned with the documented escaping boundary.
- Nav and section order come from the content collection frontmatter `order`; do not reintroduce a
  hand-maintained navigation list.
- Keep each subject on a single home page and link to it from the others instead of duplicating
  version matrices, event lists, or option tables.
- Keep `README.md` and the docs site in sync on requirements and supported ranges.

## Git and Pull Requests

- Keep commits small and focused on one decision.
- Lead the commit message with intent, then record meaningful constraints, rejected alternatives,
  and verification.
- Document completed checks with `Tested:` and any known gaps with `Not-tested:`.
- Do not introduce a project-specific branch naming scheme in this file.

AI Contribution Guidelines

Welcome, AI assistant. Follow these guidelines when contributing to this repository.

Project Overview

UX Driver is a third-party Symfony UX bundle that integrates Driver.js with Symfony applications. It provides product tours, standalone highlights, and hints, authored either with Twig Components, the create_tour() / create_hints() Twig builders, or the autowired PHP builders.

Requirements: PHP 8.2+, Symfony 7.x/8.x, Symfony StimulusBundle 2.x/3.x, Symfony UX TwigComponent 2.x/3.x, Twig 3.8+, Driver.js 1.8+

PHP namespace: Pentiminax\UX\Driver\ maps to src/

Test namespace: Pentiminax\UX\Driver\Tests\ maps to tests/

General Rules

  • Use American English for code, comments, documentation, commits, and branches.
  • Use single quotes for PHP and TypeScript strings unless interpolation or escaping makes double quotes clearer.
  • Keep changes focused, reviewable, and backward compatible.
  • Treat popover titles and descriptions as a security boundary. Driver.js writes them with innerHTML, so they are escaped in PHP by Html\PopoverContent. Never bypass that treatment, and keep Twig\Markup / ux_driver_html() as the only opt-out for trusted markup.
  • Keep the three authoring modes behaviorally identical. A feature added to Twig Components, Twig builders, or PHP builders must produce the same serialized payload in the others.
  • Add dependencies only when the task explicitly requires them.

Do Not Edit Directly

  • vendor/, any node_modules/ directory, and var/ are managed dependencies or runtime output.
  • docs/dist/ and docs/.astro/ are generated by Astro.
  • assets/dist/ is generated but versioned. Change assets/src/, then rebuild it with npm run build from assets/; never hand-edit compiled files or source maps. CI enforces this with git diff --exit-code dist.
  • Update lock files only through their package manager. Keep the tracked docs/package-lock.json and assets/package-lock.json synchronized with their package.json.

Architecture

Core Data Flow

Twig Components
  twig:Driver:Tour / twig:Driver:Step
  -> Twig\Components\* + templates/components/*.html.twig
  -> data-tour-* attributes (PopoverContent escaping)
  -> Stimulus controller (assets/src/controller.ts)
  -> driver.js

Builders (Twig create_tour() / PHP TourBuilder)
  -> Model\Tour + Model\Step
  -> UXDriverExtension::renderTour() + stimulus.helper
  -> serialized steps and options values
  -> Stimulus controller (assets/src/controller.ts)
  -> driver.js

Hints
  twig:Driver:Hints / create_hints() / HintsBuilder
  -> Model\Hints + Model\Hint
  -> assets/src/hints-controller.ts + hint-utils.ts
  -> driver.js/hints

Declarative tours collect their steps from Stimulus step targets in DOM order; builder-driven tours embed the whole step list in the serialized steps value. Both paths converge on the same Stimulus controller and the same driver.js configuration.

Main Boundaries

  • User configuration (src/Model/, src/Builder/, src/Enum/): Tour, Step, Hints, Hint, the fluent builders, and the option enums are the primary user-facing surface.
  • Twig integration (src/Twig/, templates/): the Twig functions, the four Twig Components, and their templates. UXDriverExtension is the single place where Stimulus attributes are produced.
  • HTML safety (src/Html/PopoverContent.php): the one treatment point for popover content in both authoring modes.
  • Bundle wiring (src/DriverBundle.php, config/services.php, config/reference.php): services are registered explicitly; no implicit autowiring assumptions.
  • Frontend (assets/src/): the tour controller, the hints controller, and their pure utility modules (tour-utils.ts, hint-utils.ts) which hold the persistence and resolution logic.

Public API and Backward Compatibility

Treat documented entry points and downstream-consumed behavior as public contracts. This includes Tour, Step, Hints, Hint, TourBuilder, HintsBuilder, the enums, the Twig functions (create_tour, ux_tour, ux_tour_action, ux_highlight, create_hints, ux_hints, ux_hints_action, ux_driver_html), the Driver:* component keys and their props, the emitted data-* attribute names, the serialized frontend values, the dispatched Stimulus events, and the published JavaScript entrypoints declared in assets/package.json.

  • Prefer additive, backward-compatible changes.
  • Deprecate an existing path before removing it, and document its replacement.
  • Do not expose internal runtime objects or implementation details through user configuration.
  • Keep fluent configuration consistent: chainable methods returning static or the model itself.
  • Consider payload shape and the Stimulus values contract when changing PHP or TypeScript APIs.
  • Keep peerDependencies and symfony.importmap driver.js ranges aligned; tests/PackageMetadataTest.php asserts it.
  • Keep stylesheets out of the built controllers; they travel through the StimulusBundle autoimport declaration, as asserted by tests/AssetsDistTest.php.

Commands

Use the repository manifests and CI workflows as the source of truth.

Setup

composer install

cd assets
npm install

cd ../docs
npm ci

PHP

composer audit
composer fix
composer analyse
vendor/bin/phpunit
vendor/bin/phpunit tests/Model/TourTest.php
vendor/bin/phpunit --filter=test_name

composer fix rewrites PHP files. Review its diff before committing.

Frontend

Run from assets/:

npm run typecheck
npm test
npm run build

Documentation

Run from docs/:

npm run check
npm run build
npm run test:build

Before Creating a Pull Request

Run the relevant checks for every changed area:

Changed area Required checks
PHP source, config, or tests composer fix, composer audit, composer analyse, vendor/bin/phpunit
TypeScript or frontend tests npm run typecheck, npm test, npm run build in assets/, then commit assets/dist/
Twig templates or serialized payloads Relevant PHPUnit tests and affected frontend tests
Astro/MDX documentation npm run check, npm run build, npm run test:build in docs/
Contribution documentation git diff --check and a manual diff review

PHP Code Standards

PHP-CS-Fixer (.php-cs-fixer.dist.php) is the formatting source of truth. Its rules include PSR-12, Symfony conventions, strict types, single quotes, ordered imports, native function invocation, and snake_case PHPUnit method names. PHPStan runs at level 8 over src/ and tests/.

  • Add declare(strict_types=1); to PHP files.
  • Use PHP 8.2+ syntax and native types. Prefer constructor property promotion where it improves clarity. Do not use syntax that PHP 8.2 does not support.
  • Register bundle services explicitly in config/services.php; do not introduce implicit autowiring assumptions.
  • Prefer enums over groups of constants for closed sets of values, as src/Enum/ already does.
  • Return or throw early instead of nesting control flow.
  • Handle exceptions explicitly; never add silent catches.
  • Start exception messages with a capital letter and end them with a period.
  • Add comments only for non-obvious constraints or decisions. Do not use comments as section separators.
  • Keep properties before methods, then order methods public, protected, and private.
  • Use PHPDoc for useful generic, iterable, array-shape, or behavioral information; PHPStan level 8 relies on the declared array shapes. Avoid repeating native type declarations.

TypeScript and Frontend Standards

  • Use TypeScript and ES modules; assets/src/ compiles to assets/dist/ with tsc.
  • Use 4-space indentation and single quotes, matching the existing controllers.
  • Use camelCase for variables and functions and UpperCamelCase for classes and types.
  • Import driver.js types rather than redeclaring them; when driver.js does not export a type, derive it from the public signature as controller.ts does for HookOpts.
  • Keep controllers thin: resolution, persistence, and pure logic belong in tour-utils.ts and hint-utils.ts, which is where they are unit tested.
  • Guard localStorage access; persistence must never break a tour when storage is unavailable.
  • Add or update Vitest coverage for behavior changes.
  • Rebuild and commit assets/dist/ whenever published frontend source changes.

Twig and Components

  • Keep Twig auto-escaping enabled. Use raw HTML only when the value is intentionally trusted and already passed through PopoverContent or ux_driver_html().
  • Use semantic HTML, labels, and appropriate aria-* attributes for interactive controls.
  • Emit Stimulus attributes through stimulus.helper and the ux_tour_action() / ux_hints_action() helpers instead of hardcoding controller identifiers in templates.
  • Reuse the existing component templates before adding new variants.
  • Keep component props aligned with the matching model setters so both authoring modes accept the same option names.

Documentation

Documentation lives in docs/ and uses Astro with MDX.

  • Write concise American English for an international audience.
  • Prefer realistic Symfony and driver.js examples over placeholder code.
  • Include imports and relevant configuration context in code examples.
  • Show the authoring modes consistently: Twig Component, Twig builder, and PHP builder.
  • Keep security-sensitive examples aligned with the documented escaping boundary.
  • Nav and section order come from the content collection frontmatter order; do not reintroduce a hand-maintained navigation list.
  • Keep each subject on a single home page and link to it from the others instead of duplicating version matrices, event lists, or option tables.
  • Keep README.md and the docs site in sync on requirements and supported ranges.

Git and Pull Requests

  • Keep commits small and focused on one decision.
  • Lead the commit message with intent, then record meaningful constraints, rejected alternatives, and verification.
  • Document completed checks with Tested: and any known gaps with Not-tested:.
  • Do not introduce a project-specific branch naming scheme in this file.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle