php artisan larecipe:sync runs a docs agent inside your Laravel app, on your own AI provider key, when you ask for it. It does the job your coding agent does before a push: it finds the pages a change affected and updates them. Reach for it when:
- you want an audit of a whole doc set, not only the pages one change touched;
- a developer has no local coding agent, and wants a draft of the docs update for their branch;
- you edit a production database set outside a pull request.
It is not the default writer. Your coding agent is, because it has the full context of the change it made a moment ago. See how it works.
Run it
It is built on laravel/ai. Install that and add your provider key to .env the way laravel/ai expects:
composer require laravel/ai
php artisan vendor:publish --provider="Laravel\Ai\AiServiceProvider"Then run it on your branch. It updates the pages your branch affects compared with the default branch, uncommitted work included:
php artisan larecipe:syncIt prints its plan first (the set, the task, the change it reads, the provider and model, the budget, where its writes land and the pages it will work on) and asks before it spends a token. On a repository set, the result is edited Markdown files in your working tree, uncommitted, for you to review with git diff.
There is no LaRecipe service in between and no credit meter: a run costs the tokens your provider charges you.
Tell it what to work on
php artisan larecipe:sync --base=origin/main --head=HEAD
php artisan larecipe:sync --page=billing/refunds --page=billing/webhooks
php artisan larecipe:sync --audit --dry-run--baseand--headgive it a range, the same way aslarecipe:affected.--pagenames the pages yourself, once per page, as a page path or its file.--auditreviews the whole version: the pages whose sources changed after them first, then the ones withoutsources:, then the rest.--dry-runreports what the agent would change and writes nothing. Start an audit with it.--set,--docs-versionand--localepick another doc set, version or language. Without them, it works on the default set, version and language.--yesskips the question. Without a terminal to ask, it runs only with--yes.
On demand only, never in CI
larecipe:sync runs when a person runs it: on a developer's machine, or as a queued job with --queue. It is never a CI default. The CI check LaRecipe scaffolds runs no AI agent, pushes nothing, commits nothing, needs no secrets, and never calls larecipe:sync. Inside a repository, whatever it writes still rides in the branch with the code.
Details
Where its changes go, and --commit
| Your set | What it writes |
|---|---|
| Repository | Edits to the Markdown files in your working tree, uncommitted, for you to review with git diff. |
| Database, inside a git repository | The change is applied to your local database and written into the branch's docs migration in database/migrations/docs/, for you to review and commit with the code. |
| Database, with no git repository around it (a queue worker on production) | Changes to the set itself, under its review mode: drafts under review: required, published revisions under review: auto. |
Database, with --remote |
Changes to the production set, through its authenticated remote author tools. Drafts under review: required, published revisions under review: auto. |
--commit commits the docs changes to the current branch for you:
php artisan larecipe:sync --commitIt commits only the files the agent wrote, with a message that lists each page and names the agent in a Co-Authored-By trailer. You still push, so the docs travel with the code. It refuses to start when those docs files already have uncommitted changes, it cannot be combined with --dry-run, and it only works where the change rides in the branch.
Edit a production database set with --remote
php artisan larecipe:sync --remote=https://acme.dev/handbook/mcp--remote works outside any pull request, so the set's review mode decides what goes live. It needs ai.sync.remote_token (LARECIPE_SYNC_TOKEN): a token the remote app accepts on its MCP endpoint, such as a Sanctum token, of a user its manageLarecipe gate allows. The production set must have its web author tools turned on (see review modes). A repository set refuses --remote, because its changes belong in git.
Settings
Pick the provider and model in config/larecipe.php:
// config/larecipe.php
'ai' => [
'sync' => [
'provider' => env('LARECIPE_AI_PROVIDER'),
'model' => env('LARECIPE_AI_MODEL'),
'max_pages' => 20,
'max_steps' => 30,
'timeout' => 120,
'remote_token' => env('LARECIPE_SYNC_TOKEN'),
'deny' => [],
'queue' => env('LARECIPE_SYNC_QUEUE'),
],
],| Key | Controls |
|---|---|
provider |
A provider name from config/ai.php. Empty uses laravel/ai's default provider. |
model |
The model. Empty uses the provider's default model. |
max_pages |
How many pages one run may change. |
max_steps |
How many steps the agent may take in one run. |
timeout |
Seconds per provider request. |
remote_token |
The token a --remote run sends to a production set's MCP endpoint. |
deny |
Paths or globs the agent may never read, on top of the built-in list. |
queue |
The queue for --queue runs. Empty uses your default queue. |
ai.sync.provider and ai.sync.model read the same environment variables as Ask AI, so one provider serves both unless you set them apart.
Before it plans anything, the command checks that laravel/ai is installed, that the provider exists in config/ai.php and has a key, and, for --remote, that remote_token is set. When something is missing, it stops and says exactly what to install or set. Keys are only checked for presence; their values are never printed.
Budgets, providers and queued runs
Every run is bounded. ai.sync.max_pages and ai.sync.max_steps set the defaults, and you can change them for one run. Pages over the budget are listed in the plan and in the report as not done. The page budget limits what an audit may change, not what it may read.
php artisan larecipe:sync --audit --max-pages=5 --max-steps=40--provider and --model pick another provider or model for one run, the same way.
By default the run happens in your terminal, and it ends with what changed, the agent's summary and anything it could not do. With --queue, the run is an ordinary queued job instead, with one attempt: you can follow it in Horizon or Nightwatch, and its report goes to your log. In tests, fake it like any other laravel/ai agent, with DocsMaintainer::fake().
The agent and its tools
The agent is DocsMaintainer, a laravel/ai agent. Because it runs inside your booted app, it writes from what the app actually does, not only from the text in the repository. It follows the same workflow your coding agent does: the larecipe-update-docs skill, or larecipe-audit-docs for an audit.
| Tool | What it does |
|---|---|
search_docs, read_page, list_pages |
Search and read the docs, as any MCP client would. |
read_page_source |
A page's frontmatter and Markdown as written, with its content hash, so the agent edits the real source and never overwrites a newer edit. |
affected_pages |
The same check as larecipe:affected: the pages a change made stale. |
read_code, git_diff |
Read files and diffs in the project, read-only. |
app_reference |
Routes, artisan commands, model schemas and events, the way live references read them. Never configuration or environment values. |
validate_docs |
The larecipe:validate report, to fix what the agent wrote. |
| The author tools | write_page, move_page, delete_page, update_navigation and update_manifest, the same tools your coding agent uses, so validation, docs migrations and the review mode apply exactly as they do to every other writer. |
Every tool is bound to the run's doc set, version and language. read_code and git_diff never leave the project, and they never open the files that may hold configuration, environment values or secrets: the same list snippet includes refuse, described in code blocks. git_diff names such a file without showing it. ai.sync.deny adds paths to the list; nothing can take paths off it.
The page budget and dry runs are enforced in code, in front of the author tools, so a confused model cannot write past them.
Next
- Review modes: drafts and published revisions for changes outside a pull request.
- Docs migrations: how a database set's changes travel in the pull request.
- Artisan commands: every option, read from the running app.