Repository navigation
API Snap
Caligrafy Quill 2.26.0. Generated from the source by
php qa/build-api-reference.php; the guides explain how to use these classes, this reference says exactly what each public method takes and returns. Back to the API reference.
Snap Cards and the assistant (namespace Caligrafy\Snap): cards built from what capabilities declare, the conversation, the planner and the setup.
| Class | What it is |
|---|---|
Caligrafy\Snap\Cards |
Snap Cards (2.23.0): every card is built from what a capability already declares |
Caligrafy\Snap\Hints |
Snap Cards work without any hint: every card is built from what a capability declares (its rules, descriptions, readOnly and destructive). |
Caligrafy\Snap\Views |
How a Show card looks, best first (2.25.0): 1. its card view: application/views/snap/<capability>.pug, a Pug view made for the card, in the app's own markup and |
Caligrafy\Snap\Designer |
A capability shown through its own page uses that page (Snap\Views). |
Caligrafy\Snap\Conversation |
The Snap shell's two spaces (2.23.0) |
Caligrafy\Snap\Planner |
The Snap shell's planner (2.23.0): Claude reads what the person typed or said and answers with cards. |
Caligrafy\Snap\Flow |
The next card for a capability and its inputs, the same whoever asks (a card that is sent, the shell's fast path, the model's choice): one place decides, so the planner can never take a shortcut around consent. |
Caligrafy\Snap\Input |
The inputs of a card arrive as an object, or its JSON (agents and addresses send JSON text): this gives the plain values only (a nested object or list is left out: a card's inputs are scalars). |
Caligrafy\Snap\Reads |
The reads of one request, once (2.23.0): Home asks the same lists for its alerts, insights and picks; each runs once per person per request. |
Caligrafy\Snap\Say |
The assistant's line after every action (2.23.0): whatever the person did (sent a form, picked a choice, confirmed, opened a row, undid, saved a shortcut), the answer carries what the assistant says about it, shown in ... |
Caligrafy\Snap\Consent |
Snap consent (2.23.0): nothing that changes data runs from a card until the person confirms it. |
Caligrafy\Snap\Offers |
Offer: Suggestion and Offer: Routine (2.23.0): the assistant notices what a person does again and again, only if they turned noticing on, and offers to help. |
Caligrafy\Snap\Shortcuts |
Go: Shortcut cards (2.23.0): a request a person saved (a capability with its inputs), run with one click. |
Caligrafy\Snap\Tasks |
Track: Task cards (2.23.0): work that runs in the background for one person. |
Caligrafy\Snap\Discover |
Discover (2.23.0): Home surfaces the things this application is about, to invite browsing, the way a shop surfaces products. |
Caligrafy\Snap\Setup |
install: the tables (framework/settings/platform.sql), a starter application/config/snap.php when there is none, then the two lines to add by hand (they are the app's own files): Route::snap(); in web.php, and the ... |
Caligrafy\Snap\Shell |
The Snap shell's fast path (2.23.0): what it can answer without a model, at once and for free |
Snap Cards (2.23.0): every card is built from what a capability already declares
Its 16 public methods have a page of their own: Caligrafy\Snap\Cards.
namespace Caligrafy\Snap;
class HintsSource: framework/core/Snap/Hints.php:30
Class Hints Snap Cards work without any hint: every card is built from what a capability declares (its rules, descriptions, readOnly and destructive). Hints only make them better, from one file the app owns, application/config/snap.php:
return [
'about' => 'a library app', // what the assistant is the assistant of (the planner)
'cards' => [ // keyed by capability name
'list_books' => ['title' => 'The catalog', 'columns' => ['title', 'author.name'], 'empty' => 'No book yet.'],
'reading_report' => ['async' => true, 'working' => ['Counting the books…']],
],
];
A file that returns the cards alone (no 'cards' key) works too. The keys of a card are in the wiki page "Snap Cards and the Assistant": title, lead, submit, columns, labels, hide, values, choices, open, full, empty, variant, noun, icon, done, undo, next, applies, empty_next, alert, insight, discover, working, async, consequence, confirm, card (2.25.0: its card view, 'Folder/view' under application/views, or false), view (2.24.0: the page whose part marked data-snap shows it, or false) and design (2.24.0: how its data is shown without a card view or a page). A capability is async when #[Capability(async: true)] says so, or its hint does.
public static function for($name)The hints of one capability (an empty array when it has none)
Parameters
$name
Source: framework/core/Snap/Hints.php:37
public static function about()What the app is about, for the assistant ("a library app"); empty when the file does not say
Source: framework/core/Snap/Hints.php:46
public static function forget()Forgets the file read (tests, and a file that changed)
Source: framework/core/Snap/Hints.php:54
namespace Caligrafy\Snap;
class ViewsSource: framework/core/Snap/Views.php:25
Class Views How a Show card looks, best first (2.25.0):
- its card view: application/views/snap/<capability>.pug, a Pug view made for the card, in the app's own markup and classes, rendered on the server into the card (the hint 'card' => 'Folder/view' names another, false none). It gets $result (what the capability returned), $rows and $page for a list, $record for one record, $input, $card, $home, $authorized and $user. A link with data-snap-open="<capability>" and data-snap-input='{"id":7}' opens that card in the conversation. Written by Claude from the app's views (the assistant skill); its first line names the page it was made from and that page's fingerprint, so
php caligrafer.php snap viewssays when it is stale. - the part of its page marked data-snap="<capability>" (a Route::page whose first data it is), embedded in the card (?snap-embed: no frame, sized to it); a whole page only when the hint 'view' names it
- a card designed for its data in the app's design system (Snap\Designer)
Views::embed()Views::page()Views::card()Views::cardFile()Views::source()Views::fingerprint()Views::cards()
public static function embed($name, array $inputs)The address of the page that shows a capability, with its inputs in place, in embed mode; null when there is none (no page uses it as data, or one of the page's route variables is not among the inputs)
Parameters
$name-
$inputsarray
Source: framework/core/Snap/Views.php:31
public static function page($html)Renders a page in embed mode: its style sheet and script go in, so the page shows without the site's frame and tells the card its height
Parameters
$html
Source: framework/core/Snap/Views.php:97
public static function card($name, $result, array $input, array $card = array())The HTML of a capability's card view, or null when it has none (or it failed: the card is then designed)
Parameters
$name-
$resultmixed: what the capability returned, as plain arrays -
$inputarray -
$cardarray, defaultarray()
Source: framework/core/Snap/Views.php:114
public static function cardFile($name)The card view file of a capability, or null: the hint 'card' (a view name, or false), else views/snap/<name>.pug
Parameters
$name
Source: framework/core/Snap/Views.php:152
public static function source($file)What the first line of a card view says it was made from: array('view' => 'Bookshelf/books', 'print' => '1a2b3c4d') (//- snap card of list_books, from Bookshelf/books.pug 1a2b3c4d), or null
Parameters
$file
Source: framework/core/Snap/Views.php:166
public static function fingerprint($view)A view's fingerprint, written in the card views made from it: when the view changes, they are stale
Parameters
$view
Source: framework/core/Snap/Views.php:175
public static function cards()Every card view of the app, with what it was made from and whether it is stale: [name => ['file', 'from', 'stale' (true, false, or null when its first line names no view)]]
Source: framework/core/Snap/Views.php:185
namespace Caligrafy\Snap;
class DesignerSource: framework/core/Snap/Designer.php:23
Class Designer A capability shown through its own page uses that page (Snap\Views). Without one, its card is designed, never dumped: a design says which of the data makes the title, the line under it, the badges, the numbers that stand out, the details, the longer text and the tags of a record, or the title, line, details and badge of each row of a list. The page then draws it with the app's own design tokens (its DESIGN_STYLE), so it looks like the rest of the app.
Who designs it: the hint 'design' of application/config/snap.php when the app gives one; else Claude (when the assistant has its key), once for each shape of data, kept in the cache; else rules from the names of the fields.
FORMATS = array('text', 'number', 'money', 'percent', 'date', 'datetime', 'bool', 'email', 'url')TONES = array('success', 'warning', 'danger', 'info', 'neutral')CACHE_DAYS = 30
-
public static $model = true: bool false: rules only, never the model (tests, and a design asked for while answering) -
public static $transport = null: Tests fake Claude's design here (a callable that takes the request and returns the response), apart from the planner's: a test that fakes the planner never sees the designer's requests
public static function record($name, array $record)The blocks of a record's card, values in place and formatted: hero (eyebrow, title, subtitle, badges), stats, fields, text, tags
Parameters
$name-
$recordarray
Source: framework/core/Snap/Designer.php:50
public static function rows($name, array $rows)Each row of a list, designed: title, subtitle, details (meta), a badge
Parameters
$name-
$rowsarray
Source: framework/core/Snap/Designer.php:89
public static function spec($name, $kind, array $sample)The design of a capability's data: the app's hint, else Claude's (kept for its shape), else the rules
Parameters
$name$kind-
$samplearray
Source: framework/core/Snap/Designer.php:116
public static function paths(array $data, $prefix = '', $depth = 0)The data's fields, flattened: path => a sample value (author.name => 'Octavia E. Butler'), lists kept whole
Parameters
-
$dataarray -
$prefix, default'' -
$depth, default0
Source: framework/core/Snap/Designer.php:138
public static function format($value, $format)No doc comment.
Parameters
$value$format
Source: framework/core/Snap/Designer.php:321
The Snap shell's two spaces (2.23.0)
Its 15 public methods have a page of their own: Caligrafy\Snap\Conversation.
namespace Caligrafy\Snap;
class PlannerSource: framework/core/Snap/Planner.php:25
The Snap shell's planner (2.23.0): Claude reads what the person typed or said and answers with cards.
What the model may do, enforced here, not in the prompt:
- look things up with the read-only capabilities this person may call (as tools, run with their permissions);
- answer with show_cards: which capability, with which values, and one sentence of caption.
Every card it names goes through Snap\Flow like any other: a read runs, a change comes back as an Ask: Confirm whose token only the person's click sends. The model never sees a token and never runs a change. Tool results are the app's data: the system prompt says so, and nothing in them can reach a change anyway.
Claude through the official PHP SDK (anthropic-ai/sdk), claude-opus-5-5 at low effort (a quick turn in a UI), server-side refusal fallbacks on. Without ANTHROPIC_API_KEY the planner is off and the shell uses its fast path.
MODEL = 'claude-opus-5-5'MAX_STEPS = 6RESULT_BYTES = 12000FILE_TYPES = array('image/png', 'image/jpeg', 'image/gif', 'image/webp', 'application/pdf', 'text/plain', 'text/csv', 'text/markdown')FILE_BYTES = 5242880FILES = 3
-
public static $transport = null: callable|null tests: fn (array $request): object (a response with ->stopReason and ->content)
public static function on()No doc comment.
Source: framework/core/Snap/Planner.php:34
public static function files($files)The files the person attached, checked: [name, type, data (base64)] of an allowed type, 3 at most, 5 MB in all
Parameters
-
$files -
@throws ServiceError invalid when a file is refused (the message says which)
Source: framework/core/Snap/Planner.php:60
public static function plan($text, Context $context, $instead = null, array $files = array(), $memory = '')No doc comment.
Parameters
$text-
$contextContext -
$instead, defaultnull -
$filesarray, defaultarray() -
$memory, default''
Source: framework/core/Snap/Planner.php:107
public static function send(array $request)No doc comment.
Parameters
-
$requestarray
Source: framework/core/Snap/Planner.php:163
namespace Caligrafy\Snap;
class FlowSource: framework/core/Snap/Flow.php:16
The next card for a capability and its inputs, the same whoever asks (a card that is sent, the shell's fast path, the model's choice): one place decides, so the planner can never take a shortcut around consent.
read: inputs missing -> its Ask card; complete -> runs -> Show card
write/destroy: inputs missing -> its Ask card; refused by its rules -> Ask with errors; else -> Ask: Confirm
A change runs only in SnapRun, with the token of that Confirm.
public static function next($name, array $inputs, Context $context)Parameters
$name-
$inputsarray -
$contextContext
Returns array: [card, http status]
Source: framework/core/Snap/Flow.php:21
public static function refused($name, Context $context, array $inputs, ServiceError $e)No doc comment.
Parameters
$name-
$contextContext -
$inputsarray -
$eServiceError
Source: framework/core/Snap/Flow.php:55
namespace Caligrafy\Snap;
class InputSource: framework/core/Snap/Input.php:15
Class Input The inputs of a card arrive as an object, or its JSON (agents and addresses send JSON text): this gives the plain values only (a nested object or list is left out: a card's inputs are scalars).
public static function decode($value)No doc comment.
Parameters
$value
Source: framework/core/Snap/Input.php:17
namespace Caligrafy\Snap;
class ReadsSource: framework/core/Snap/Reads.php:12
The reads of one request, once (2.23.0): Home asks the same lists for its alerts, insights and picks; each runs once per person per request. Cards::forget() (after a change) forgets them too.
public static function plain($name, Context $context)A read-only capability's plain result, without inputs, once per request and person (its errors too)
Parameters
$name-
$contextContext
Source: framework/core/Snap/Reads.php:19
public static function forget()No doc comment.
Source: framework/core/Snap/Reads.php:36
namespace Caligrafy\Snap;
class SaySource: framework/core/Snap/Say.php:11
The assistant's line after every action (2.23.0): whatever the person did (sent a form, picked a choice, confirmed, opened a row, undid, saved a shortcut), the answer carries what the assistant says about it, shown in the conversation section. Written here, at once and for free, from what the card is; the model writes only the captions of free questions. Also: which answers deserve a celebration.
public static function for(array $card, $after = null)The line for a card the person just reached, and whether it is a moment to celebrate
Parameters
-
$cardarray -
$after, defaultnull
Returns array: [say, celebrate]
Source: framework/core/Snap/Say.php:17
public static function on(array $card)Adds the line (and the celebration) to a card
Parameters
-
$cardarray
Source: framework/core/Snap/Say.php:95
namespace Caligrafy\Snap;
class ConsentSource: framework/core/Snap/Consent.php:20
Snap consent (2.23.0): nothing that changes data runs from a card until the person confirms it.
- snap_run answers a change with an Ask: Confirm: what will change (before -> after), and a one-time token bound to this person, this capability and these exact inputs, for 10 minutes, kept in the session (never in the card's address). Only the person's click on that card sends it back; a model, a page or a link cannot make one.
- A confirmed change is recorded in Caligrafy's audit log (capability snap_confirm, detail: what was confirmed).
- What the change can be undone with is decided here, from what was true before (update_), what was created (create_ -> delete_), or a hint ('undo' in application/config/snap.php). Undoing is a change too: it gets its own Confirm.
TTL = 600KEEP = 20KEY = 'snap_consent'
public static function ask($name, Context $context, array $inputs, $message = null)The Ask: Confirm card of a change, with a fresh token
Parameters
$name-
$contextContext -
$inputsarray -
$message, defaultnull
Source: framework/core/Snap/Consent.php:29
public static function take($token, $name, Context $context, array $inputs)Whether $token confirms exactly this change by this person; a token works once
Parameters
$token$name-
$contextContext -
$inputsarray
Returns array|null: what was kept with it (the values before the change)
Source: framework/core/Snap/Consent.php:47
public static function undo($name, array $inputs, $result, array $kept, Context $context)The action that undoes a done change, or null when there is none
Parameters
$name-
$inputsarray $result-
$keptarray -
$contextContext
Source: framework/core/Snap/Consent.php:64
namespace Caligrafy\Snap;
class OffersSource: framework/core/Snap/Offers.php:26
Offer: Suggestion and Offer: Routine (2.23.0): the assistant notices what a person does again and again, only if they turned noticing on, and offers to help. Built to stay quiet rather than noisy:
- opt-in per person (snap_settings.noticing), off by default; "What I've noticed" shows every pattern, each deletable, and turning noticing off deletes what was noticed
- a pattern is the same request (capability + inputs) on 3 different days or more, on the same weekday (weekly) or around the same hour (daily); anything weaker says nothing
- every offer says why ("you did this 4 Mondays in a row"), has Not now and Don't suggest this again, and at most MAX_OFFERS are shown at a time
- Offer: Suggestion: it is the usual moment and it was not done yet today: do it now (through Snap\Flow, so a change still asks for its Confirm)
- Offer: Routine: do it on that rhythm, at a level the person picks: suggest (a Suggestion at that moment), confirm (its Confirm ready at that moment), auto (it runs as a task and they are told). Accepting a routine is itself a change with its Ask: Confirm. A delete is never automatic.
MIN_DAYS = 3MAX_OFFERS = 2WINDOW_DAYS = 42LEVELS = array('suggest', 'confirm', 'auto')DAYS = array(1 => 'Monday', 2 => 'Tuesday', 3 => 'Wednesday', 4 => 'Thursday', 5 => 'Friday', 6 => 'Saturday', 7 => 'Sunday')
-
public static $now = null: int|null tests: the time "now" is
Offers::noticing()Offers::setNoticing()Offers::record()Offers::forget()Offers::patterns()Offers::offers()Offers::dismiss()Offers::routines()Offers::saveRoutine()Offers::deleteRoutine()Offers::runDue()Offers::rhythmText()Offers::fingerprint()
public static function noticing(Context $context)No doc comment.
Parameters
-
$contextContext
Source: framework/core/Snap/Offers.php:39
public static function setNoticing(Context $context, $on)No doc comment.
Parameters
-
$contextContext $on
Source: framework/core/Snap/Offers.php:44
public static function record(Context $context, $name, array $inputs)Something this person did through a card (a read that ran, a change they confirmed, a task they started)
Parameters
-
$contextContext $name-
$inputsarray
Source: framework/core/Snap/Offers.php:64
public static function forget(Context $context, $fingerprint = null)No doc comment.
Parameters
-
$contextContext -
$fingerprint, defaultnull
Source: framework/core/Snap/Offers.php:74
public static function patterns(Context $context)What was noticed: each request done on MIN_DAYS different days or more, with its rhythm and why
Parameters
-
$contextContext
Source: framework/core/Snap/Offers.php:88
public static function offers(Context $context)The offers to show now: routines that are due, then suggestions of this moment, then routines to propose; never more than MAX_OFFERS, never one dismissed
Parameters
-
$contextContext
Source: framework/core/Snap/Offers.php:121
public static function dismiss(Context $context, $fingerprint, $kind)No doc comment.
Parameters
-
$contextContext $fingerprint$kind
Source: framework/core/Snap/Offers.php:147
public static function routines(Context $context)No doc comment.
Parameters
-
$contextContext
Source: framework/core/Snap/Offers.php:162
public static function saveRoutine(Context $context, $capability, array $inputs, $weekday, $hour, $level)Keeps a routine (snap_routine_save, after its Ask: Confirm): the consent to do it on a rhythm, recorded in the audit log
Parameters
-
$contextContext $capability-
$inputsarray $weekday$hour$level
Source: framework/core/Snap/Offers.php:174
public static function deleteRoutine(Context $context, $id)No doc comment.
Parameters
-
$contextContext $id
Source: framework/core/Snap/Offers.php:194
public static function runDue()The scheduler's side (snap_routines_due, every minute): routines at the auto level that are due run as a task, as their owner, and they are told (by the task). Others wait for the person, as offers.
Source: framework/core/Snap/Offers.php:206
public static function rhythmText(array $r)No doc comment.
Parameters
-
$rarray
Source: framework/core/Snap/Offers.php:313
public static function fingerprint($name, array $inputs)No doc comment.
Parameters
$name-
$inputsarray
Source: framework/core/Snap/Offers.php:333
namespace Caligrafy\Snap;
class ShortcutsSource: framework/core/Snap/Shortcuts.php:14
Go: Shortcut cards (2.23.0): a request a person saved (a capability with its inputs), run with one click. Running one goes through Snap\Flow like any card: a read shows its result, a change asks for its Confirm.
TABLE = 'caligrafy_snap_shortcuts'MAX = 12
public static function of(Context $context)No doc comment.
Parameters
-
$contextContext
Source: framework/core/Snap/Shortcuts.php:19
public static function save(Context $context, $title, $capability, array $inputs)No doc comment.
Parameters
-
$contextContext $title$capability-
$inputsarray
Source: framework/core/Snap/Shortcuts.php:35
public static function delete(Context $context, $id)No doc comment.
Parameters
-
$contextContext $id
Source: framework/core/Snap/Shortcuts.php:49
public static function mark(array $card, Context $context)A Show card says whether it is one of this person's shortcuts already (its id), so its control shows the state: saved (with Remove) or not (Save)
Parameters
-
$cardarray -
$contextContext
Source: framework/core/Snap/Shortcuts.php:62
public static function find(Context $context, $text)The shortcut whose title matches what was typed, or null
Parameters
-
$contextContext $text
Source: framework/core/Snap/Shortcuts.php:81
namespace Caligrafy\Snap;
class TasksSource: framework/core/Snap/Tasks.php:24
Track: Task cards (2.23.0): work that runs in the background for one person.
A capability declared #[Capability(async: true)] (or with the hint 'async' in application/config/snap.php) does not run in the request: a read starts as a task at once, a change after its Ask: Confirm. The task is a row of snap_tasks and a job of Caligrafy's queue (snap_task_run). The worker runs the capability AS THE PERSON who asked (their user, the web channel: their permissions, not the queue's full access), keeps the card of what came out, and notifies them:
done -> the Show card of the result
needs_input -> the Ask card of what the capability refused (the person answers it, a new task starts)
failed -> a notice, after the queue's retries
The Track card shows where it is: queued, running, then the card it ended with.
TABLE = 'caligrafy_snap_tasks'LABELS = ...
public static function async($name)No doc comment.
Parameters
$name
Source: framework/core/Snap/Tasks.php:30
public static function start($name, array $inputs, Context $context)Starts a task for this person: the row, then its job. Returns its Track card.
Parameters
$name-
$inputsarray -
$contextContext
Source: framework/core/Snap/Tasks.php:40
public static function run($id)The worker (snap_task_run, in the queue): runs the task as its owner, keeps the card it ends with, notifies
Parameters
$id
Source: framework/core/Snap/Tasks.php:55
public static function get($id, Context $context)One task's Track card, for its owner only
Parameters
$id-
$contextContext
Source: framework/core/Snap/Tasks.php:90
public static function of(Context $context, $limit = 6)This person's latest tasks, newest first ("Coming up" and what just finished)
Parameters
-
$contextContext -
$limit, default6
Source: framework/core/Snap/Tasks.php:102
namespace Caligrafy\Snap;
class DiscoverSource: framework/core/Snap/Discover.php:28
Discover (2.23.0): Home surfaces the things this application is about, to invite browsing, the way a shop surfaces products. Out of the box, from one hint on a list capability ('discover'):
- for you more like what this person looked at (only when they turned noticing on: what they opened is in snap_events), e.g. another book by the author of a book they opened
- new what was added last
- the rule a business rule of the app: only what is available now (not in another list, e.g. not lent)
Each pick is a Home card that opens the object in the task space; each says why it is there.
The hint: 'discover' => array(
'open' => 'get_book', 'key' => 'id', how an object opens (capability, the field it takes)
'title' => 'title', 'meta' => array('author.name', ...), what a pick shows
'new' => 'created_at', the field that says when it was added
'related' => 'author.id', 'by' => 'author.name', what "more like it" shares, and its name
'opened' => array('get_book' => 'id', 'lend_book' => 'book_id'), the requests that mean "looked at it"
'unavailable' => array('capability' => 'list_loans', 'field' => 'book_id'), the business rule
'title_section' => 'On the shelf for you')
PICKS = 6
public static function sections(Context $context)Parameters
-
$contextContext
Returns array: [title, cards, nudge] for each list capability with a 'discover' hint this person may read
Source: framework/core/Snap/Discover.php:35
public static function dig($row, $path)No doc comment.
Parameters
$row$path
Source: framework/core/Snap/Discover.php:155
namespace Caligrafy\Snap;
class SetupSource: framework/core/Snap/Setup.php:17
Class Setup install: the tables (framework/settings/platform.sql), a starter application/config/snap.php when there is none, then the two lines to add by hand (they are the app's own files): Route::snap(); in web.php, and the routines' job in application/config/schedule.php. status: each of those, the queue (tasks run in it), and the assistant's model (ANTHROPIC_API_KEY).
CONFIG = 'application/config/snap.php'TEMPLATE = 'framework/settings/snap.php.template'ROUTES = 'application/config/routing/web.php'SCHEDULE = 'application/config/schedule.php'
public static function status($root = '.')What is ready, and what is not: [label => [ok (bool), detail]]
Parameters
-
$root, default'.'
Source: framework/core/Snap/Setup.php:27
public static function config($root = '.')Writes the starter application/config/snap.php when there is none
Parameters
-
$root, default'.'
Returns bool: true when it was written
Source: framework/core/Snap/Setup.php:49
namespace Caligrafy\Snap;
class ShellSource: framework/core/Snap/Shell.php:15
The Snap shell's fast path (2.23.0): what it can answer without a model, at once and for free:
- "What can I do?" (help, menu, ?): the cards this person may use, by family
- the title of one of their shortcuts: that Go: Shortcut, run
- the title or the name of a card ("the catalog", "lend a book", "list_loans"): that card
Anything else goes to the planner (Claude) when it is on.
MENU = array('what can i do', 'what else can i do', 'what can you do', 'help', 'menu', '?', 'options')ON_IT = ...
public static function onFocus($text, Context $context, $focus)A follow-up on the record the conversation is about, at once: "delete it", "change this", "lend that one". Anything longer ("lend it to Sam") goes to the planner, with the conversation's memory.
Parameters
$text-
$contextContext -
$focusarray|null: ['capability' => 'get_book', 'input' => ['id' => 7]]
Source: framework/core/Snap/Shell.php:31
public static function fast($text, Context $context)No doc comment.
Parameters
$text-
$contextContext
Source: framework/core/Snap/Shell.php:51
public static function menuCard(Context $context)The menu as a card: Go: Shortcut in its menu variant (ready-made starts the system offers, not ones you saved)
Parameters
-
$contextContext
Source: framework/core/Snap/Shell.php:73
public static function menu(Context $context)The menu: every card this person may start, with its family and type
Parameters
-
$contextContext
Source: framework/core/Snap/Shell.php:84
public static function normalize($text)No doc comment.
Parameters
$text
Source: framework/core/Snap/Shell.php:99
Caligrafy: Describe it. Approve it. Ship it. Your idea turned into a complete app: every feature built once, for web pages, Vue apps, a REST API and AI agents, and online.
Why Caligrafy: the benefits, the measurements, and what it is not yet
-
Quickstart with Claude: describe it, approve it, ship it
or the Quickstart: the same three steps by hand, in 5 minutes
- How Caligrafy works: the ideas in 5 minutes
- Your first capability: build a feature, page included
-
Capabilities in depth
-
#[Capability]: every option - Scheduled jobs: capabilities on a timer
- Notifications: web push and email
- Background jobs: capabilities run later
- Migrations: database changes, in order
- The cache
-
Testing your app
- Dependency injection
- Validation rules
-
Web pages
- Views and page components
- Design styles: another look, one setting
- Declarative routes: every request, in one line
-
Route::page·Route::form·Route::auth·Route::webhook·Route::download·Route::redirect·Route::action·Route::snap· capability routes - How to export a list as CSV
- Controllers: moving one to a declared route · how to, step by step
- Forms and helpers
-
Vue apps
-
Mobile and tablet
-
REST API
-
AI agents
-
Snap Cards and the assistant
- Payments: Stripe and crypto
- Face detection and face login
- OpenAI: chat and images · Assistants
- Open models: Llama, Mistral...
- Chatbots with Watson
- Machine learning in the browser
- Metadata and social cards · search and analytics
-
Putting it online: the production image, the database at every start
-
API reference: every class and method
-
Routing ·
Route·AuthRoutes· pages ·Controller· capabilities -
Data ·
Model·Query· sign-in · jobs ·Notify· payments · AI -
Interfaces · Snap ·
Snap\Cards·Snap\Conversation· testing · tooling · helper functions
-
Routing ·
-
Caligrafer: every command
- Project · build · data · agents · jobs and tests · maintenance · deploy
- Installation, configuration and Caligrafer
- Routing · Request · Controllers · Views
- Vue: flow of information · routes · validations
- Security and upgrading
- Release notes: 2.26 · 2.25 · 2.24 · 2.23 · 2.22 · 2.21 · 2.20 · 2.19 · 2.18 · 2.17 · 2.16 · 2.15 · 2.14 · 2.13 · 2.12 · 2.11 · 2.10 · 2.9 · 2.8 · 2.7 · 2.6 · 2.5 · 2.4 · 2.3 · 2.1 · October 2026 · changelog
- Testing Caligrafy (contributors)