andreapollastri/larapilot

Spec-driven AI product workflow for Laravel โ€” discovery, backlog, planning, implementation, and review via Laravel Boost.

Maintainers

Package info

github.com/andreapollastri/larapilot

pkg:composer/andreapollastri/larapilot

Transparency log

Statistics

Installs: 222

Dependents: 0

Suggesters: 0

Stars: 8

Open Issues: 0

2.3.2 2026-07-31 21:30 UTC

This package is auto-updated.

Last update: 2026-07-31 21:31:29 UTC


README

From product idea to reviewed Laravel code โ€” with an AI product team that follows a real process.

Larapilot is a spec-driven workflow for Laravel projects, integrated with Laravel Boost. Install the package, run /larapilot-* skills in your AI editor, and ship backlog artifacts, plans, and reviewed code from .larapilot/.

The agent proposes. You approve what ships. Human-in-the-loop, always.

๐Ÿ“– Documentation: larapilot.web.ap.it ยท Walkthrough ยท API

Why Larapilot

AI agents are fast, but isolated prompts are not a product process. Larapilot gives your assistant a disciplined squad โ€” discovery โ†’ backlog โ†’ plan โ†’ implement โ†’ review โ†’ ship โ€” with 27 personas (Mark, John, Alex, Anne, โ€ฆ) as review lenses, not costumes.

Each skill orchestrates the conversation. Artisan commands persist state; Boost skills drive the workflow in chat; MCP exposes Laravel context and workflow tools to your editor.

Core loop

Greenfield โ€” repeat steps 3โ€“5 per user story:

/larapilot-inception "โ€ฆ"  โ†’  /larapilot-spec  โ†’  /larapilot-plan US-XXX
  โ†’  /larapilot-implement US-XXX  โ†’  /larapilot-review US-XXX
When Start with
New product, pivot, or legacy rewrite /larapilot-inception
One new capability on an existing product /larapilot-feature "โ€ฆ"
Defect or regression /larapilot-bug "โ€ฆ"

Optional: /larapilot-design before plan ยท /larapilot-ship when MVP stories are DONE ยท /larapilot-autopilot to batch plan + implement ยท /larapilot-settings for project effort / backlog granularity / git / testing modes ยท /larapilot-backstage to publish the repo into a Backstage developer portal.

Git discipline follows settings.git_mode (default Gitflow without auto-push): one feature/US-XXX-* branch per story, atomic commits per plan task; push + remote PR only when mode is GITFLOW_PUSH. Configure with /larapilot-settings. Details on the docs site.

What lands in .larapilot/

Path Purpose
config.yaml Project workflow config + settings (effort, backlog, git_mode, testing, auto_approve)
docs/PRD.md Product Requirements Document
backlog/ User stories (US-XXX) with status machine
plans/ Technical plans and tasks per spec
mockups/{spec}/ Static HTML previews (optional)
internal-feedback/{code}.md PM/dev comments until DONE
design-systems/ Packaged references (Filament, Starter Kit, Bootstrap 5, Tailwind, AdminLTE)
techdocs/ Generated Backstage TechDocs sources (only after larapilot:backstage-export --write)

Skills write artifacts; the workflow engine blocks invalid state transitions (e.g. implement before plan, approve before review, approve with open [blocks-merge] feedback or unfinished tasks โ€” override with --force).

Two configuration layers

Layer File Owns Changed via
Laravel config config/larapilot.php (publishable) + .env Environment toggles: routes, environments, diagnostics, LARAPILOT_API_TOKEN, package defaults php artisan vendor:publish --tag=larapilot-config, env vars
Project workflow .larapilot/config.yaml (committed) Per-project settings (effort, backlog, git mode, testing, auto-approve), paths, statuses /larapilot-settings or php artisan larapilot:settings-set

The YAML wins for workflow settings; Laravel config only provides their defaults on first install.

Skills

Published via Laravel Boost after php artisan boost:install:

