Pre-1.0. Not intended for public use yet. The API is subject to undocumented change, and these pages may already be wrong about it.

Skip to content

Commands ​

Introduction ​

Artisan commands install, inspect and maintain the feed.

Installing Storyfeed ​

CommandDescription
storyfeed:installpublishes config/storyfeed.php and the migrations, creates routes/feed.php from a stub, and offers to run the migrations. --without-migrations publishes none
bash
# never overwrites an existing routes/feed.php
php artisan storyfeed:install
# the routes/feed.php stub alone
php artisan vendor:publish --tag=storyfeed-definitions

The installer preserves an existing routes/feed.php that is not a Storyfeed file and explains how to set another definitions path. Setting definitions to false disables file creation.

Generating Classes ​

Stories ​

make:story creates a Story class. Without arguments, it prompts for the name and class structure. Passing only a name creates a class for one activity, constructed with its data and then published. The command prints the routes/feed.php binding for you to add.

OptionEffect
--model=Ordera resource class for that model. Takes precedence over --invokable
--resourcea resource class: one method per verb
--invokablea single verb's __invoke() declaration
--verb=the stored verb
--object=the object model or morph alias, or * for none
--axes=comma-separated grouping axes to pre-fill; default, every axis that applies
--from-doctorone class per recorded type and verb without a headline; see Generating From Doctor Findings
--forceoverwrites an existing story

Feeds ​

CommandDescription
make:feedcreates a feed class. --force overwrites an existing feed. --subject= writes the typed constructor, --role= the bound role (default context), --only= and --mode= fill define(). --from-doctor writes one class with unclassified verbs commented out; its only([]) throws until you classify each verb with only() or except()

Listing Definitions ​

CommandDescription
storyfeed:listlists every definition, as route:list lists routes: type, verb, name, the action that declares it (App\Stories\OrderStory@place, or a one-verb class), headline, anonymous headline, icon, intent, group headlines, grouping period, the keep-latest policy, and the file:line or action that defined it. --type= (a morph alias or model class), --verb=, --name= (name contains), --json; -v adds resolved middleware and a Where column for role constraints; JSON always includes middleware and where
storyfeed:verbslists registered verbs, their AS2 types, and whether each has a headline (the Grammar column) and an icon. --used compares against recorded verbs. Registered means declared with Storyfeed::verbs() or by a story class; see Verbs
storyfeed:storieslists publishers and models that could publish but have no recorded activities. --gaps shows only rows needing attention, --json, --since= sets the days after which a Story is considered inactive (default 30)

Caching Definitions ​

CommandDescription
storyfeed:cachecompiles registered stories and routes/feed.php into a cached manifest; also runs on php artisan optimize. Run it again after adding a method to a Story class
storyfeed:clearremoves the cached manifest

Like route:cache, storyfeed:cache prevents the definitions file from loading at boot. It serialises closure headlines and fails with a file:line reference if a closure cannot be serialised. Keep only Story definitions in the feed file; register verb vocabulary in a service provider.

Running Diagnostics ​

CommandDescription
storyfeed:doctoraudits headline, icon and AS2 type coverage, and feed health. --json; --stubs prints the routes/feed.php suggested definitions, with their use lines; --only=; --list names the checks --only= accepts; --fail-on=warning|error exits non-zero at the selected severity

See Diagnosing Your Feed for usage and Doctor Checks for the checks.

php artisan about ​

Laravel's about command has a Storyfeed section:

bash
php artisan about --only=storyfeed
LineReports
Definitionswhether routes/feed.php is loaded, or cached and skipped at boot
Cachewhether storyfeed:cache has run, and when
Verbshow many are declared, and how many ship as defaults
Object types, Stories, Feedshow many are registered
Recordingwhether recording is on
Curate, Trickle and Close-batches scheduleswhether storyfeed:curate, storyfeed:trickle and storyfeed:close-batches are scheduled
Doctorwhat the tables, recording and manifest checks report; storyfeed:doctor runs them all

The section works without a database and supports --json.

Scheduling Maintenance ​

The feed works without a scheduler. When Laravel's scheduler runs, Storyfeed schedules storyfeed:curate hourly unless curate.schedule is false. Schedule other maintenance commands in your application:

CommandDescriptionSuggested
storyfeed:tricklekeeps entity snapshots and deletions up to date, including models deleted without a model event, such as by a query builder delete. --limit=; --prune deletes activities with a role that no longer resolvesevery minute
storyfeed:close-batchescloses batches whose window has elapsed, dispatches BatchClosed, creates composites. --quiet-minutes=every 5 minutes
storyfeed:prunepermanently deletes activities past their verb's retention window. --days= overrides prune.after_days (per-verb retention takes precedence); --pretend reports what a run would delete, per verb, and deletes nothingdaily, if a verb declares a window or prune.after_days is set
routes/console.php
php
use Illuminate\Support\Facades\Schedule;

Schedule::command('storyfeed:trickle')->everyMinute();
Schedule::command('storyfeed:close-batches')->everyFiveMinutes();
Schedule::command('storyfeed:prune')->daily();

Maintaining Stored Activities ​

Rebuilding Snapshots ​

CommandDescription
storyfeed:rebuildrebuilds every entity snapshot and link from toFeed(); --recent=N limits the pass to entities named by the newest N activities
storyfeed:cache-snapshotsbounded snapshot refresh run by php artisan optimize; skips when the database is unavailable

Rehashing Groups ​

Storyfeed groups activities at publication. Existing groups remain unchanged when you:

  • register an axis
  • change an axis's grouping key
  • change a published activity's verb or roles

Neither storyfeed:rebuild nor storyfeed:curate without --rehash applies these changes to existing groups. To regroup stored activities:

bash
php artisan storyfeed:curate --rehash   # --window= bounds it by published_at

Changes to grouping.policy thresholds only affect eligibility. Plain php artisan storyfeed:curate re-evaluates existing candidate hashes against those thresholds; it does not need --rehash.

Scheduled curate runs never rehash; run --rehash explicitly.

Rehashing can move groups past an active cursor, leaving the next page empty. It changes sync_token, so clients must discard accumulated nodes and fetch from the start, even after an empty response. See the Sync token rule.

Releasing Orphaned Composites ​

If a composite parent is force-deleted while its members still appear in the composite, the doctor reports claims.parent_gone. Use --release to return them to ordinary grouping:

bash
php artisan storyfeed:curate --release   # a second run changes nothing

Releasing members changes sync_token. Soft-deleted parents keep their members.

Other Maintenance Commands ​

CommandDescription
storyfeed:curatechooses which group shows each activity with live() (backfill/repair); scheduled hourly by the package unless curate.schedule is false. --rehash, --window=, --release
storyfeed:healsoft-deletes activities whose source is permanently absent. --pretend previews; repeat --only= to select healers
storyfeed:bundlecombines Bundleable activities in closed batches into composites. --window=
storyfeed:participantsrebuilds the index queried by involving(). --missing, --chunk=. Safe to run repeatedly

bundle and curate can change existing groups and their sync_token. Clients that accumulate nodes must then fetch the feed again.

Seeding Demo Data ​

CommandDescription
storyfeed:demoseeds a fictional demo tenant. --days=7, --seed=1 select the history and deterministic seed; --fresh removes prior demo data first, --clear removes it without seeding, and --force allows production use

Released under the MIT License.