App screens: navigation and filters in a web app
For developers, in code: declaring the screens of an application as sources with routes, navigation by route, URL filters, the raised hand on a screen, and what the assistant sees at the start of a turn.
An application is a set of screens, and the assistant can only open one it knows. A screen is a source in the panel — the kind «App screen» — carrying a name, a description of what the screen is for, and one or more route patterns. Everything else about operating an app follows from that.
Declaring a screen
In the panel: Sources → Add source → App screen. Name, description, routes. A route is a path pattern, or a full URL to bind it to one host of a site family:
/orders
/orders/{id}
https://app.example.com/settings/{siteId}/widgets
The description is what the assistant reads to answer «what is this screen for?» and to decide
where «my invoices» is. Write it the way you would explain the screen to a new colleague — what
is on it, what the buttons do, what a user usually comes here for. It is also where
data-sa-hint-style instructions belong for the screen as a whole.
Which screen a visitor is on is matched from the URL on every message; a hash-routed app declares
it with Shukai.setContext (Single-page apps).
Navigation by route
An assistant that can see at least one screen source gets a navigate tool whose destinations
are exactly the declared routes — it cannot invent one. «Take me to the invoices for March» opens
/orders with the filter set, when the screen declares one. A placeholder in a route ({id},
{siteId}) is filled from the current address, from an entity lookup the assistant made, or from
the finding that raised a hand. The most specific fully-resolvable route wins: a source
declaring both /widgets and /widgets/{widgetId} opens the list until the id is known.
Navigation by route is not a page action and is not gated by plan: a Starter assistant that sees screens still opens them. What it does on a screen — fill, press — is page actions, from Growth up.
URL filters
A screen that filters itself by query parameters — ?country=UA, ?status=open — declares
those parameters on the source (url_filters), each optionally with a fixed list of values. The
assistant then filters the screen by changing the URL rather than operating a dropdown, keeps
the existing selection when it adds a filter, and refuses a value outside a declared list. «Show
only Ukraine» on an analytics screen is one URL change, not a click sequence. Declare a filter
only where the value set is small and knowable (a country code, an enum); free-text filters are
better left to the screen’s own controls.
The raised hand on a screen
A screen may name a proactive tool — an HTTP call the assistant makes after the user has been on the screen for eight seconds, with no model involved. If it returns findings, the assistant raises a hand in the corner with one sentence about the first one worth saying; if it returns nothing, nothing happens and nothing is spent. The cooldown — how long before the same finding is offered again on that screen — is per screen, inheriting the agent’s default. Proactive findings.
What the assistant sees at the start of a turn
Once a conversation has looked at a screen, the assistant is shown the live manifest at the start of every later turn, with the note that anything earlier in the conversation is stale. The same happens on the turn after a navigation, so the destination is read before the assistant acts. This is why an app conversation does not re-scan on every question and why «the screen has changed» is never a surprise to it.
The user behind the screen
In an app the assistant acts for a logged-in user, and what it may read from your API is that
user’s. Hand it the user’s own token with Shukai.setUser(token) after login; a custom tool with
Authorization: Bearer {{user}} then calls your API as that user.
User identity.
A worked example
Our own panel is an application run this way: every screen is a source with routes and a
description, the Save buttons are data-sa-commit, the FAQ chip list is a declared list with a
language axis, the period picker’s trigger carries aria-expanded, and the co-pilot in the
panel’s corner edits the widget’s Content tab in three languages in one call. Sign up and ask it
to change your widget’s colour.