Skill Role
/larapilot-inception Product discovery โ†’ PRD (includes Frontend Topology)
/larapilot-spec MoSCoW backlog from PRD
/larapilot-feature Mini-inception for one evolutiva
/larapilot-bug Bug triage โ†’ fix spec or rework
/larapilot-frontend-companion Link external FE repo path, scan code โ€” from Laravel only
/larapilot-design Static HTML mockups from design system
/larapilot-plan Technical plan + tasks for a spec
/larapilot-implement Code + tests on a feature branch
/larapilot-review Human gate โ†’ DONE or rework
/larapilot-ship Release checklist when MVP is done
/larapilot-autopilot Batch plan + implement
/larapilot-settings Persist effort / backlog granularity / git mode / testing / auto-approve for the project
/larapilot-backstage Publish the repo into a Backstage developer portal (catalog entity + TechDocs)
/larapilot-tracker Mirror the backlog into Linear ยท Asana ยท Jira ยท Trello ยท ClickUp ยท Monday

During inception, John + Joe ask Frontend Topology: Laravel-coupled, SPA-in-Laravel, or API + external frontend. For split-repo: larapilot:frontend-set --path=โ€ฆ, then frontend-scan โ€” all from Laravel. Details: Frontend companion.

Dashboard & API (dev/staging)

When the dashboard is browsable (never in production):

  • /larapilot โ€” Kanban board, PRD reader, spec detail with mockup preview and internal feedback
  • /larapilot/api โ€” JSON over the same artifacts (board, specs, PRD, OpenAPI at /larapilot/api/docs)
  • GET /larapilot/api/backstage โ€” Backstage catalog entities + delivery snapshot (see Developer portal)
  • POST /larapilot/api/specs/{code}/comments โ€” append internal feedback from scripts or tooling

API auth: set LARAPILOT_API_TOKEN to require a bearer token (or X-Larapilot-Token header) on every /larapilot/api/* request โ€” strongly recommended on shared staging hosts. Without a token, reads stay open in the allowed environments, but writes are refused outside local/development/testing.

Diagnostics (bug triage)

Read-only runtime snapshot for /larapilot-bug and local debugging โ€” never mutates workflow state.

Surface How
API GET /larapilot/api/diagnostics โ€” same dashboard gate (dev/staging only); 404 when LARAPILOT_DIAGNOSTICS_ENABLED=false
CLI php artisan larapilot:diagnostics โ€” --lines= (cap log tail), --no-logs (status + checks only)
MCP Larapilot diagnostics tool, or RunArtisanTool with larapilot:diagnostics

Query params (API): ?lines=100 (default from config, capped by max_log_lines) ยท ?no_logs=1 to omit the log tail.

Payload: app (name, env, Laravel/PHP versions, โ€ฆ), checks (storage_writable, cache, database, queue, log_file), healthy (critical checks), optional logs with secrets redacted ([REDACTED]).

Config (config/larapilot.php / env): LARAPILOT_DIAGNOSTICS_ENABLED (default true), LARAPILOT_DIAGNOSTICS_LOG_LINES (default 100), LARAPILOT_DIAGNOSTICS_MAX_LOG_LINES (default 500).

Workflow state still changes only via skills or Artisan โ€” not from the dashboard or API.

Frontend companion โ€” split repo

When Frontend Topology is API + external frontend, Laravel is the only Larapilot cockpit. PRD, backlog, plans, and all /larapilot-* commands run in the backend workspace. The FE repo is a linked write target configured with an absolute path.

How it works

Laravel (cockpit)                         Frontend repo (write target)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                         โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
.larapilot/docs/PRD.md                    src/โ€ฆ                   โ—„โ”€โ”€ implement (repo: frontend)
.larapilot/backlog.yaml                   tests/โ€ฆ
.larapilot/plans/                         (application code only)
.larapilot/mockups/
  1. Inception records topology and asks for the FE absolute path โ†’ larapilot:frontend-set.
  2. Scan (larapilot:frontend-scan) reads existing FE structure before planning evolutive work.
  3. Spec โ†’ plan โ†’ implement run on Laravel. UI tasks use repo: frontend and write under data.frontend.repo_path.

Setup commands

php artisan larapilot:frontend-set --path=/absolute/path/to/fe-repo --stack=React
php artisan larapilot:frontend-scan

Or /larapilot-frontend-companion in the Laravel editor.

Command Purpose
larapilot:frontend-set Persist frontend.repo_path (+ optional stack)
larapilot:frontend-scan Detect stack, tooling, structure, entrypoints

Details: Frontend companion.

Developer portal โ€” Backstage

Larapilot is repo-level; Backstage is org-level. The integration publishes .larapilot/ into the portal โ€” one way. The workspace stays the source of truth and workflow state never changes from Backstage.

php artisan larapilot:backstage-export           # preview the bundle (writes nothing)
php artisan larapilot:backstage-export --write   # generate catalog + TechDocs

Or run /larapilot-backstage, which asks for owner/system/lifecycle first and persists them to .env.

Generated Contents
catalog-info.yaml (repo root) Component entity + one API entity per OpenAPI contract found (storage/api-docs/api-docs.json, openapi.json, โ€ฆ)
mkdocs.yml (repo root) TechDocs config โ€” docs_dir: .larapilot/techdocs, plugin techdocs-core
.larapilot/techdocs/ index.md (delivery snapshot), prd.md, backlog/index.md, backlog/US-XXX.md (spec + plan + tasks)

catalog-info.yaml and mkdocs.yml are never overwritten without --force โ€” a project may already own them. Everything under .larapilot/techdocs/ is regenerated, and pages for deleted specs are pruned. --no-techdocs generates the catalog entity only.

Catalog identity lives in Laravel config / .env (not .larapilot/config.yaml โ€” it describes the org catalog, not the delivery workflow):

Env var Default Purpose
LARAPILOT_BACKSTAGE_ENABLED true Master switch for the integration and its endpoints
LARAPILOT_BACKSTAGE_OWNER guests Backstage Group/User that owns the entity โ€” set this, Backstage flags unresolvable owners
LARAPILOT_BACKSTAGE_SYSTEM โ€” Parent System entity, when your org uses them
LARAPILOT_BACKSTAGE_LIFECYCLE experimental experimental ยท production ยท deprecated
LARAPILOT_BACKSTAGE_COMPONENT_TYPE service Backstage component type
LARAPILOT_BACKSTAGE_NAME slug of app.name Entity name override
LARAPILOT_BACKSTAGE_BASE_URL app.url Base URL for catalog links/annotations โ€” non-production only
LARAPILOT_BACKSTAGE_TECHDOCS true Generate the TechDocs site
LARAPILOT_BACKSTAGE_WORKFLOW_API false Also register the dev-only Larapilot API as an API entity

Live delivery data

For a Backstage plugin or entity provider, two endpoints share the dashboard gate (dev/staging only):

  • GET /larapilot/api/backstage โ€” catalog entities, rendered YAML, TechDocs metadata, and a lean snapshot (metrics, per-status counts, blocking feedback, story list without bodies) built for polling many repos
  • GET /larapilot/api/backstage/catalog-info.yaml โ€” the same entities as a Backstage url location

Call them through the Backstage backend proxy so LARAPILOT_API_TOKEN stays server-side. The API returns 404 in production by design โ€” if the portal cannot reach a dev/staging host, ship the committed catalog-info.yaml and TechDocs instead.

Keep the catalog fresh with a CI step on the default branch (--write --force) or by re-running /larapilot-backstage after PRD and backlog milestones. php artisan larapilot:config-show reports the current mapping under data.backstage.

Project trackers โ€” Linear, Asana, Jira, Trello, ClickUp, Monday

Optional, API-key based. Mirrors the backlog into the tool the rest of the organisation already uses, so a PM or a client can follow delivery without opening backlog.yaml. .larapilot/ stays the source of truth โ€” the tracker is a window, not a second workflow.

php artisan larapilot:tracker-status --ping   # provider, status map, credentials check
php artisan larapilot:tracker-push --dry-run  # what would change, no API calls
php artisan larapilot:tracker-push            # backlog โ†’ tracker
php artisan larapilot:tracker-pull            # tracker โ†’ drift report (read-only)
php artisan larapilot:tracker-pull --apply    # write mapped statuses back

Or run /larapilot-tracker, which picks the provider, collects the credentials into .env, and checks the status map before the first push.

What gets mirrored

Larapilot Tracker
User story US-XXX Issue / task / card / item titled US-XXX โ€” Title, with the spec body, priority, points, and epic
Plan task TASK-XX A native sub-issue, subtask, subitem, or checklist item โ€” not a checklist buried in the description
Workflow status The provider's own column: workflow state, status, section, list, or status-column label
Provider Auth Destination Subtasks Status maps to
Linear personal API key team key sub-issues (parentId) workflow state
Jira (Cloud, REST v2) email + API token project key subtasks (parent) status, via a workflow transition
Asana personal access token project gid subtasks section (a DONE story is also marked complete)
Trello key + token board id checklist items list (board column)
ClickUp personal token pk_โ€ฆ list id subtasks (parent) list status
Monday API token board id subitems status-column label

Only one provider is active at a time (LARAPILOT_TRACKER_PROVIDER), but links are stored per provider, so switching tools โ€” or switching back โ€” never loses the mapping.

Direction: push writes, pull reports

Push is authoritative. Pull is a report: it reads remote state and lists drift, and changes the backlog only with --apply. Two things it will never do:

  • Set a spec to DONE. DONE is a human review gate that records the merge commit โ€” that stays with /larapilot-review and larapilot:spec-approve.
  • Change spec text. Titles, bodies, and acceptance criteria are owned by .larapilot/; the card description says so, and edits made in the tracker are overwritten on the next push.

TODO and PLANNED mapping to the same column is normal and is not reported as drift. A remote status outside the map is reported as drift with no suggestion rather than guessed at.

Set LARAPILOT_TRACKER_PULL_COMMENTS=true to import tracker comments as internal feedback (non-blocking, imported once).

Configuration

Credentials live in .env only โ€” never in .larapilot/, which is committed:

Env var Purpose
LARAPILOT_TRACKER_ENABLED Master switch (default false)
LARAPILOT_TRACKER_PROVIDER linear ยท asana ยท jira ยท trello ยท clickup ยท monday
LARAPILOT_TRACKER_SYNC_TASKS Mirror plan tasks as native subtasks (default true)
LARAPILOT_TRACKER_PULL_COMMENTS Import remote comments as internal feedback (default false)
LARAPILOT_LINEAR_API_KEY / _TEAM Linear key and team key (e.g. ENG)
LARAPILOT_JIRA_BASE_URL / _EMAIL / _API_TOKEN / _PROJECT Jira site, account, token, project key
LARAPILOT_ASANA_TOKEN / _PROJECT Asana PAT and project gid
LARAPILOT_TRELLO_KEY / _TOKEN / _BOARD Trello credentials and board id
LARAPILOT_CLICKUP_TOKEN / _LIST ClickUp token and list id
LARAPILOT_MONDAY_TOKEN / _BOARD / _DESCRIPTION_COLUMN Monday token, board, and the long-text column that carries the spec body

Status maps live in config/larapilot.php โ†’ tracker.providers.{provider}.status_map. If a mapped column does not exist, the push fails and names the columns that do โ€” Larapilot never creates columns in your tracker.

.larapilot/tracker.yaml holds the spec โ†’ remote-id mapping. Commit it: without a shared map, every machine creates duplicate cards. It contains identifiers only, never credentials. php artisan larapilot:config-show reports the wiring under data.tracker, including whether credentials are present โ€” never their values.

Requirements

  • PHP ^8.3
  • Laravel ^12 or ^13
  • Laravel Boost ^2.0 (installed automatically)
  • MCP-capable editor (Cursor, Claude Code, VS Code, โ€ฆ)

Quickstart

composer require andreapollastri/larapilot --dev
php artisan larapilot:install
php artisan boost:install

larapilot:install also scaffolds Larastan level 5+ and Laravel Pint (phpstan.neon.dist, pint.json, Composer scripts, dev dependencies). Run php artisan larapilot:quality before merge; larapilot:doctor fails when the gate is missing.

Already on Boost? Refresh skills once:

php artisan boost:update --discover

Register MCP servers in your editor if needed:

{
  "mcpServers": {
    "laravel-boost": {
      "command": "php",
      "args": ["artisan", "boost:mcp"]
    },
    "larapilot": {
      "command": "php",
      "args": ["artisan", "mcp:start", "larapilot"]
    }
  }
}

First run in your editor:

/larapilot-inception "your product idea"

Then /larapilot-spec, and the per-story loop above.

Upgrade

composer update andreapollastri/larapilot
php artisan larapilot:update
php artisan larapilot:doctor

Runtime-only refresh (skip Boost republish): php artisan larapilot:update --skip-boost.

larapilot:update overwrites .larapilot/design-systems/ with the packaged references; pass --preserve-design-systems to keep local customizations.

Learn more

License

MIT ยฉ Andrea Pollastri