# s-m-r-t > s-m-r-t is an MIT-licensed TypeScript stack for agentic software that people and agents use through the same screens, rules and permissions. Describe a record once and the storage, forms, API, command line and agent tools are generated from it. The site has three doors, BUILD, FEATURES and DOCS. FEATURES groups what ships by what a person is trying to do, into nine groups (Sell, Buy, Make, Team, Publish, Talk, Grow, Plan and Assistant), and each feature has a showcase with a live example where the packages ship one. build-a-boilerplate, behind BUILD, assembles a working mock-up for a kind of business in the browser and exports the plan as a file. DOCS holds every technical page, for developers and for agents. ## Released boundaries This site documents the installed s-m-r-t release. The framework supports a shared domain model and manifest. It generates REST, CLI, MCP, and selected WebMCP surfaces. Agent-assisted form controls support explain, validate, staged-change, and confirmed-apply flows. Application MCP surfaces include allow-lists and policy checks. These explicit surfaces do not expose every model method or field. Generated runtime operations still resolve through the application’s principal, tenant scope, field policy, writable-field rules, permissions, and any required confirmation. Development MCP is a separate, read-only development plane; it never executes the project’s application entry and never reads record payloads, principals, or credentials. Awareness is not authority: discovery never grants permission. ## Runtime provenance in the development MCP: read-only and only when configured Without a development database configured, the development MCP answers from the workspace and installed packages only. With one configured (SMRT_DEV_DB_URL or the project’s CLI database setting), it adds read-only runtime provenance: migration, job, schedule and dispatch health from the framework’s system tables, a tail of the change feed, and a sanitized snapshot of the booted object registry. That snapshot is built from manifests without executing the project’s application entry. Payloads, results, agent configuration and credentials are never read. These tools distinguish observed facts from declared facts. Live data operations remain on the generated and application MCP runtime plane and remain policy-controlled. # The s-m-r-t application stack [Skip to content]() []() [Sell]()[Customers]()[Orders]()[Invoices]()[Products]()[Quotes]()[Subscriptions]()[Payments]()[Buy]()[Vendors]()[Purchase orders]()[Expenses]()[Inventory]()[Make]()[Assemblies]()[Production]()[Stock]()[Team]()[Employees]()[Timesheets]()[Qualifications]()[Approvals]()[Roles]()[Publish]()[Articles]()[Images]()[Video]()[Voice]()[Comments]()[Social]()[Talk]()[Chat]()[Email]()[Slack]()[Support]()[Grow]()[Campaigns]()[Analytics]()[Reports]()[Ads]()[Affiliates]()[Plan]()[Projects]()[Tasks]()[Events]()[Places]()[Assistant]()[Agents]()[Tools]()[Memory]()[BUILD]() Click a group for its everyday set · click a feature to add or drop it [BUILD]() ## [Sell]() Everyday set - [Customers]() - [Orders]() - [Invoices]() - [Products]() - [Quotes]() - [Subscriptions]() - [Payments]() ## [Buy]() Everyday set - [Vendors]() - [Purchase orders]() - [Expenses]() - [Inventory]() ## [Make]() Everyday set - [Assemblies]() - [Production]() - [Stock]() ## [Team]() Everyday set - [Employees]() - [Timesheets]() - [Qualifications]() - [Approvals]() - [Roles]() ## [Publish]() Everyday set - [Articles]() - [Images]() - [Video]() - [Voice]() - [Comments]() - [Social]() ## [Talk]() Everyday set - [Chat]() - [Email]() - [Slack]() - [Support]() ## [Grow]() Everyday set - [Campaigns]() - [Analytics]() - [Reports]() - [Ads]() - [Affiliates]() ## [Plan]() Everyday set - [Projects]() - [Tasks]() - [Events]() - [Places]() ## [Assistant]() Everyday set - [Agents]() - [Tools]() - [Memory]() [**Build**build-a-boilerplate]()[**Features**showcases]()[**Docs**for developers and agents]() --- Build # Features Nine groups of what you do not build from scratch. - [## Sell Customers, orders, invoices and payments for what you sell. CustomersOrdersInvoicesProductsQuotesSubscriptionsPayments]() - [## Buy Vendors, purchase orders and expenses for what you buy. VendorsPurchase ordersExpensesInventory]() - [## Make Parts, assemblies and production for what you build. AssembliesProductionStock]() - [## Team Employees, hours, qualifications, approvals and roles for the people who work here. EmployeesTimesheetsQualificationsApprovalsRoles]() - [## Publish Articles, images, video and voice, with comments and social posts. ArticlesImagesVideoVoiceCommentsSocial]() - [## Talk Chat, email, Slack and support cases. ChatEmailSlackSupport]() - [## Grow Campaigns, ads, affiliates, analytics and reports. CampaignsAnalyticsReportsAdsAffiliates]() - [## Plan Projects, tasks, events and places. ProjectsTasksEventsPlaces]() - [## Assistant Agents that read, propose and act inside the application. AgentsToolsMemory]() --- Docs # Documentation for developers and agents Start building on the left. Point an agent at the entry points on the right. Every technical section follows below. ## For developers - [**Getting Started** Pick a starting point: a cookbook, smrt-start, or an existing project.]() - [**smrt-start** Scaffold a SvelteKit application with the framework already wired in.]() - [**build-a-boilerplate** Assemble a working mock-up in the browser and export it as a cookbook.]() - [**Task guides** Follow one procedure to one complete result.]() ## For agents - [**llms.txt** The site directory for language models, one line per page.]() - [**Agent docs** Curated full-page context. Every page also has a Markdown copy at its path plus .md.]() - [**Application MCP** Generated and hosted MCP for permitted runtime data operations.]() - [**Development MCP** Read-only workspace and installed-package knowledge for coding agents.]() - [**Evidence** Each site claim beside the released source it was verified in.]() ## Sections - [**Framework** Learn how models, data, identity, permissions, and generated interfaces fit together.]() - [**Agents** See where agents connect, what they may do, and whose authority they carry.]() - [**Interaction** Learn how persons and application agents communicate, propose changes, and share control.]() - [**UI** Explore the visible components and patterns that implement governed interaction.]() - [**Tooling** Use development tools, framework knowledge, and MCP surfaces for the correct job.]() - [**Guides** Follow task procedures and keep concept and reference details in their source sections.]() - [**Reference** Look up exhaustive package, interface, configuration, and contract details.]() --- # build-a-boilerplate Loading build-a-boilerplate… Add recipes or packages and an app mock-up assembles around them: navigation, list views, forms and help per model. Its Export tab gives you two ways out: download the cookbook and run smrt cookbook apply on the file to create a project, or copy a prompt that has your coding agent build the app from it. --- Agents # Agents work with borrowed authority. A s-m-r-t application can offer its operations to agents: an agent in the browser page, an agent connected over MCP, or one of the application's own scheduled and chat agents. Each connects through a defined door, and every door is a choice the application makes. Whichever door it uses, an agent acts as someone — the signed-in person on the page, or a user account bound to it on the server — and the server checks every request against that identity. The front page says an agent never has more power than the person it works for. This section is the mechanism behind that sentence. About agents that use a running application. Coding agents, which help build one, are covered in [Tooling](). 1. [01 Generated model tools page]() 2. [02 Mounted UI tools page]() 3. [03 Component tools page]() 4. [04 Server principal tools server]() Agents 01 ## Four ways in, on two levels of trust An agent reaches a s-m-r-t application through one of four defined surfaces. Three live in the browser page and act as the person using it. The fourth runs on the server and is never visible to the browser. **In plain English** Before asking what an agent may do, ask where it stands. An agent in the page works as the signed-in person. An agent on the server works as a user account an operator assigned to it. ### Three doors open from the page A page can offer an agent tools from three sources. Generated model tools come from the application's record declarations and run over its own web routes. Six fixed UI tools describe and operate the forms and tables currently on the page. A component can also declare a tool of its own for as long as it stays mounted. - Generated model tools carry the same names, descriptions, and input rules as the rest of the application. - The six UI tools list, inspect, and operate form controls and data views. - A component tool answers to the same exposure policy as the generated tools, and it is removed when its component leaves the page. - All three run as the signed-in page user. No page tool carries an account of its own. ### The fourth door never reaches the browser The application's own agents — the ones that follow written instructions, run on schedules, and talk in chat — do their work on the server, as a user account bound to their persona. These server tools are a separate surface, and they are never registered in a browser page. - A server agent acts as the user account bound to its persona. - Its allowed tools are a fixed list stored with that persona. - Its actions are recorded as done on behalf of the person they serve. ### One set of rules behind every door Whichever surface a request arrives on, the server resolves the same questions: who is asking, in which tenant, with which permissions, touching which fields. The door decides how a request arrives, never whether it is allowed. [Exposure is not authorization →]()[Two planes, kept apart →]()[Security reference →]() 01 Generated model tools Tools written from the record declarations; calls run over the application's web routes. Browser · the signed-in person 02 Mounted UI tools Six fixed tools that read and operate the forms and tables on the page. Browser · the signed-in person 03 Component tools A tool one component declares for itself while it is on the page. Browser · the signed-in person 04 Server principal tools The application's own agents, working as a persona's bound user. Server · a bound user account Three doors share one plane and one identity; the fourth has its own. The rest of this page follows that split. **Packages** **Canonical sources** Agents 02 ## One declaration writes every tool The actions a record declares become its web routes, its commands, and its agent tools. The api selection on the model gates all of them, and every action carries an effect class — read, write, or destructive — that exposure policies filter on. **In plain English** You do not write agent tools. You declare what a record can do, once, and the framework writes the route, the command, and the tool from that declaration — with the same names, descriptions, and rules. **Manifest** RESTMCPWebMCPCLIBrowser Each interface reads the same declared model capabilities. ### Tools are projections, not copies REST, CLI, MCP, and WebMCP are four projections of one declared operation set, sharing one discovery and invocation contract. A browser tool is named after its record and action — an Article's list action is the tool article\_list on every agent surface. - The api selection gates the browser tools too: an action excluded from the web API has no browser tool. - Descriptions and input rules come from the model's own fields and metadata. - Whether an action needs a record id is decided by the method itself — an instance method is item-scoped, a collection method is not — and route configuration cannot change that. ### Every action has a fixed effect class Listing and reading are read. Creating and updating are write. Deleting is destructive. This classification is fixed for the standard actions — configuration cannot soften it — and it is what an exposure policy filters on. ### An undeclared custom action counts as destructive A custom method with no declared route metadata is classified destructive, non-idempotent, and open-world, so a browser capability policy never fails open. Under the read-only default that makes it invisible to page agents until its declaration says otherwise — and the contract asks you to declare safer semantics only when they are true. src/lib/objects/Report.ts typescript ``` @smrt({ api: { exclude: ['delete'], routes: { preview: { method: 'GET', effect: 'read', idempotent: true, openWorld: false } } } }) export class Report extends SmrtObject { async preview() { // A declared read: visible to page agents under the read-only default. } } ``` **Packages** **Canonical sources** Agents 03 ## Showing a tool grants nothing An exposure policy chooses which tools a page offers, and offering none of it is the default: registration without a policy exposes reads only. Whether a call to the application succeeds is decided at the authenticated route it runs through — never by the fact that a tool was visible. **In plain English** The list of tools an agent can see is a table of contents, not a set of keys. Every call still signs in, still lands in one tenant, and still passes the same permission and field checks as the person's own request. ### The default is read-only Registering tools without an exposure policy offers only read-effect tools. Write and destructive tools appear only when the application names those effects deliberately. The policy can also prefix the page's tool names and cap how many register at once. @happyvertical/smrt-web · index.d.ts typescript ``` export interface WebMcpExposurePolicy { /** Allowed effects. Omitted means read-only exposure. */ effects?: readonly ('read' | 'write' | 'destructive')[]; /** Prefix every registered tool name with `_`. */ namespace?: string; /** Optional maximum tools registered by one call. */ maxTools?: number; } ``` ### A component's own tool follows the same rule A component can declare a tool of its own while it is mounted. That tool goes through the same policy as the generated set. One that does not declare its effect counts as destructive, the same fail-closed reading an undeclared custom action gets. Under the read-only default it is left out. The policy on the page's Provider always wins over anything the component says for itself, even when the Provider's policy is narrower. - The name prefix and the tool cap apply only to the generated set. A component tool keeps the name its author chose and is never counted against a generated set's budget. - The tool a rich form opts into declares itself a write, never destructive. It falls back to allowing reads and writes for itself only when no Provider above it states a policy. - On a browser without the interface, or under a policy that excludes the tool's effect, registering it does nothing. ### Selection and permission are different questions The exposure policy answers one question: which tools does this page offer. It does not answer whether a call succeeds. The package contract says so in its own words: this capability policy is not authorization — the authenticated REST surface remains the auth, tenant, field-write, and sensitive-data boundary. Security Two different questions Which tools appear on a page is a capability choice. Whether a call succeeds is an authorization decision. The server answers the second question on every request, whatever the first answer was. ### Where a mistake fails closed Suppose a page offers a tool it should not have. What happens next depends on the source. A generated model tool still arrives at an authenticated route as the signed-in person, in that person's tenant, under that person's permissions and field rules. A tool the person could not use fails there, the same way it would fail for the person. - A component tool runs whatever its component wrote, in the browser. If that code calls the application's routes, the same server checks apply. If it does not, there is no server round-trip to fail closed; the exposure policy is what bounds it. - A declared interaction never calls the application's routes. It dispatches one registry command marked as an agent's, so its boundary is the registry's own rules: staged review and a person's own confirming gesture. **Packages** **Canonical sources** Agents 04 ## Browser agents and server agents never trade places A page tool always acts as the signed-in person; personas and agent-class limits play no part there. A server agent always acts as its persona's bound user, inside three limits at once. The two planes meet only at the application's authenticated routes. **In plain English** There is no path from the page into a server agent's authority, and no persona hiding behind a page tool. Each plane has one identity story, and the server checks it on every request. ### The browser plane: the person's own authority A generated tool registered in the page executes over the application's web routes as the signed-in user — the same session, tenant, and permissions the person already has. Persona allow-lists and agent-class ceilings do not participate on this plane. There is nothing for them to bound, because a page tool holds no identity of its own. ### The server plane: three limits at once An application agent runs its work as the user account bound to its persona. What it can actually do is the overlap of three lists: what that user may do, what its class of agent may ever do, and what this persona is allowed to call. An action outside any one of the three does not run. - The database applies the bound user's row rules to every query in the run. - Every action is recorded as done on behalf of the person it serves. - Server principal tools are never registered in a browser page. ### They meet only at the boundary Both planes end in the same place: one authenticated application request, resolved as one identity, in one tenant, against one permission set. Nothing else crosses between them. This is the mechanism behind a sentence the front page states without proof: an agent never has more power than the person it works for. [Permissions and security →]()[Authorization reference →]()[Interaction →]() BROWSER PLANE Page agent → registered tools → generated fetchers acts as: the signed-in person. SERVER PLANE Application agent → persona → principal run acts as: the persona's bound user, inside three limits. **Authenticated application routes** identity · tenant · permission · field rules — checked on every request. Records **Packages** **Canonical sources** Agents 05 ## An agent asks the page what it means Mounted forms and data views register their identity, meaning, constraints, and current state. Agent tools read those registries — never the rendered screen — and a proposed change waits for a person's own click to apply. **In plain English** A page agent does not scan pixels or press buttons. It reads a live index of what is on the page, proposes a value beside the current one, and shows its work. The person applies it or throws it away. ### Controls carry their own description Every registered control has a stable identity and a published meaning: kind, label, options, constraints, unit, sensitivity, and current state. A data view registers its columns the same way. The six fixed UI tools read these registries at call time; they do not inspect or simulate the screen. - The six tools do not change as components mount and unmount — the answers do. - Secret values are never serialized into a tool response. - Tool responses are marked as untrusted content for the agent reading them. ### Propose, then a person confirms An agent can stage a value on a control. Staging records who proposed it and when, and places the proposal beside the current value for review. Applying it requires a person's own gesture, checked by the registry while the gesture is happening — input that merely claims to be a confirmed user action is rejected. - The review surface is a released component, StagedControlReview — not custom code each application writes. - Apply, clear, and undo stay on the human side of the line. - A protected field refuses staging outright. The refusal is part of the demo below. ### A component can declare an interaction as data A component can also declare one interaction of its own as data with no code in it, such as advancing a table one page. The declaration holds an id, a description, an effect it may declare, and which registered control or data view it addresses. Bound to that control or view while the component is on the page, it becomes a page tool like any other. Running it dispatches one registry command marked as an agent's, so the staged review and the person's own gesture above apply unchanged. - The declaration has no place for a function, a URL, or a route. What runs is built from the target it names, and it never calls the application's routes. - A declared interaction follows the page's exposure policy like every other page tool, and one that does not declare its effect counts as destructive. - A declared interaction needs registries to dispatch to: the Provider's mounted-UI registries, or ones handed to the component directly. With neither, binding it registers nothing. - The six fixed UI tools are unchanged. A declared interaction sits above them and cannot claim their reserved prefix. [Declare and bind an interaction →]() ### See it run The same demo that runs on the UI overview: an agent finds a field, checks its proposal against the same rule a person sees, stages it, and is refused on a protected field. Nothing changes until the confirm click — which an agent cannot send. Scripted demonstration · released registry ### A proposal succeeds. A protected change fails. This scripted adapter uses real controls, validation, classification, staging, and confirmation policies. No language model runs in this demo. Small example object Subject Profile · 42 Form ID ` profile-demo ` Display name 3–30 characters. Start with a letter. Recovery key A stored secret exists. The form and adapter do not receive its value. Permitted proposal 1. **Find and explain**Read stable identity, label, constraints, and policy. 2. **Validate the proposal**Use the same rule as the visible form. 3. **Stage separately**Keep the proposal apart from the live value. 4. **Review**Compare the live and proposed values. 5. **Confirm and apply**A real click supplies the confirmation an agent cannot send. 6. **Undo**Restore the previous registry-held value. Live value**Willow Reed** Proposed value**Not staged** Proposal check**Not checked** Policy refusal #### Awareness is not authority The registry can identify the recovery-key control. Its secret classification removes read and mutation authority. **No request sent** The adapter supplies no protected value to this attempt. Choose the first step to run the permitted proposal. The same demo, with its technical notes, is on the [UI overview]() and in the [Playground](). **Packages** **Canonical sources** Agents 06 ## The defaults are quiet, and every step up is deliberate The framework always prepares the tool descriptions; the application decides whether any reach a browser. Saying nothing more offers reads only, and the mounted UI tools take a second, separate decision. The starter template makes the read-only choice for you. **In plain English** An installed library offers agents nothing. A new application from the starter offers read-only record tools, in browsers that support them, and nothing else — until you decide otherwise. ### A description is not an offer Build time always emits the tool definitions — there is no switch for that, and none is needed, because a definition in a bundle does nothing. Tools exist for an agent only after the application registers them in a page. ### One ladder of decisions Each row is a separate decision with its own quiet default. No earlier row implies a later one. A component's own tool adds no row. The exposure policy on the second row governs it too, and a component tool that declares no effect counts as destructive. ### The starter's choice, in full The starter template registers the generated read-only tools in its root layout, through the Provider inside AppShell from @happyvertical/smrt-svelte/app. Three qualifications travel with that choice: it is read-only; it is feature-gated, so server rendering and browsers without the interface get nothing; and it does not enable the six UI tools, which remain a separate decision. The runtimeDiagnostics prop, on for signed-in sessions, adds exactly one more read-only tool, smrt.runtime.diagnostics.read, which fetches the mounted diagnostics route as the page user. src/routes/+layout.svelte (starter template) svelte ``` {@render children()} ``` | Layer | Default | What changes it | | --- | --- | --- | | Installed library | Offers agents nothing | The application registers definitions in a page | | Registration with no policy | Reads only | An exposure policy that names write or destructive effects | | Mounted UI tools | Off, even when model tools are on | A second, separate opt-in on the Provider | | Starter template | Read-only model tools on, feature-gated | Editing one derived value in the root layout | **Packages** **Canonical sources** Continue by task ## Use the section that owns the next question. [**Interaction** How persons and agents propose, confirm, and refuse — moment to moment.]() [**Framework** The one declaration everything on this page projects from.]() [**Tooling** The hosted and local MCP surfaces, and the coding-agent tools — a different audience. The tools that help agents build one live in Tooling.]() [**Reference** The exhaustive interface, authorization, and security contracts.]() [**Playground** The released controls these tools address, standalone.]() --- [← Reference]() Framework concept # Software as Agentic Domain Logic A SAADL application exposes the same domain operations to people and agents instead of maintaining a separate, reduced bot interface. **In plain English** Define the work once. People can reach it through pages, HTTP, or the command line. Agents receive callable tools that resolve to the same models, permissions, and field policies. **Manifest** RESTMCPWebMCPCLIBrowser Each interface reads the same declared model capabilities. ## One definition, several ways to operate it The domain model is the source of truth. REST routes, CLI commands, MCP and WebMCP tools, and human interfaces are projections of that same model rather than independent implementations that drift apart. ## Useful to operators and builders An operating agent receives the same permitted capabilities as a person. A coding agent receives a manifest of the objects, fields, relationships, and generated tools. Thus, the agent can understand and change one definition instead of rediscovering each interface. ## What does not count A chatbot beside an application is not automatically SAADL. Neither is an agent-only tool or a generated UI. The defining property is parity: human and agent operations resolve through the same domain logic and security boundaries. ## Why s-m-r-t uses this shape One model reduces duplicated code and review. It keeps the codebase map current and makes infrastructure replaceable. Security improvements can then flow from shared framework packages into each application. **Related pages** [Agent-legible applications]()[Connect APIs, tools, and agents]()[The development MCP server]() **Packages used in this guide** [@happyvertical/smrt-core]()[@happyvertical/smrt-app-mcp]()[@happyvertical/smrt-app-cli]()[@happyvertical/smrt-web]() **On this page** --- [← Capabilities]() Framework approach # Build an application agents can understand s-m-r-t describes the application at several layers. An agent can inspect declared domain logic, understand visible controls, and discover permitted operations. An exposed runtime bridge also lets the agent observe the active environment. **In plain English** An agent receives bounded descriptions of the model, interface, and callable actions. The runtime bridge can also provide an active-environment view. The agent does not have to infer these details from files or rendered pixels. **Agent understanding** Domain manifestOptional runtime bridgeForm controlsMCP tools Explicit registries describe the application from source through the active interface. ## One application, four semantic views Each registry answers a different question. Together they give people and agents a consistent map from what the product means to what this particular environment can do. - The domain manifest describes objects, fields, relationships, policies, and declared interfaces. - When exposed, the runtime-environment registry describes which modules and capabilities are actually available in the active process. - The control registry describes the visible form controls, their meaning, constraints, sensitivity, and state. - MCP and WebMCP schemas describe the operations an agent may request at the current boundary. ## Compare what is declared with what is running The runtime-environment registry is designed as a bounded bridge for development tooling. When a development MCP connection exposes that registry, an agent can compare workspace knowledge with the active process. The agent does not assume that a build artifact and its process agree. - Missing or stale registrations become diagnosable facts instead of mysterious runtime failures. - Environment-specific modules and adapters can be discovered without hard-coding one deployment shape. - The registry exposes capability metadata, not application records, credentials, principals, or tenant data. Version added Runtime bridge availability The current tooling reference is pinned to the released 0.55.16 development MCP, which reads workspace and installed-package artifacts only. Treat runtime-environment awareness as available only when the installed development MCP explicitly exposes a runtime integration. [Development MCP and its runtime boundary →]() ## Use the same pattern in the visible interface Agent-assisted forms make controls legible in the same way. A stable form and control identity replaces DOM position or visible wording, while descriptions, options, validation, and sensitivity travel with the control. - Chat, voice, tutorials, and tests can share one control description. - Highlight, explain, and validate commands can help without changing a value. - Staged changes keep the proposed value separate until a confirmed apply command. [Try the agent-assisted form pattern →]() ## Awareness is not authority Describing an environment or control does not grant permission to operate it. Development metadata remains separate from live data operations, and runtime calls still resolve through the application principal, tenant scope, field policy, and explicit confirmation rules. - The development MCP understands code and, when connected, bounded capability metadata; generated local MCP, hosted application MCP, and WebMCP perform permitted data operations. - Secret values stay out of control descriptions and generated outputs. - An application can expose a narrow tool set even when its model supports more operations internally. ## Why explicit registries beat reverse-engineering A semantic contract is stable across layout changes, deployment shapes, and agent providers. The same metadata also improves documentation, accessibility, validation, testing, and generated interfaces, so making the application legible does not create a separate agent-only implementation. - Less duplicated integration code and fewer human/agent interface drift bugs. - More reliable automation than filesystem, DOM, or screenshot guessing. - One inspectable boundary for builders, operators, tests, chat, and voice experiences. - Security hardening flows through the shared model and registries instead of being recreated per adapter. **Related pages** [Software as Agentic Domain Logic]()[Agent-assisted forms]()[The development MCP server]()[WebMCP]() **Packages used in this guide** [@happyvertical/smrt-core]()[@happyvertical/smrt-dev-mcp]()[@happyvertical/smrt-ui]()[@happyvertical/smrt-app-mcp]() **On this page** --- [← Capabilities]() New UI capability # Let an agent help with a form s-m-r-t controls describe their identity, permitted operations, and page location to an adapter. The adapter can support chat, voice, tutorials, or tests. The description does not give the adapter unchecked page access. **In plain English** An agent can find a field, explain it, highlight it, check it, or propose a value. The user still confirms changes, and secret or read-only fields remain protected. **Form controls** DescribeHighlightValidateStageConfirm An adapter can guide the user or stage a change; confirmed application stays explicit. ## Give every control a stable address A form has a formId and each control has a controlId, usually taken from its name. That lets an adapter refer to profile.displayName or settings.notifications without guessing from DOM position or visible wording. - Controls publish their label, description, kind, options, constraints, and current validation state. - A subject can connect a control to the record being edited. - Public, personal, sensitive, and secret classifications travel with the control description. ## Help without changing anything An adapter can list the controls in a form and use safe commands to focus, reveal, highlight, explain, or validate one of them. These commands help someone navigate the interface but do not change its values. - Highlight can point to the field being discussed in chat. - Explain returns the control description, choices, and constraints to the adapter. - Validate runs the same rule the visible form uses. ## Propose first, then ask Staging records a proposed value separately from the live form. Applying, clearing, or undoing an agent change is always refused by default — only a human, through a real local click routed via executeLocalControlCommand, can confirm one — so the UI has a natural place for a review step. - Secret values are redacted and cannot be read or changed through the registry. - Read-only, disabled, and non-writable controls reject mutation commands. - Applications can supply a stricter policy for their own risk and permission rules. ## Connect the adapter your product uses The registry deliberately does not know about a particular chat model, voice service, WebMCP transport, or DOM implementation. Your adapter translates a trusted tool call or tutorial step into the small command vocabulary. AgentAssistedProfile.svelte typescript ```
``` ## Know where the boundary is today The standardized controls, registry, safety policy, s-m-r-t Svelte form bridge, and interactive playground example are included. A product chooses and connects the chat or voice adapter that exposes these commands. The installation of both packages does not let smrt-chat control every form. **Related pages** [Agent-legible applications]()[Canonical success-and-refusal demonstration]()[Standalone Playground demonstration]()[Control interaction contract]()[WebMCP]() **Packages used in this guide** [@happyvertical/smrt-ui]()[@happyvertical/smrt-svelte]()[@happyvertical/smrt-chat]() **On this page** --- [← Capabilities]() New capability # Your web app becomes an agent tool surface s-m-r-t generates WebMCP tools from the model actions and field metadata that MCP uses. It registers the tools with the browser. In-page agents can then discover and invoke the tools. Verified against s-m-r-t 0.57.40 **In plain English** In a browser with WebMCP support, your page can advertise useful application actions to an AI agent. Those actions still run as the signed-in page user through the generated REST API, so existing authentication, tenant, permission, and field policies remain in charge. **Page tools** ManifestJSON SchemaWebMCPREST policy Browser agents discover model actions that still use the signed-in server session. ## One tool vocabulary, in the server and the page The core descriptor builder emits the same stable tool names, descriptions, and JSON Schema inputs for Node MCP and browser WebMCP. A product\_list tool means the same thing on both surfaces; list and get are marked with the WebMCP read-only hint. - One generated descriptor per exposed collection action. - CRUD tools cover list, get by ID or slug, create, update, and delete. - Unsupported browsers and server rendering safely receive a no-op disposer. ## Register only the tools this page should offer Pass the generated web tool definitions to registerWebMcpTools. Omitting an exposure policy is deliberate: it registers read-only tools only. The returned disposer removes every registration together. webmcp.client.ts typescript ``` import { webMcpToolDefinitions } from '@happyvertical/smrt-virt-web'; import { registerWebMcpTools } from '@happyvertical/smrt-web'; // Omitting an exposure policy registers read-only tools only. const dispose = registerWebMcpTools(webMcpToolDefinitions); // Remove this page's tools when the surface unmounts. dispose(); ``` ## Opt into more than read-only Name the effects a page may register, prefix its tool names to avoid collisions between two Providers on one page, and cap how many tools one call may register. No implicit budget applies to a whole-manifest read registration. webmcp.client.ts typescript ``` registerWebMcpTools(webMcpToolDefinitions, { effects: ['read', 'write', 'destructive'], namespace: 'admin', maxTools: 32 }); ``` ## A component's own tool follows the same policy useWebMcpTool registers one hand-written tool for a component's lifetime and routes it through smrt-web's registerWebMcpBespokeTool, so the same fail-closed classification filters it. A spec with no annotations, or whose annotations leave its effect undeclared, classifies destructive, non-idempotent, and open-world. It is excluded unless the policy allows destructive. The policy is the nearest Provider's webmcp.effects. The hook's own effects option applies only when no Provider ancestor declares a policy. An explicit Provider policy always wins, even a narrower one. - namespace and maxTools never apply to a bespoke tool. The author already chose a stable name, and one tool never counts against a generated set's budget. - The generated Form webmcp tool declares itself write-class, never destructive. It falls back to a read and write policy only when no ancestor Provider declares webmcp.effects. - On a browser without WebMCP, or when policy excludes the tool's effect, the call is a no-op and its disposer is inert. OrderTable.svelte svelte ``` ``` ## Declare an interaction as data defineIntent, from the dependency-free @happyvertical/smrt-web/intents entry, declares a component-owned interaction in a .ts sidecar as plain data. The declaration names an id, a description, an optional capability, and a target: one browser registry — control or dataSurface — and what the intent does there. Call it at module scope with one object literal of literal values: no spreads, identifiers, conditionals, or computed keys. That static form is what a scanner reads without evaluating the module; anything computed keeps using useWebMcpTool. - Ids are lowercase and dot-namespaced with at least two segments. The WebMCP tool name is the id with . and - replaced by \_. An id resolving into the reserved smrt\_ui\_ prefix is rejected. So is a second id that derives a tool name an already declared intent derives. - capability resolves through the same fail-closed rule as every other declaration: omitted entirely, an intent classifies destructive, non-idempotent, and open-world. - The no-REST invariant: the declaration has no execute, fetch, url, route, endpoint, or method field and no field of function type. defineIntent rejects unknown keys and non-JSON values at runtime, and the tool's execute is constructed from target — no author-supplied callable ever runs. OrderTable.intents.ts typescript ``` import { defineIntent } from '@happyvertical/smrt-web/intents'; export const nextPageIntent = defineIntent({ id: 'orders.next_page', description: 'Advance the orders table by one page', capability: { effect: 'read', idempotent: false, openWorld: false }, target: { registry: 'dataSurface', controlId: 'next-page', kind: 'table' } }); ``` ## Bind it to what is mounted useViewIntent binds a declared intent to this component's mounted registry identity for exactly the component's lifetime. The identity is formId and controlId for a control intent, or surfaceId and kind for a data-surface one, with an optional subject for record-qualified identity. Registries come from the nearest Provider's WebMCP UI context or an explicit controlRegistry or dataSurfaceRegistry override; with neither, the binding is a silent no-op. Registration goes through registerWebMcpBespokeTool, so the intent inherits the policy above. Execution dispatches exactly one registry command as source: 'agent'. Staged review, the trusted local-gesture requirement, sensitivity, and writability apply unchanged, and there is no path to REST. - An identity whose shape does not match the intent's declared target, or that contradicts an identity the declaration pinned, throws. That is an author error, not an environment difference. - The compiler is imported from the /intents entry, so binding an intent never pulls the client-data engine into the page. - The six fixed smrt\_ui\_ tools are unchanged; intents sit above them. A derived name can still collide with a generated model tool or, under a custom UI prefix, with a fixed UI tool. Keep an intent's first id segment out of your model names, or give the generated set a namespace. OrderTable.svelte svelte ``` ``` ## The page session is the security boundary A generated model tool executes over the generated REST fetchers as the authenticated page user. A declared interaction has no path to REST at all, and a component tool runs only the code its author wrote. If that code calls the application's routes, the same server checks apply; if it does not, there is no server round-trip to fail closed. REST authentication, tenant gates, writable-field rules, sensitive-field policy, and operation permissions are enforced in their existing server boundary rather than copied into browser tool code. The exposure policy above is a capability choice, not an authorization boundary. [Exposure is not authorization →]() **Related pages** [Agents overview]()[One vocabulary, four projections]()[State, not the screen]()[UI overview]() **Packages used in this guide** [@happyvertical/smrt-web]()[@happyvertical/smrt-core]()[@happyvertical/smrt-app-mcp]()[@happyvertical/smrt-svelte]() **Canonical sources** [smrt-web package instructions]()[smrt-svelte package instructions]()[smrt-web package README]() **On this page** --- [← Developer tooling]() Developer tooling # Runtime MCP surfaces for application agents Generated local MCP, hosted application MCP, and WebMCP use the same @smrt() model. They run at different boundaries and do not give an application agent the same identity or authority. Verified against s-m-r-t 0.55.16 **In plain English** These surfaces let an application agent operate real data. Local stdio gets credentials from its environment. Hosted MCP resolves a principal per request. WebMCP uses the signed-in browser session. ## Describe the server once createMcpAppServer wraps the generated core tools with an application allow-list and returns listTools and callTool. The allow-list determines which classes are reachable. Public tool patterns determine what an unauthenticated caller can see. The tool policy evaluates each principal. Workflow assertions run before generated dispatch. src/lib/server/mcp.ts typescript ``` import { createMcpAppServer, McpAccessError } from '@happyvertical/smrt-app-mcp'; import { adminResources } from '$lib/admin/resources'; import { getDbConfig } from './db'; export const mcpServer = createMcpAppServer({ smrtOptions: () => ({ db: getDbConfig() }), serverInfo: { name: 'my-app', version: '0.1.0' }, allowedClassNames: adminResources.map((r) => r.className), // Empty by default, so nothing is anonymous until an operator opts in. // Until a pattern is listed, no tool passes the base rule for a caller with // no principal, and the unauthenticated branch below is never reached. publicToolPatterns: () => (process.env.MY_APP_PUBLIC_MCP_TOOLS ?? '') .split(',') .map((s) => s.trim()) .filter(Boolean), toolPolicy: ({ tool, principal }) => { if (!principal) return tool.name === 'application_get'; if (principal.kind === 'human') return principal.roles?.includes('admin') ?? false; return principal.kind === 'service' && principal.scopes?.includes('mcp:applications') === true; }, workflowAssertions: { application_update: (args, user) => { if (!user?.id) throw new McpAccessError(401, 'sign in first'); args.approvedByUserId = user.id; } } }); ``` ## Mount it as one route mountMcpRoute is the modern, fetch-style Streamable HTTP endpoint. It serves server/discover, tools/list, and tools/call. The tools capability is always present; the optional tasks extension is advertised only when an allowed object enables a task action. Tool discovery is deterministically ordered by name. src/routes/api/mcp/+server.ts typescript ``` import { mountMcpRoute } from '@happyvertical/smrt-app-mcp/sveltekit'; import { mcpServer } from '$lib/server/mcp'; export const POST = mountMcpRoute(mcpServer); ``` [Package reference →]() ## Opt long-running actions into durable tasks Long-running item actions can opt into the experimental io.modelcontextprotocol/tasks extension. Tasks are disabled by default. List each task action in the object’s MCP configuration. Align the jobs runner dispatch allowlist when the class uses backgroundEligible markers. - Task-aware clients use tasks/get, tasks/update, and tasks/cancel to observe or control the durable job. - An application deployment must run a TaskRunner for the mcp-tasks queue; generated stdio servers start that worker automatically. - Task lifecycle calls require a stable authenticated principal id, plus tenantId for tenant-scoped objects. - backgroundEligible is restrictive once the first method is marked, so mark every method the TaskRunner may dispatch. Report.ts typescript ``` import { backgroundEligible } from '@happyvertical/smrt-jobs'; @smrt({ mcp: { include: ['generateReport'], tasks: ['generateReport'] } }) class Report extends SmrtObject { @backgroundEligible() async generateReport() { return buildReport(this.id); } } ``` ## Stateless by construction The route builds a fresh protocol server for every HTTP request. It does not issue or depend on a session id, sticky load-balancer routing, or a held event stream, so it runs behind ordinary round-robin deployment. The mount exposes no subscription capability, and subscription requests are refused as a JSON-RPC error before any stream opens. - Persist multi-step workflow progress in application objects. - Pass the explicit object id back into the next tool call. - Neither MCP sessions nor request principal state are held between nodes. ## Request metadata is validated, not trusted Stock MCP clients send a required Mcp-Method header, and Mcp-Name for a tool call. The mount validates them against the JSON-RPC body and returns the protocol HeaderMismatch error, code -32020 with HTTP 400, for a missing or mismatched header. Header presence is not authentication. [Protocol and conformance detail →]() ## Policy runs on discovery and on the call The tool policy evaluates every tool that passes the allow-list and the base public or authenticated rule. The policy runs during discovery and direct calls. Returning false hides the tool from discovery and denies a direct call with the non-retryable mcp\_tool\_access\_denied code. A thrown policy error is treated as a denial, so policy failures fail closed. - On the modern mount the denial arrives as a JSON-RPC protocol error carrying the code and a retryable flag in its data. - The deprecated REST aliases instead return the older ok, code, message, status, and retryable body. - Neither shape includes tool, principal, scope, or policy-error detail. - A tool outside the application allow-list receives the safe not-found behavior. - Unauthenticated callers see only the tools selected by public tool patterns. ## Identity comes from the application SvelteKit mounts resolve the request principal once and use it for both discovery and calls. McpAppPrincipal has optional id, kind, roles, and scopes fields. This flexible shape represents a person or scoped service without encoding the application identity model. A missing principal means the request is unauthenticated. - resolvePrincipal is the current hook for applications that store the principal elsewhere. - resolveUser remains as a legacy compatibility alias. - resolveAuthenticated is a deprecated legacy boolean gate, consulted only when resolvePrincipal is absent. Only a false result clears the principal. An older mount that returns true keeps its calls without a user. Discovery then uses the old boolean behavior. Migrate the mount to resolvePrincipal. ## Catalog caching is private until proven shareable tools/list emits the required cache metadata with a one-day private default. Shared caching is intentionally exceptional: a public catalog must be a reviewed set where every allowed tool is unauthenticated, read-only, and global. The server verifies that shape, including the absence of tenant-scoped tools and principal-aware policy, and falls back to private otherwise. public-catalog.ts typescript ``` // Only for a reviewed catalog with no tenant-scoped or principal-gated tools. toolListCache: { cacheScope: 'public', publicCatalog: true } ``` ## Authorization is terminated in front of the route This package trusts the principal supplied by the application adapter. It does not implement an OAuth authorization server and does not validate bearer tokens itself. For a public deployment, terminate OAuth at the gateway. Validate the token signature, issuer, audience or resource, expiry, and scopes. Populate the request principal, tenant, and permissions only after validation succeeds. - Use one stable HTTPS issuer identifier per authorization server. - Issuer values are compared as exact strings; a trailing-slash difference aborts the grant. - Prefer a pre-registered client, then a Client ID Metadata Document, then dynamic registration. - Keep public tool patterns empty unless anonymous read access is deliberate. - Preserve tenant isolation and the allow-list for every invocation. ## Generated stdio stays local The generated local MCP server runs beside the application. It obtains credentials from its environment and has no per-request authorization principal, so it must not be exposed remotely. Use the smrt-mcp-bridge binary to reach a deployed application from a local stdio client. @happyvertical/smrt-app-cli publishes this bridge. It authenticates through the first-party terminal device flow. The bridge sends stored tokens only to their associated server. [Task guide: expose your app over MCP →]()[Reference: generated interfaces →]()[Capability: WebMCP in the browser →]() ## WebMCP stays in the browser session WebMCP is not the local stdio server and it is not the hosted application MCP route. The page registers selected tool descriptions in a compatible browser. Tool execution uses the generated REST client as the signed-in page user. Existing authentication, tenant, permission, writable-field, and field-policy checks stay in the request path. - The browser page selects which generated tool descriptions it registers. - The page session supplies the application identity. WebMCP does not introduce a coding-agent identity. - The browser surface does not give the Development MCP server access to application data. - Use hosted application MCP when a remote agent runs outside the browser session. [WebMCP capability →]()[Reference: generated interfaces →]()[Reference: security defaults →]() **Related pages** [Expose an application over MCP]()[Generated interfaces reference]()[Security reference]()[Development MCP]() **Packages used in this guide** [@happyvertical/smrt-app-mcp]()[@happyvertical/smrt-core]()[@happyvertical/smrt-app-cli]() **Canonical sources** [smrt-app-mcp README]()[smrt-app-mcp AGENTS.md]()[Remote MCP authorization contract]() **On this page** --- [← Developer tooling]() Developer tooling # The development MCP server @happyvertical/smrt-dev-mcp gives a coding agent the same deterministic workspace and installed-package knowledge as the CLI. It also provides class generation, project introspection, and portable review and architecture bundles. Verified against s-m-r-t 0.55.16 **In plain English** The default read-only stdio server helps a coding agent understand your codebase. It returns generated source as output but never writes it. The Level 1 and Level 3 runtime paths have their own scoped access to framework tables or the live application registry. ## It inspects the workspace, not the running application The default smrt-dev-mcp stdio server reads source, manifests, and authored documentation from a workspace on disk. It is read-only, never writes files, never executes generated code, and has no access to your application database, principals, or tenants. Level 1 and Level 3 are separate runtime paths; live data operations belong to generated local MCP, hosted application MCP, or WebMCP. - Application-agent surfaces are generated from your @smrt() objects and perform live data operations. - Development MCP provides code generation output and project analysis for a coding agent. - Its review and architecture tools are model-agnostic and call no model provider. - The standalone install lists all 21 tools but ships no smrt-core. Code generation, the knowledge and context tools, agent skills, and introspection of a built manifest work without a runtime. Source-scan enrichment and the runtime tools need @happyvertical/smrt-core installed in the selected project; without it they return a sanitized runtime\_dependency\_unavailable diagnostic. - One server process loads one runtime project. A request for another project fails with runtime\_project\_mismatch; start a separate server or restart it for that project. [Generated and application MCP →]()[The broader pattern: agent-legible applications →]() ## Inspect the complete declared workspace view A coding agent can inspect project source, runtime manifests, knowledge artifacts, and installed package contracts through structured tools and resources. The results identify packages, objects, fields, relationships, generated interfaces, and authored documentation. Coverage and diagnostics state what the server did not find. - Source and manifest paths show where each declared object came from. - Object results include fields, relationships, methods, interface settings, and package identity when the selected evidence contains them. - Installed package entries include the package version and the hash of its version-matched AGENTS.md. - Review and architecture bundles carry the same coverage and diagnostics as the underlying index. [Knowledge evidence and discovery order →]()[Reference: generated interfaces →]() ## Choose the runtime path that fits the question smrt-dev-mcp has three read-only runtime paths. The normal stdio server reads declared workspace evidence. The Level 1 diagnostics inspect selected framework tables in a development database. Level 2 boots a confined registry over loopback HTTP. Level 3 runs inside a SvelteKit development server and reads that app's live registry. - Level 1 returns migration, job, schedule, dispatch, change, and registry-drift diagnostics. It never returns payloads, agent configuration, dispatch metadata, database paths, or driver error details. - Level 2 exposes runtime-registry, runtime-object, runtime-schema-diff, and the six Level 1 diagnostics through a positive, loopback-only catalog. It boots once from project manifests and does not import application code. - Level 3 adds registry-live inside the app. It is available only in SvelteKit development mode and shares the app root and configured database. - None of these paths mounts generated CRUD, custom actions, do(), or an application-agent data surface. [Development MCP runtime reference →]()[Upstream: live runtime bridge →]() ## Install it and point a client at the stdio server The package publishes a smrt-dev-mcp binary. For a project-local client, declaring the stdio server in .mcp.json is enough; a compatible client launches it on demand. .mcp.json json ``` { "mcpServers": { "smrt-dev-mcp": { "type": "stdio", "command": "npx", "args": ["-y", "@happyvertical/smrt-dev-mcp"] } } } ``` ## Prefer an absolute launcher in global configuration A user-level MCP client can start servers from repositories that do not install this package. A package-manager launcher can run dependency or build-approval checks before the server starts. Install the package in a stable location. Point the client at the built server with an absolute path. config.toml toml ``` [mcp_servers.smrt-dev-mcp] command = "node" args = ["/absolute/path/to/node_modules/@happyvertical/smrt-dev-mcp/dist/index.js"] ``` ## Use the current tool names Tool names are stable strings. Generation and introspection cover the code. The knowledge tools mirror the CLI commands. The context builders return prompt bundles for any model. - Generation and introspection: generate-smrt-class, introspect-project, review-smrt-project. - Freshness: check-knowledge-freshness and the current knowledge index. - build-context takes task: "review" or task: "architecture". It replaces the separate review and architecture builders. - smrt-review and smrt-architecture remain compatibility names for one minor release and report a deprecated-tool diagnostic. - Bundled skills: list-agent-skills, get-agent-skill. ## Run the confined runtime host when a registry must boot The Level 2 HTTP host boots manifests in one confined process. It does not import project code. Use it for a sanitized registry snapshot, one object's fields and generated DDL, or a read-only schema comparison. - The host binds loopback only and requires a bearer token on every request. It uses stateless Streamable HTTP and does not issue MCP session ids. - Its catalog contains runtime-registry, runtime-object, runtime-schema-diff, and the six Level 1 tools. Restart it after rebuilding manifests. terminal bash ``` SMRT_DEV_MCP_TOKEN=local-dev-token smrt-dev-mcp --http --port 3939 --project . ``` ## Mount the in-app runtime path only in SvelteKit development Level 3 uses the app's live ObjectRegistry, so it sees Vite SSR HMR registrations without restarting. Install smrt-dev-mcp as a development dependency and enable the generated route explicitly. The smrt() preset has no option for this route. An application that wants it calls the two public plugins, smrtConsumer() and smrtPlugin(), in place of the preset and passes devPlaneRoute to smrtPlugin. - GET /api/\_dev lists the JSON catalog, GET or POST /api/\_dev/\ invokes a tool, and POST /api/\_dev/mcp serves MCP. - The route is 404 outside development mode and 503 until SMRT\_DEV\_MCP\_TOKEN is set. It accepts only loopback Host and Origin requests with that bearer token. - Use smrt dev:runtime \ with --url or SMRT\_DEV\_PLANE\_URL to call the in-app route; without a URL it uses the Level 2 boot locally. vite.config.ts ts ``` smrtPlugin({ svelteKit: { enabled: true, devPlaneRoute: { enabled: true } } }); ``` ## Every tool declares the same result envelope Each tool publishes an output schema requiring ok, coverage, diagnostics, and data, and returns that object as structured content beside the human-readable text result. data preserves the tool payload unchanged, while coverage and diagnostics are promoted only when the underlying result reports them. A failure returns ok false with an error-severity diagnostic rather than an empty success. tool-result.json json ``` { "ok": true, "coverage": { "workspaceGlobs": ["packages/*", "apps/*"], "workspaceGlobSource": "pnpm-workspace.yaml", "packageDirs": ["packages/billing", "packages/ui"], "packagesWithObjects": ["@acme/billing (7, domain-artifact)"], "packagesWithoutObjects": [ { "name": "@acme/ui", "reason": "no-smrt-objects-in-sources", "checkedPaths": [], "remedy": "No @smrt() classes were found in this package. Expected if it is a UI, contract, or tooling package." } ] }, "diagnostics": [], "data": {} } ``` ## Responses are budgeted, and the budget is honest Knowledge and introspection tools return a summary by default and accept detail full for the complete payload. An introspection response that exceeds its character budget reports a truncated block naming the omitted count and how to filter, rather than being silently cut. Project metadata and diagnostics are always returned in full, because a diagnostic is how discovery reports that it found nothing. - maxChars overrides the introspection budget and applies to the objects payload. - Summary architecture and review results list authored docs by path instead of embedding them. - The equivalent CLI commands request full detail, so their output is unaffected. ## Catalogs are cached privately The static tools and prompts catalogs advertise a one-day private cache lifetime. Workspace knowledge resources are also private, but they use a zero lifetime. The server rebuilds them from the current workspace for every request. The transport has no visible invalidation signal to support a longer lifetime. [Shared runtime catalogs →]()[Cache and tenancy safety →]() ## An agent workflow from source to runtime evidence The tools compose into a repeatable loop. Deterministic context comes first, the model reads the actual diff, and the checker runs again after the edits land. - Run the downstream build or dev server so the domain artifact exists. - Call introspect-project to establish the declared object and package view. - Call check-knowledge-freshness before and after edits. - Call build-context with task review or task architecture and the changed files, scope, and optional package. - Send the returned prompt bundle to the model of your choice. - Use runtime-object or runtime-schema-diff only when declared evidence needs a bounded development-runtime check. [The commands behind these tools →]()[Package reference →]() ## Resources, prompts, and the bundled skill Besides tools, the server exposes the composed project knowledge and package-scoped knowledge as resources, and publishes review and architecture prompts. It also ships one harness-agnostic agent skill, smrt-code-review, which get-agent-skill returns as Markdown with YAML frontmatter that skill-unaware harnesses can ignore. [How the skill is packaged →]() **Related pages** [Agent-legible applications]()[Knowledge tooling]()[Generated and app MCP]() **Packages used in this guide** [@happyvertical/smrt-dev-mcp]()[@happyvertical/smrt-scanner]()[@happyvertical/smrt-core]() **Canonical sources** [smrt-dev-mcp README]()[smrt-dev-mcp AGENTS.md]() **On this page** --- [← Reference]() Reference # Generated interfaces fail closed Generated routes require an authenticated principal unless public access is explicitly declared, and field policy is applied before data leaves or enters the application. **In plain English** Private is the default. Secret fields stay out of responses and filters, while read-only and server-managed fields are removed from client writes. ## Authentication is the default When api.public is not set, generated reads and writes require a resolved principal. Use public: "read" to open only reads or public: true when every generated action is intentionally public. Invoice.ts typescript ``` @smrt({ api: { include: ['list', 'get', 'create', 'update'] } }) class Invoice extends SmrtObject { amount = 0; } // No api.public declaration: generated routes require authentication. ``` ## Sensitive fields close both read paths A sensitive field is removed from public serialization and rejected in collection filters. Both protections matter: hiding output alone would still allow a caller to probe a secret value through repeated where clauses. ## Write policy blocks mass assignment Generated create and update handlers filter the request body before the model receives it. They remove read-only fields, IDs, timestamps, tenant IDs, underscore-prefixed keys, and fields outside an optional writable allowlist. ## Application code still owns its boundary Generated routes enforce these defaults. Custom actions, jobs, direct collection calls, external callbacks, and product-specific threat models still need deliberate principal, tenant, permission, and input checks. Security The defaults do not extend to hand-written paths A generated route resolves the principal, applies the tenant scope, and filters fields. Hand-written code does not get these controls automatically. A custom endpoint, background job, webhook receiver, or direct collection call uses the supplied authority. Treat each hand-written entry point as unauthenticated until it proves otherwise. ## Authentication is not authorization These defaults answer whether a caller is known. Authorization is a separate decision about the operation and tenant. An application guard checks the permission catalog. On Postgres, generated row-level security policies can also check it. ## Field policy is presentation, not enforcement A field hidden by field policy is still writable through the generated API unless the model says otherwise. A policy cannot store a default on a sensitive, transient, or read-permission-gated field, and the batch resolve response omits those fields for every caller. Warning Hiding a field does not protect it Field policy decides what an interface shows, not what the API accepts. A field you hide is still writable unless the model marks it read-only, server-managed, or outside the writable allowlist. Put the guarantee on the model and treat the policy as presentation. **Related pages** [Authorization model]()[Field policies]()[Field policy API]() **Packages used in this guide** [@happyvertical/smrt-core]()[@happyvertical/smrt-users]()[@happyvertical/smrt-tenancy]() **On this page** --- Reference # Evidence Each claim the site makes about the framework, with the page that explains it and the released source it was checked against. Package sources are the AGENTS.md contracts shipped in s-m-r-t 0.57.40; the site row links a commit of this repository. | Claim | Source | | --- | --- | | One record description becomes both the human screens and the agent tools. Explained at [What is a SAADL?]() | [Core release contract ↗]() [#]() | | Every control has a stable name; an agent can stage a value only where sensitivity rules allow, and only a person’s confirmation applies it. Explained at [Agent-assisted forms]() · Try it: [Agent-aware form demo]() | [smrt-ui release contract ↗]() [#]() | | Selected operations become agent tools with the same names, inputs, and policy as the human interface. Explained at [Agents]() · Try it: [UI overview]() | [smrt-web release contract ↗]() [#]() | | However a request arrives, the same permission checks apply — down to the stored record. Explained at [Security defaults]() · Try it: [Governed interaction demo]() | [Application MCP release contract ↗]() [#]() | | A coding agent’s development server reads the project and its installed packages. It sees a development database’s system tables only when one is configured, and never your records. Explained at [Agent-legible applications]() | [Development MCP release contract ↗]() [#]() | | Native mobile shares one Kotlin Multiplatform core behind separate Compose and SwiftUI screens. Explained at [Mobile]() | [Mobile source contract (source-only; package publishing deferred) ↗]() [#]() | | This site itself runs on the released packages it documents, not a separate internal build. Explained at [Component playground]() | [Documentation site source ↗]() [#]() | The audit wording for each row lives with its id in the site source, ` src/lib/data/why-smrt-claims.ts `. A row is removed when its source no longer supports it. --- [← Docs]() # s-m-r-t playground Package-owned components and working views Find a component Theme 🔷 Material💎 Glass◻️ Studio🟠 s-m-r-t🔶 Day Shift UI Foundation **Overview** @happyvertical/smrt-ui ## UI Foundation Provider-free controls and data primitives rendered in the active s-m-r-t theme. 11 components ### Components --- Reference family # API Reference Start with the generated-interface contract. Then choose a package or a supporting contract. The model metadata remains the source for each generated surface. ## Choose the contract [**Generated interfaces** Learn the shared model contract behind REST, MCP, WebMCP, and CLI.]()[**Package REST, MCP, WebMCP, and CLI tabs** Choose a package and inspect each generated surface beside its source evidence.]()[**Authorization and security** Apply the permission catalog, guards, row security, and generated-route defaults.]()[**Field policy API** Resolve the field metadata that generated human interfaces consume.]()[**Configuration** Set generated-surface options through the canonical configuration contract.]()[**Decorators** Declare the model and field metadata that generation reads.]() --- Reference # Package reference Open a package and read its purpose. Browse its components and playground entries. Check how its models appear through REST, MCP, WebMCP, and CLI. Packages 75 Release 0.57.40 Search 75 resultsOverview · Components · Playground · REST · MCP · WebMCP · CLI ## Foundation 15 [` @happyvertical/smrt-core `v0.57.40 The object model, persistence layer, AI operations, manifests, and generated interfaces at the center of every s-m-r-t app. runtime**→**]()[` @happyvertical/smrt-config `v0.57.40 One configuration layer for s-m-r-t packages, runtime settings, safe exports, and secret-aware loading. runtime**→**]()[` @happyvertical/smrt-types `v0.57.40 Shared cross-package TypeScript contracts and enums with almost no runtime weight. runtime**→**]()[` @happyvertical/smrt-scanner `v0.57.40 Fast OXC-based source scanning that turns decorated classes into the s-m-r-t manifest. tooling**→**]()[` @happyvertical/smrt-tenancy `v0.57.40 Automatic tenant isolation, context propagation, required or optional scope, and tenant-aware query enforcement. 2 playground entries**→**]()[` @happyvertical/smrt-users `v0.57.40 Users, sessions, memberships, hierarchical tenants, roles, fine-grained permissions, access requests, and Postgres RLS. 4 playground entries**→**]()[` @happyvertical/smrt-profiles `v0.57.40 People, organizations, identities, metadata, and reciprocal or directional relationships. models**→**]()[` @happyvertical/smrt-languages `v0.57.40 Code-first language strings with application, config, and tenant overrides plus AI-assisted translation. models**→**]()[` @happyvertical/smrt-prompts `v0.57.40 A typed prompt registry with editable, tenant-aware overrides and predictable resolution. models**→**]()[` @happyvertical/smrt-secrets `v0.57.40 Per-tenant secrets protected by envelope encryption, rotation, and audit trails. models**→**]()[` @happyvertical/smrt-features `v0.57.40 Code-first feature definitions with tenant-aware overrides and deterministic evaluation. models**→**]()[` @happyvertical/smrt-fields `v0.57.40*New* Layered field policy: per-field defaults, visibility tiers, labels, help, ordering, and organization locks resolved over the code seed at app, tenant, and user scope. 2 playground entries**→**]()[` @happyvertical/smrt-preferences `v0.57.40*New* Saved user-interface preferences: tenant defaults and per-user overrides for overview layouts and the app frame, validated per registered kind. models**→**]()[` @happyvertical/smrt-approvals `v0.57.40*New* A decision gate: revision-bound, single-use approvals with quorum, expiry, tenant policy, and an append-only event ledger. models**→**]()[` @happyvertical/smrt-webhooks `v0.57.40*New* Outbound webhook subscriptions with HMAC-signed delivery to public HTTPS endpoints, a durable jobs queue, retries, and a safe delivery log. 1 component**→**]() ## Agents & runtime 9 [` @happyvertical/smrt-agents `v0.57.40*New* Autonomous actors with scheduling, interests, dispatch, durable learning, principal execution, and safe agent-to-agent delegation. 3 playground entries**→**]()[` @happyvertical/smrt-personas `v0.57.40*New* Tenant-owned agent personalities that scope instructions, tools, identity, memory, feedback, and human-approved adaptation. 1 component**→**]()[` @happyvertical/smrt-jobs `v0.57.40 Persistent background work, schedules, retries, runners, queue controls, and operational visibility. 3 playground entries**→**]()[` @happyvertical/smrt-chat `v0.57.40*New* Rooms, direct messages, threads, persona-bound conversations, tool loops, the AssistantDock, helper preferences, and voice gateway turns. 3 playground entries**→**]()[` @happyvertical/smrt-app-mcp `v0.57.40 App-runtime MCP server scaffolding and transport adapters for exposing a s-m-r-t application over HTTP. runtime**→**]()[` @happyvertical/smrt-dev-mcp `v0.57.40 Development-time knowledge, review, architecture, introspection, and code-generation tools for AI coding agents. tooling**→**]()[` @happyvertical/smrt-playbooks `v0.57.40 Layered playbook definitions, app and tenant overrides, and plan resolution for agents: a named sequence of steps every agent surface follows. models**→**]()[` @happyvertical/smrt-mcp-apps `v0.57.40*New* A framework-neutral, browser-only view-side bridge for portable MCP Apps: lifecycle, correlated transport, and capability gates. runtime**→**]()[` @happyvertical/smrt-mcp-openai `v0.57.40*New* Optional OpenAI navigation, settings, context, messages, and composer mentions for authorized s-m-r-t MCP Apps. runtime**→**]() ## Web & UI 12 [` @happyvertical/smrt-ui `v0.57.40*New* Provider-free Svelte 5 components for accessible forms, agent-assisted controls, feedback, collections, charts, overlays, layouts, and themes. 5 playground entries**→**]()[` @happyvertical/smrt-svelte `v0.57.40*New* The top-of-stack Svelte integration: AppShell, Provider, rich forms, recipe screens, browser AI, live collections, and permissions. 105 components**→**]()[` @happyvertical/smrt-web `v0.57.40*New* A manifest-generated browser data runtime with typed collections, persistence, live updates, and offline mutation replay. runtime**→**]()[` @happyvertical/smrt-playground `v0.57.40 Shared package playground discovery, preview metadata, runtime hosting, and dev workbench components. 1 component**→**]()[` @happyvertical/smrt-app-cli `v0.57.40 A reusable branded CLI factory for s-m-r-t apps with decorator-driven resources and a stdio MCP bridge. tooling**→**]()[` @happyvertical/smrt-cli `v0.57.40 The framework developer CLI for manifests, database migrations, application operations, cookbooks, introspection, and generated resources. tooling**→**]()[` @happyvertical/smrt-vitest `v0.57.40 Vitest integration for manifest generation, package discovery, isolated databases, and Svelte setup. tooling**→**]()[` @happyvertical/smrt-template-sveltekit `v0.57.40 The recommended SvelteKit application scaffold: AppShell as the root layout, a server runtime built once, and smrt app one-liners for every lifecycle script. tooling**→**]()[` @happyvertical/smrt-template-site-static-json `v0.57.40 A static community-site scaffold with JSON data storage and package-owned UI conventions. tooling**→**]()[` @happyvertical/smrt-app-runtime `v0.57.40 Validated local, self-hosted, and cloud runtime composition for s-m-r-t applications, with a SvelteKit entry for server hooks. runtime**→**]()[` @happyvertical/smrt-workbench `v0.57.40 A shared developer workbench for s-m-r-t packages and consumer projects: package metadata, route modules, previews, scripts, docs, and manifests in one browser host. 1 component**→**]()[` @happyvertical/smrt-planner `v0.57.40*New* The s-m-r-t app planner as a mountable Svelte component with cookbooks, recipes, layout, theme, and export tabs, a typed command set, and a plan snapshot. 3 components**→**]() ## Content & media 11 [` @happyvertical/smrt-content `v0.57.40 Documents, articles, publication state, governed editing, contributions, references, and transparent review workflows. 7 playground entries**→**]()[` @happyvertical/smrt-assets `v0.57.40 Provider-neutral asset storage, metadata, versions, associations, and AI-assisted operations. 2 playground entries**→**]()[` @happyvertical/smrt-assets-local `v0.57.40 Local image metadata and variant processing for the s-m-r-t asset runtime. runtime**→**]()[` @happyvertical/smrt-assets-ergot `v0.57.40 Ergot-backed asset processing, search, workflows, and remote execution. runtime**→**]()[` @happyvertical/smrt-images `v0.57.40 Image galleries, uploads, editing, categorization, metadata extraction, and semantic search. 3 playground entries**→**]()[` @happyvertical/smrt-messages `v0.57.40 A unified STI hierarchy for email, social, and other communication channels, plus in-app notifications. 4 playground entries**→**]()[` @happyvertical/smrt-voice `v0.57.40 Voice profiles, source samples, cloning, synthesis, and timing data for spoken media. models**→**]()[` @happyvertical/smrt-video `v0.57.40 Characters, performers, scenes, production workflows, frames, and AI video operations. models**→**]()[` @happyvertical/smrt-social `v0.57.40 Connected social accounts, OAuth, multi-platform publishing, and scheduled posts. 1 component**→**]()[` @happyvertical/smrt-comments `v0.57.40*New* Tenant-scoped comments on any record, mention notification composition, and a browser-safe RecordComments component. 1 component**→**]()[` @happyvertical/smrt-ingestion `v0.57.40*New* Durable tenant-scoped intake: receipts, evidence, analysis attempts, proposals, and an action journal, with inbox and review components for people. 3 components**→**]() ## Business & operations 17 [` @happyvertical/smrt-commerce `v0.57.40 Customers, vendors, contracts, invoices, credit notes, payments, payment rails, tax codes, and fulfillment, with four recipes. 3 playground entries**→**]()[` @happyvertical/smrt-products `v0.57.40 A product catalog and reference module for package, federation, standalone, and browser-store consumption. models**→**]()[` @happyvertical/smrt-inventory `v0.57.40 Multi-location SKUs, stock levels, immutable movements, and guarded stock mutation. models**→**]()[` @happyvertical/smrt-manufacturing `v0.57.40 Industry-neutral bills of materials, cost rollups, and production orders. models**→**]()[` @happyvertical/smrt-ledgers `v0.57.40 Double-entry accounting, journal lifecycle, balance enforcement, and traceable entries. models**→**]()[` @happyvertical/smrt-subscriptions `v0.57.40 Tenant plans, grants, entitlement resolution, usage thresholds, and subscription UI. 3 components**→**]()[` @happyvertical/smrt-reports `v0.57.40 Materialized aggregate read models with incremental refresh, schedules, and tenant fan-out, plus runtime reports compiled per principal from a stored spec, with browser surfaces. 6 playground entries**→**]()[` @happyvertical/smrt-analytics `v0.57.40 Analytics properties, streams, server-side events, and useful reporting surfaces. 3 playground entries**→**]()[` @happyvertical/smrt-ads `v0.57.40 Priority-based ad delivery, weighted variations, and immutable event tracking. models**→**]()[` @happyvertical/smrt-marketing `v0.57.40 Cross-channel campaigns, immutable performance snapshots, and computed budget pacing. 5 components**→**]()[` @happyvertical/smrt-affiliates `v0.57.40 Partners, tiered commissions, attribution, and payout processing. Now a compatibility shim over the smrt-sales commissions module — new applications should use smrt-sales directly. models**→**]()[` @happyvertical/smrt-sales `v0.57.40 Provider-neutral agreement execution, CRM, referral intake and attribution, and a neutral commissions core. 14 components**→**]()[` @happyvertical/smrt-projects `v0.57.40 Provider-neutral projects, repositories, issues, pull requests, and the time workflows re-exported from smrt-timesheets. 3 playground entries**→**]()[` @happyvertical/smrt-support `v0.57.40 Channel-neutral support cases with lifecycle, routing, service targets, escalation, and auditable service time. 5 components**→**]()[` @happyvertical/smrt-timesheets `v0.57.40*New* Shared time entries: who worked how long on what, approval and correction, and immutable charge and compensation snapshots taken at approval. 5 components**→**]()[` @happyvertical/smrt-expenses `v0.57.40*New* Expense records: a cost incurred against a job, work package, or project, with deduplicated receipts, an explicit review, reimbursement, and purchase-order drawdown. 5 components**→**]()[` @happyvertical/smrt-human-resources `v0.57.40*New* HR records: who works for an organization, as what, and with what standing. Employment with dated terms, and qualifications with expiry. 4 components**→**]() ## Domain models 7 [` @happyvertical/smrt-events `v0.57.40 Deeply nested events, series, participants, placements, and meeting presentation. 1 playground entries**→**]()[` @happyvertical/smrt-places `v0.57.40 Hierarchical places, geocoding, lookup-or-create, and proximity search. models**→**]()[` @happyvertical/smrt-facts `v0.57.40 Distributed knowledge with provenance, confidence, semantic reconciliation, and evolution chains. models**→**]()[` @happyvertical/smrt-properties `v0.57.40 Digital properties and nested zones for content, ads, and application placement. models**→**]()[` @happyvertical/smrt-sites `v0.57.40 Multi-tenant site lifecycle, configuration, and prioritized agent bindings. models**→**]()[` @happyvertical/smrt-tags `v0.57.40 Context-scoped hierarchical tags, aliases, and multi-language labels. models**→**]()[` @happyvertical/smrt-gnode `v0.57.40*Not implemented* Federation scaffolding for gnode knowledge bases: published types and class shells, with none of the discovery or exchange behavior implemented yet. runtime**→**]() ## Mobile 4 [` @happyvertical/smrt-mobile `v0.57.40 Kotlin Multiplatform state and services for offline packs, durable writes, evidence capture, authentication, networking, and cross-platform presenters. mobile**→**]()[` @happyvertical/smrt-mobile-contract `v0.57.40 Manifest and allowlist code generation into mobile contracts and Kotlin or Swift DTOs. tooling**→**]()[` @happyvertical/smrt-android `v0.57.40 Compose shell, s-m-r-t theme, and Android adapters for barcode, speech, on-device AI, secure auth, and storage. mobile**→**]()[` @happyvertical/smrt-ios `v0.57.40 SwiftUI shell, s-m-r-t theme, and iOS adapters for VisionKit, Speech, Foundation Models, Keychain, and native storage. mobile**→**]() --- Generated Reference # UI component reference Search the public component exports across every installed ` @happyvertical/smrt-* ` package. Each contract is read from the declaration files in release 0.57.40. Every prop and type here is generated from the shipped declarations and is accurate. 2933 of 3099 props and 153 of 412 components also carry prose written in the package. The rest are listed without description, and say so. Search components, props, or import paths 412 public exports ## Agents · Components 9 - [**AgentAdminPanel** ` @happyvertical/smrt-agents/svelte/admin ` 9 props · 0 bindable · 1 callbacks]() - [**AgentAdminTabs** ` @happyvertical/smrt-agents/svelte/admin ` 8 props · 0 bindable · 1 callbacks]() - [**AgentDashboard** ` @happyvertical/smrt-agents/svelte ` 10 props · 0 bindable · 7 callbacks]() - [**AgentRunHistory** ` @happyvertical/smrt-agents/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**AgentScheduleForm** ` @happyvertical/smrt-agents/svelte ` 6 props · 0 bindable · 2 callbacks]() - [**AgentScheduleList** ` @happyvertical/smrt-agents/svelte ` 8 props · 0 bindable · 4 callbacks]() - [**AgentSettingsForm** ` @happyvertical/smrt-agents/svelte/admin ` 4 props · 0 bindable · 1 callbacks]() - [**AgentSettingsShell** ` @happyvertical/smrt-agents/svelte/admin ` 7 props · 0 bindable · 1 callbacks]() - [**ScheduleStatusBadge** ` @happyvertical/smrt-agents/svelte ` 2 props · 0 bindable · 0 callbacks]() ## Analytics · Components 6 - [**AnalyticsSummary** ` @happyvertical/smrt-analytics/svelte ` 1 props · 0 bindable · 0 callbacks]() - [**EventsTable** ` @happyvertical/smrt-analytics/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**PropertyInfo** ` @happyvertical/smrt-analytics/svelte ` 6 props · 0 bindable · 0 callbacks]() - [**PropertyStatusBadge** ` @happyvertical/smrt-analytics/svelte ` 1 props · 0 bindable · 0 callbacks]() - [**StatCard** ` @happyvertical/smrt-analytics/svelte ` 5 props · 0 bindable · 0 callbacks]() - [**TrendBadge** ` @happyvertical/smrt-analytics/svelte ` 2 props · 0 bindable · 0 callbacks]() ## Assets · Components 10 - [**ActionBar** ` @happyvertical/smrt-assets/svelte ` 6 props · 0 bindable · 4 callbacks]() - [**AssetDetail** ` @happyvertical/smrt-assets/svelte ` 11 props · 0 bindable · 8 callbacks]() - [**AssetGrid** ` @happyvertical/smrt-assets/svelte ` 7 props · 0 bindable · 3 callbacks]() - [**AssetList** ` @happyvertical/smrt-assets/svelte ` 7 props · 0 bindable · 3 callbacks]() - [**AssetManager** ` @happyvertical/smrt-assets/svelte ` 15 props · 0 bindable · 7 callbacks]() - [**AssetToolbar** ` @happyvertical/smrt-assets/svelte ` 11 props · 0 bindable · 8 callbacks]() - [**AttachmentList** ` @happyvertical/smrt-assets/svelte ` 13 props · 0 bindable · 1 callbacks]() - [**AttachmentPanel** ` @happyvertical/smrt-assets/svelte ` 14 props · 0 bindable · 1 callbacks]() - [**AttachmentUpload** ` @happyvertical/smrt-assets/svelte ` 21 props · 0 bindable · 0 callbacks]() - [**CreateAssetModal** ` @happyvertical/smrt-assets/svelte ` 4 props · 0 bindable · 2 callbacks]() ## Chat · Components 36 - [**AgentChat** ` @happyvertical/smrt-chat/svelte ` 7 props · 0 bindable · 3 callbacks]() - [**AgentSelector** ` @happyvertical/smrt-chat/svelte ` 2 props · 0 bindable · 1 callbacks]() - [**AgentSessionPanel** ` @happyvertical/smrt-chat/svelte ` 4 props · 0 bindable · 2 callbacks]() - [**AssistantChoiceCards** ` @happyvertical/smrt-chat/svelte ` 6 props · 0 bindable · 5 callbacks]() - [**AssistantComposer** ` @happyvertical/smrt-chat/svelte ` 13 props · 0 bindable · 2 callbacks]() - [**AssistantDock** ` @happyvertical/smrt-chat/svelte ` 35 props · 0 bindable · 6 callbacks]() - [**AssistantQuestionForm** ` @happyvertical/smrt-chat/svelte ` 5 props · 0 bindable · 1 callbacks]() - [**AssistantThreadList** ` @happyvertical/smrt-chat/svelte ` 4 props · 0 bindable · 2 callbacks]() - [**Avatar** ` @happyvertical/smrt-chat/svelte ` 4 props · 0 bindable · 0 callbacks]() - [**CaptionOverlay** ` @happyvertical/smrt-chat/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**ChatLayout** ` @happyvertical/smrt-chat/svelte ` 6 props · 0 bindable · 2 callbacks]() - [**ChatTab** ` @happyvertical/smrt-chat/svelte ` 7 props · 0 bindable · 4 callbacks]() - [**ChatTabList** ` @happyvertical/smrt-chat/svelte ` 3 props · 0 bindable · 2 callbacks]() - [**ChatTabs** ` @happyvertical/smrt-chat/svelte ` 7 props · 0 bindable · 4 callbacks]() - [**FileUpload** ` @happyvertical/smrt-chat/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**FloatingAssistant** ` @happyvertical/smrt-chat/svelte ` 41 props · 0 bindable · 6 callbacks]() - [**HeardCaptions** ` @happyvertical/smrt-chat/svelte ` 6 props · 0 bindable · 0 callbacks]() - [**HelperControlPanel** ` @happyvertical/smrt-chat/svelte ` 6 props · 0 bindable · 2 callbacks]() - [**LinkPreview** ` @happyvertical/smrt-chat/svelte ` 4 props · 0 bindable · 0 callbacks]() - [**MemberList** ` @happyvertical/smrt-chat/svelte ` 2 props · 0 bindable · 1 callbacks]() - [**MentionAutocomplete** ` @happyvertical/smrt-chat/svelte ` 5 props · 0 bindable · 2 callbacks]() - [**MessageInput** ` @happyvertical/smrt-chat/svelte ` 5 props · 0 bindable · 2 callbacks]() - [**MessageItem** ` @happyvertical/smrt-chat/svelte ` 6 props · 0 bindable · 4 callbacks]() - [**MessageList** ` @happyvertical/smrt-chat/svelte ` 5 props · 0 bindable · 3 callbacks]() - [**MiniChat** ` @happyvertical/smrt-chat/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**ModelPicker** ` @happyvertical/smrt-chat/svelte ` 5 props · 0 bindable · 1 callbacks]() - [**ReactionPicker** ` @happyvertical/smrt-chat/svelte ` 2 props · 0 bindable · 1 callbacks]() - [**ReadReceipts** ` @happyvertical/smrt-chat/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**RoomCreateDialog** ` @happyvertical/smrt-chat/svelte ` 3 props · 0 bindable · 2 callbacks]() - [**RoomHeader** ` @happyvertical/smrt-chat/svelte ` 4 props · 0 bindable · 2 callbacks]() - [**RoomList** ` @happyvertical/smrt-chat/svelte ` 4 props · 0 bindable · 2 callbacks]() - [**SearchMessages** ` @happyvertical/smrt-chat/svelte ` 5 props · 0 bindable · 3 callbacks]() - [**SpokenCaptions** ` @happyvertical/smrt-chat/svelte ` 7 props · 0 bindable · 0 callbacks]() - [**ThreadPanel** ` @happyvertical/smrt-chat/svelte ` 5 props · 0 bindable · 2 callbacks]() - [**ToolCallDisplay** ` @happyvertical/smrt-chat/svelte ` 4 props · 0 bindable · 2 callbacks]() - [**UserPresence** ` @happyvertical/smrt-chat/svelte ` 2 props · 0 bindable · 0 callbacks]() ## Commerce · Components 28 - [**CustomerDetail** ` @happyvertical/smrt-commerce/svelte ` 12 props · 0 bindable · 0 callbacks]() - [**CustomerDirectory** ` @happyvertical/smrt-commerce/svelte ` 24 props · 0 bindable · 0 callbacks]() - [**CustomerForm** ` @happyvertical/smrt-commerce/svelte ` 19 props · 0 bindable · 0 callbacks]() - [**CustomerSelect** ` @happyvertical/smrt-commerce/svelte ` 15 props · 0 bindable · 2 callbacks]() - [**InvoiceActions** ` @happyvertical/smrt-commerce/svelte ` 10 props · 0 bindable · 7 callbacks]() - [**InvoiceAllocationFields** ` @happyvertical/smrt-commerce/svelte ` 9 props · 0 bindable · 0 callbacks]() - [**InvoiceCard** ` @happyvertical/smrt-commerce/svelte ` 6 props · 0 bindable · 1 callbacks]() - [**InvoiceEditor** ` @happyvertical/smrt-commerce/svelte ` 10 props · 0 bindable · 0 callbacks]() - [**InvoiceHeader** ` @happyvertical/smrt-commerce/svelte ` 10 props · 0 bindable · 1 callbacks]() - [**InvoiceLineItems** ` @happyvertical/smrt-commerce/svelte ` 10 props · 0 bindable · 3 callbacks]() - [**InvoiceRecordScreen** ` @happyvertical/smrt-commerce/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**InvoiceReview** ` @happyvertical/smrt-commerce/svelte ` 1 props · 0 bindable · 0 callbacks]() - [**InvoiceTotals** ` @happyvertical/smrt-commerce/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**MoneyInvoiceEditor** ` @happyvertical/smrt-commerce/svelte ` 10 props · 0 bindable · 0 callbacks]() - [**PartyContactFields** ` @happyvertical/smrt-commerce/svelte ` 10 props · 0 bindable · 0 callbacks]() - [**PricingVersionDecision** ` @happyvertical/smrt-commerce/svelte ` 13 props · 0 bindable · 0 callbacks]() - [**PricingVersionSummary** ` @happyvertical/smrt-commerce/svelte ` 1 props · 0 bindable · 0 callbacks]() - [**PurchaseOrderEditor** ` @happyvertical/smrt-commerce/svelte ` 26 props · 0 bindable · 0 callbacks]() - [**PurchaseOrderHeaderForm** ` @happyvertical/smrt-commerce/svelte ` 13 props · 0 bindable · 0 callbacks]() - [**PurchaseSourceSelector** ` @happyvertical/smrt-commerce/svelte ` 9 props · 0 bindable · 0 callbacks]() - [**QuoteEditor** ` @happyvertical/smrt-commerce/svelte ` 21 props · 0 bindable · 0 callbacks]() - [**QuoteRevisionComparison** ` @happyvertical/smrt-commerce/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**QuoteRevisionHistory** ` @happyvertical/smrt-commerce/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**UnbilledItems** ` @happyvertical/smrt-commerce/svelte ` 5 props · 0 bindable · 2 callbacks]() - [**VendorDetail** ` @happyvertical/smrt-commerce/svelte ` 11 props · 0 bindable · 0 callbacks]() - [**VendorDirectory** ` @happyvertical/smrt-commerce/svelte ` 24 props · 0 bindable · 0 callbacks]() - [**VendorForm** ` @happyvertical/smrt-commerce/svelte ` 18 props · 0 bindable · 0 callbacks]() - [**VendorSelect** ` @happyvertical/smrt-commerce/svelte ` 15 props · 0 bindable · 2 callbacks]() ## Content · Components 38 - [**ArticleCard** ` @happyvertical/smrt-content/svelte ` 5 props · 0 bindable · 0 callbacks]() - [**ArticleList** ` @happyvertical/smrt-content/svelte ` 7 props · 0 bindable · 0 callbacks]() - [**ContentAgentChat** ` @happyvertical/smrt-content/svelte ` 10 props · 0 bindable · 2 callbacks]() - [**ContentBodyEditor** ` @happyvertical/smrt-content/svelte ` 19 props · 0 bindable · 7 callbacks]() - [**ContentBodyRenderer** ` @happyvertical/smrt-content/svelte ` 4 props · 0 bindable · 0 callbacks]() - [**ContentClaimAuditTool** ` @happyvertical/smrt-content/svelte ` 3 props · 0 bindable · 1 callbacks]() - [**ContentContributionForm** ` @happyvertical/smrt-content/svelte ` 7 props · 0 bindable · 2 callbacks]() - [**ContentContributionInbox** ` @happyvertical/smrt-content/svelte ` 8 props · 0 bindable · 4 callbacks]() - [**ContentContributionPortal** ` @happyvertical/smrt-content/svelte ` 5 props · 0 bindable · 2 callbacks]() - [**ContentContributionsRoute** ` @happyvertical/smrt-content/svelte ` 4 props · 0 bindable · 0 callbacks]() - [**ContentContributionTypeManager** ` @happyvertical/smrt-content/svelte ` 3 props · 0 bindable · 2 callbacks]() - [**ContentContributorManager** ` @happyvertical/smrt-content/svelte ` 3 props · 0 bindable · 2 callbacks]() - [**ContentCorrectionsTool** ` @happyvertical/smrt-content/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**ContentEditor** ` @happyvertical/smrt-content/svelte ` 18 props · 0 bindable · 5 callbacks]() - [**ContentFactsRoute** ` @happyvertical/smrt-content/svelte ` 5 props · 0 bindable · 0 callbacks]() - [**ContentGovernanceAssignmentEditor** ` @happyvertical/smrt-content/svelte ` 4 props · 0 bindable · 2 callbacks]() - [**ContentGovernanceManager** ` @happyvertical/smrt-content/svelte ` 3 props · 0 bindable · 1 callbacks]() - [**ContentGovernancePanel** ` @happyvertical/smrt-content/svelte ` 16 props · 0 bindable · 3 callbacks]() - [**ContentGovernancePolicyEditor** ` @happyvertical/smrt-content/svelte ` 3 props · 0 bindable · 2 callbacks]() - [**ContentGovernanceProfileEditor** ` @happyvertical/smrt-content/svelte ` 4 props · 0 bindable · 2 callbacks]() - [**ContentGovernanceRoute** ` @happyvertical/smrt-content/svelte ` 4 props · 0 bindable · 0 callbacks]() - [**ContentGovernanceTool** ` @happyvertical/smrt-content/svelte ` 5 props · 0 bindable · 2 callbacks]() - [**ContentImageBrowser** ` @happyvertical/smrt-content/svelte ` 10 props · 0 bindable · 4 callbacks]() - [**ContentImageChooser** ` @happyvertical/smrt-content/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**ContentList** ` @happyvertical/smrt-content/svelte ` 20 props · 0 bindable · 4 callbacks]() - [**ContentMetadataFields** ` @happyvertical/smrt-content/svelte ` 6 props · 0 bindable · 1 callbacks]() - [**ContentPictureDrawer** ` @happyvertical/smrt-content/svelte ` 16 props · 0 bindable · 7 callbacks]() - [**ContentReferencesPanel** ` @happyvertical/smrt-content/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**ContentReviewStatusTray** ` @happyvertical/smrt-content/svelte ` 5 props · 0 bindable · 1 callbacks]() - [**ContentStatusFields** ` @happyvertical/smrt-content/svelte ` 5 props · 0 bindable · 1 callbacks]() - [**ContentTitleField** ` @happyvertical/smrt-content/svelte ` 10 props · 0 bindable · 1 callbacks]() - [**ContentTransparencyReport** ` @happyvertical/smrt-content/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**ContentTransparencyTool** ` @happyvertical/smrt-content/svelte ` 3 props · 0 bindable · 1 callbacks]() - [**ContentVersionsTool** ` @happyvertical/smrt-content/svelte ` 3 props · 0 bindable · 1 callbacks]() - [**ContentWorkspaceRoute** ` @happyvertical/smrt-content/svelte ` 5 props · 0 bindable · 0 callbacks]() - [**GovernedContentEditor** ` @happyvertical/smrt-content/svelte ` 20 props · 0 bindable · 3 callbacks]() - [**Markdown** ` @happyvertical/smrt-content/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**PublishedArticleRoute** ` @happyvertical/smrt-content/svelte ` 3 props · 0 bindable · 0 callbacks]() ## Events · Components 1 - [**MeetingView** ` @happyvertical/smrt-events/svelte ` 2 props · 0 bindable · 0 callbacks]() ## Fields · Components 12 - [**AdvancedFields** ` @happyvertical/smrt-fields/svelte ` 4 props · 0 bindable · 0 callbacks]() - [**FieldPolicyControlPanel** ` @happyvertical/smrt-fields/svelte ` 9 props · 0 bindable · 1 callbacks]() - [**FieldPolicyEditor** ` @happyvertical/smrt-fields/svelte ` 7 props · 0 bindable · 2 callbacks]() - [**FieldPolicyGearButton** ` @happyvertical/smrt-fields/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**FieldPolicyGearProvider** ` @happyvertical/smrt-fields/svelte ` 7 props · 0 bindable · 0 callbacks]() - [**FieldPolicyProvider** ` @happyvertical/smrt-fields/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**FieldPolicySuggestionQueue** ` @happyvertical/smrt-fields/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**FormHelp** ` @happyvertical/smrt-fields/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**ModeSwitch** ` @happyvertical/smrt-fields/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**ObjectForm** ` @happyvertical/smrt-fields/svelte ` 15 props · 1 bindable · 1 callbacks]() - [**ObjectFormSourceProvider** ` @happyvertical/smrt-fields/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**PolicyField** ` @happyvertical/smrt-fields/svelte ` 10 props · 0 bindable · 0 callbacks]() ## Images · Components 4 - [**AssetsGallery** ` @happyvertical/smrt-images/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**ImageEditor** ` @happyvertical/smrt-images/svelte ` 5 props · 0 bindable · 2 callbacks]() - [**ImageUploader** ` @happyvertical/smrt-images/svelte ` 7 props · 0 bindable · 2 callbacks]() - [**PhotoCutoutSetup** ` @happyvertical/smrt-images/svelte ` 5 props · 0 bindable · 0 callbacks]() ## Jobs · Components 6 - [**JobActions** ` @happyvertical/smrt-jobs/svelte ` 8 props · 0 bindable · 3 callbacks]() - [**JobDashboard** ` @happyvertical/smrt-jobs/svelte ` 10 props · 0 bindable · 5 callbacks]() - [**JobDetail** ` @happyvertical/smrt-jobs/svelte ` 5 props · 0 bindable · 3 callbacks]() - [**JobList** ` @happyvertical/smrt-jobs/svelte ` 12 props · 0 bindable · 5 callbacks]() - [**JobStats** ` @happyvertical/smrt-jobs/svelte ` 4 props · 0 bindable · 0 callbacks]() - [**JobStatusBadge** ` @happyvertical/smrt-jobs/svelte ` 2 props · 0 bindable · 0 callbacks]() ## Messages · Components 23 - [**AccountAvatar** ` @happyvertical/smrt-messages/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**AccountCard** ` @happyvertical/smrt-messages/svelte ` 5 props · 0 bindable · 4 callbacks]() - [**AccountList** ` @happyvertical/smrt-messages/svelte ` 5 props · 0 bindable · 3 callbacks]() - [**AttachmentChip** ` @happyvertical/smrt-messages/svelte ` 2 props · 0 bindable · 1 callbacks]() - [**AttachmentUpload** ` @happyvertical/smrt-messages/svelte ` 4 props · 0 bindable · 2 callbacks]() - [**ComposeForm** ` @happyvertical/smrt-messages/svelte ` 6 props · 0 bindable · 3 callbacks]() - [**EmailAccountManager** ` @happyvertical/smrt-messages/svelte ` 5 props · 0 bindable · 3 callbacks]() - [**EmailFilterManager** ` @happyvertical/smrt-messages/svelte ` 7 props · 0 bindable · 4 callbacks]() - [**FolderNav** ` @happyvertical/smrt-messages/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**ForwardForm** ` @happyvertical/smrt-messages/svelte ` 3 props · 0 bindable · 2 callbacks]() - [**MailboxDemo** ` @happyvertical/smrt-messages/svelte ` 0 props · 0 bindable · 0 callbacks]() - [**MessageCard** ` @happyvertical/smrt-messages/svelte ` 10 props · 0 bindable · 3 callbacks]() - [**MessageDetail** ` @happyvertical/smrt-messages/svelte ` 8 props · 0 bindable · 3 callbacks]() - [**MessageFilters** ` @happyvertical/smrt-messages/svelte ` 6 props · 0 bindable · 2 callbacks]() - [**MessageList** ` @happyvertical/smrt-messages/svelte ` 13 props · 0 bindable · 3 callbacks]() - [**MessageStatusIndicator** ` @happyvertical/smrt-messages/svelte ` 5 props · 0 bindable · 0 callbacks]() - [**MessageToolbar** ` @happyvertical/smrt-messages/svelte ` 6 props · 0 bindable · 3 callbacks]() - [**MessageTypeBadge** ` @happyvertical/smrt-messages/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**MessagingSettingsPanel** ` @happyvertical/smrt-messages/svelte ` 10 props · 0 bindable · 3 callbacks]() - [**RecipientInput** ` @happyvertical/smrt-messages/svelte ` 4 props · 0 bindable · 1 callbacks]() - [**ReplyForm** ` @happyvertical/smrt-messages/svelte ` 4 props · 0 bindable · 2 callbacks]() - [**SendStatusBadge** ` @happyvertical/smrt-messages/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**ThreadView** ` @happyvertical/smrt-messages/svelte ` 5 props · 0 bindable · 2 callbacks]() ## Personas · Components 1 - [**DirectiveReviewQueue** ` @happyvertical/smrt-personas/svelte ` 4 props · 0 bindable · 2 callbacks]() ## Planner · Planner 3 - [**HostPlanner** ` @happyvertical/smrt-planner ` 3 props · 0 bindable · 1 callbacks]() - [**Planner** ` @happyvertical/smrt-planner ` 22 props · 0 bindable · 2 callbacks]() - [**PlannerControls** ` @happyvertical/smrt-planner ` 24 props · 0 bindable · 2 callbacks]() ## Playground · Components 1 - [**PlaygroundHost** ` @happyvertical/smrt-playground/svelte ` 6 props · 0 bindable · 0 callbacks]() ## Projects · Components 13 - [**ApprovalActions** ` @happyvertical/smrt-projects/svelte ` 9 props · 0 bindable · 5 callbacks]() - [**AssistanceLauncher** ` @happyvertical/smrt-projects/svelte ` 5 props · 0 bindable · 1 callbacks]() - [**BulkActions** ` @happyvertical/smrt-projects/svelte ` 7 props · 0 bindable · 5 callbacks]() - [**DeliveryStatus** ` @happyvertical/smrt-projects/svelte ` 1 props · 0 bindable · 0 callbacks]() - [**DevelopmentBoard** ` @happyvertical/smrt-projects/svelte ` 3 props · 0 bindable · 1 callbacks]() - [**DevelopmentRequestDetail** ` @happyvertical/smrt-projects/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**DevelopmentRequestForm** ` @happyvertical/smrt-projects/svelte ` 2 props · 0 bindable · 1 callbacks]() - [**DevelopmentRequestList** ` @happyvertical/smrt-projects/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**PreviewApprovalPanel** ` @happyvertical/smrt-projects/svelte ` 3 props · 0 bindable · 1 callbacks]() - [**ProjectBoard** ` @happyvertical/smrt-projects/svelte ` 7 props · 0 bindable · 3 callbacks]() - [**ProjectQuestionsAndDecisions** ` @happyvertical/smrt-projects/svelte ` 5 props · 0 bindable · 2 callbacks]() - [**RejectDialog** ` @happyvertical/smrt-projects/svelte ` 10 props · 0 bindable · 2 callbacks]() - [**ServiceEvidenceList** ` @happyvertical/smrt-projects/svelte ` 1 props · 0 bindable · 0 callbacks]() ## Reports · Components 13 - [**MaterializedReportTable** ` @happyvertical/smrt-reports/svelte ` 5 props · 0 bindable · 2 callbacks]() - [**ReportConfirmation** ` @happyvertical/smrt-reports/svelte ` 9 props · 0 bindable · 2 callbacks]() - [**ReportDetail** ` @happyvertical/smrt-reports/svelte ` 8 props · 0 bindable · 2 callbacks]() - [**ReportPicker** ` @happyvertical/smrt-reports/svelte ` 6 props · 0 bindable · 1 callbacks]() - [**ReportResult** ` @happyvertical/smrt-reports/svelte ` 6 props · 0 bindable · 0 callbacks]() - [**RuntimeReportChartWidget** ` @happyvertical/smrt-reports/svelte ` 4 props · 0 bindable · 0 callbacks]() - [**RuntimeReportDetailRoute** ` @happyvertical/smrt-reports/svelte ` 9 props · 0 bindable · 0 callbacks]() - [**RuntimeReportsRoute** ` @happyvertical/smrt-reports/svelte ` 8 props · 0 bindable · 0 callbacks]() - [**RuntimeReportToolResult** ` @happyvertical/smrt-reports/svelte ` 1 props · 0 bindable · 0 callbacks]() - [**RuntimeReportWidgetOptions** ` @happyvertical/smrt-reports/svelte ` 3 props · 0 bindable · 2 callbacks]() - [**SavedReportCard** ` @happyvertical/smrt-reports/svelte ` 9 props · 0 bindable · 0 callbacks]() - [**SavedReports** ` @happyvertical/smrt-reports/svelte ` 10 props · 0 bindable · 1 callbacks]() - [**SavedReportsWidget** ` @happyvertical/smrt-reports/svelte ` 9 props · 0 bindable · 0 callbacks]() ## Svelte · App 4 - [**AppShell** ` @happyvertical/smrt-svelte/app ` 45 props · 0 bindable · 2 callbacks]() - [**OwnerSetupForm** ` @happyvertical/smrt-svelte/app ` 7 props · 0 bindable · 0 callbacks]() - [**RuntimeDiagnosticsWebMcp** ` @happyvertical/smrt-svelte/app ` 2 props · 0 bindable · 0 callbacks]() - [**ShellSettingsPage** ` @happyvertical/smrt-svelte/app ` 2 props · 0 bindable · 1 callbacks]() ## Svelte · Audit 2 - [**AuditList** ` @happyvertical/smrt-svelte ` 10 props · 0 bindable · 1 callbacks]() - [**RecordHistory** ` @happyvertical/smrt-svelte ` 11 props · 0 bindable · 0 callbacks]() ## Svelte · Board 1 - [**Board** ` @happyvertical/smrt-svelte/board ` 15 props · 0 bindable · 2 callbacks]() ## Svelte · Browser Ai 6 - [**AILoadingOverlay** ` @happyvertical/smrt-svelte/browser-ai/svelte ` 5 props · 0 bindable · 1 callbacks]() - [**CapabilityGate** ` @happyvertical/smrt-svelte/browser-ai/svelte ` 4 props · 0 bindable · 0 callbacks]() - [**DownloadProgress** ` @happyvertical/smrt-svelte/browser-ai/svelte ` 4 props · 0 bindable · 0 callbacks]() - [**ModelStatusControl** ` @happyvertical/smrt-svelte/browser-ai/svelte ` 5 props · 0 bindable · 1 callbacks]() - [**STTTest** ` @happyvertical/smrt-svelte/browser-ai/svelte ` 1 props · 0 bindable · 0 callbacks]() - [**VoiceInput** ` @happyvertical/smrt-svelte/browser-ai/svelte ` 5 props · 0 bindable · 1 callbacks]() ## Svelte · Command Palette 3 - [**CommandPalette** ` @happyvertical/smrt-svelte/command-palette ` 8 props · 0 bindable · 0 callbacks]() - [**CommandPaletteDialog** ` @happyvertical/smrt-svelte/command-palette ` 4 props · 0 bindable · 0 callbacks]() - [**CommandPaletteTrigger** ` @happyvertical/smrt-svelte/command-palette ` 5 props · 0 bindable · 0 callbacks]() ## Svelte · Components 1 - [**Provider** ` @happyvertical/smrt-svelte ` 12 props · 0 bindable · 3 callbacks]() ## Svelte · Cookbook 3 - [**CookbookApp** ` @happyvertical/smrt-svelte/cookbook ` 8 props · 0 bindable · 1 callbacks]() - [**CookbookSectionOverview** ` @happyvertical/smrt-svelte/cookbook ` 11 props · 0 bindable · 0 callbacks]() - [**CookbookSectionPage** ` @happyvertical/smrt-svelte/cookbook ` 5 props · 0 bindable · 0 callbacks]() ## Svelte · Forms and controls 16 - [**AddressInput** ` @happyvertical/smrt-svelte/forms ` 11 props · 0 bindable · 1 callbacks]() - [**CheckboxInput** ` @happyvertical/smrt-svelte/forms ` 7 props · 0 bindable · 1 callbacks]() - [**DateRangeInput** ` @happyvertical/smrt-svelte/forms ` 13 props · 0 bindable · 1 callbacks]() - [**DateTimeInput** ` @happyvertical/smrt-svelte/forms ` 9 props · 0 bindable · 1 callbacks]() - [**FileUpload** ` @happyvertical/smrt-svelte/forms ` 12 props · 0 bindable · 1 callbacks]() - [**Form** ` @happyvertical/smrt-svelte/forms ` 20 props · 0 bindable · 2 callbacks]() - [**FormMicButton** ` @happyvertical/smrt-svelte/forms ` 2 props · 0 bindable · 0 callbacks]() - [**FormScope** ` @happyvertical/smrt-svelte/forms ` 6 props · 0 bindable · 0 callbacks]() - [**MeasurementInput** ` @happyvertical/smrt-svelte/forms ` 14 props · 0 bindable · 1 callbacks]() - [**MoneyInput** ` @happyvertical/smrt-svelte/forms ` 12 props · 0 bindable · 1 callbacks]() - [**NumberInput** ` @happyvertical/smrt-svelte/forms ` 11 props · 0 bindable · 1 callbacks]() - [**PhoneInput** ` @happyvertical/smrt-svelte/forms ` 8 props · 0 bindable · 1 callbacks]() - [**SearchInput** ` @happyvertical/smrt-svelte/forms ` 12 props · 0 bindable · 3 callbacks]() - [**SelectInput** ` @happyvertical/smrt-svelte/forms ` 9 props · 0 bindable · 1 callbacks]() - [**TextareaInput** ` @happyvertical/smrt-svelte/forms ` 10 props · 0 bindable · 1 callbacks]() - [**TextInput** ` @happyvertical/smrt-svelte/forms ` 10 props · 0 bindable · 1 callbacks]() ## Svelte · Import Export 1 - [**ImportExport** ` @happyvertical/smrt-svelte/import-export ` 11 props · 0 bindable · 2 callbacks]() ## Svelte · Mcp Apps 1 - [**McpAppsBridge** ` @happyvertical/smrt-svelte/mcp-apps ` 9 props · 0 bindable · 0 callbacks]() ## Svelte · Module 1 - [**ModulePanel** ` @happyvertical/smrt-svelte ` 2 props · 0 bindable · 0 callbacks]() ## Svelte · Notifications 1 - [**NotificationBell** ` @happyvertical/smrt-svelte/notifications ` 3 props · 0 bindable · 0 callbacks]() ## Svelte · Overview 10 - [**ChartWidget** ` @happyvertical/smrt-svelte/overview ` 8 props · 0 bindable · 0 callbacks]() - [**LineItemsWidget** ` @happyvertical/smrt-svelte/overview ` 8 props · 0 bindable · 0 callbacks]() - [**MetricWidget** ` @happyvertical/smrt-svelte/overview ` 8 props · 0 bindable · 0 callbacks]() - [**NoteWidget** ` @happyvertical/smrt-svelte/overview ` 8 props · 0 bindable · 0 callbacks]() - [**OverviewAssistantUndo** ` @happyvertical/smrt-svelte/overview ` 3 props · 0 bindable · 0 callbacks]() - [**OverviewGrid** ` @happyvertical/smrt-svelte/overview ` 10 props · 0 bindable · 0 callbacks]() - [**RecordListWidget** ` @happyvertical/smrt-svelte/overview ` 8 props · 0 bindable · 0 callbacks]() - [**RelatedWidget** ` @happyvertical/smrt-svelte/overview ` 8 props · 0 bindable · 0 callbacks]() - [**ShortcutsWidget** ` @happyvertical/smrt-svelte/overview ` 8 props · 0 bindable · 0 callbacks]() - [**WidgetOptionsForm** ` @happyvertical/smrt-svelte/overview ` 6 props · 0 bindable · 2 callbacks]() ## Svelte · Screens 5 - [**DetailScreen** ` @happyvertical/smrt-svelte/screens ` 21 props · 0 bindable · 3 callbacks]() - [**EditForm** ` @happyvertical/smrt-svelte/screens ` 13 props · 0 bindable · 2 callbacks]() - [**ListScreen** ` @happyvertical/smrt-svelte/screens ` 18 props · 0 bindable · 3 callbacks]() - [**RecipeScreens** ` @happyvertical/smrt-svelte/screens ` 14 props · 0 bindable · 1 callbacks]() - [**RecordScreen** ` @happyvertical/smrt-svelte/screens ` 36 props · 0 bindable · 5 callbacks]() ## Svelte · Settings 1 - [**SettingsCatalog** ` @happyvertical/smrt-svelte/settings ` 9 props · 0 bindable · 0 callbacks]() ## Svelte · Sortable 1 - [**Sortable** ` @happyvertical/smrt-svelte/sortable ` 9 props · 0 bindable · 2 callbacks]() ## Svelte · Workspace 26 - [**ActivityBadge** ` @happyvertical/smrt-svelte/workspace ` 2 props · 0 bindable · 0 callbacks]() - [**ActivityItem** ` @happyvertical/smrt-svelte/workspace ` 1 props · 0 bindable · 0 callbacks]() - [**ActivityList** ` @happyvertical/smrt-svelte/workspace ` 3 props · 0 bindable · 0 callbacks]() - [**ActivityTicker** ` @happyvertical/smrt-svelte/workspace ` 4 props · 0 bindable · 0 callbacks]() - [**ActivityToasts** ` @happyvertical/smrt-svelte/workspace ` 2 props · 0 bindable · 0 callbacks]() - [**AdminShell** ` @happyvertical/smrt-svelte/workspace ` 45 props · 0 bindable · 0 callbacks]() - [**AppScopePanel** ` @happyvertical/smrt-svelte/workspace ` 7 props · 0 bindable · 0 callbacks]() - [**HotkeyInput** ` @happyvertical/smrt-svelte/workspace ` 4 props · 0 bindable · 1 callbacks]() - [**PhoneBottomBar** ` @happyvertical/smrt-svelte/workspace ` 3 props · 0 bindable · 0 callbacks]() - [**PhoneTopBar** ` @happyvertical/smrt-svelte/workspace ` 2 props · 0 bindable · 0 callbacks]() - [**ShellCorner** ` @happyvertical/smrt-svelte/workspace ` 2 props · 0 bindable · 0 callbacks]() - [**ShellDockTool** ` @happyvertical/smrt-svelte/workspace ` 11 props · 0 bindable · 0 callbacks]() - [**ShellIconButton** ` @happyvertical/smrt-svelte/workspace ` 6 props · 0 bindable · 0 callbacks]() - [**ShellLayoutEditor** ` @happyvertical/smrt-svelte/workspace ` 3 props · 0 bindable · 0 callbacks]() - [**ShellNavEditor** ` @happyvertical/smrt-svelte/workspace ` 5 props · 0 bindable · 0 callbacks]() - [**ShellNavToggle** ` @happyvertical/smrt-svelte/workspace ` 4 props · 0 bindable · 1 callbacks]() - [**ShellSectionIcon** ` @happyvertical/smrt-svelte/workspace ` 3 props · 0 bindable · 0 callbacks]() - [**ShellSectionMenu** ` @happyvertical/smrt-svelte/workspace ` 8 props · 0 bindable · 1 callbacks]() - [**ShellSettingsPanel** ` @happyvertical/smrt-svelte/workspace ` 4 props · 0 bindable · 1 callbacks]() - [**ShellTitle** ` @happyvertical/smrt-svelte/workspace ` 2 props · 0 bindable · 0 callbacks]() - [**ShortcutsOverlay** ` @happyvertical/smrt-svelte/workspace ` 1 props · 0 bindable · 1 callbacks]() - [**SystemScopePanel** ` @happyvertical/smrt-svelte/workspace ` 2 props · 0 bindable · 0 callbacks]() - [**SystemStatusChips** ` @happyvertical/smrt-svelte/workspace ` 1 props · 0 bindable · 0 callbacks]() - [**TenantNav** ` @happyvertical/smrt-svelte/workspace ` 10 props · 0 bindable · 1 callbacks]() - [**ToolsDock** ` @happyvertical/smrt-svelte/workspace/legacy ` 3 props · 0 bindable · 0 callbacks]() - [**WorkspaceAccountMenu** ` @happyvertical/smrt-svelte/workspace ` 16 props · 0 bindable · 2 callbacks]() ## Tenancy · Components 2 - [**TenantCard** ` @happyvertical/smrt-tenancy/svelte ` 7 props · 0 bindable · 3 callbacks]() - [**TenantSwitcher** ` @happyvertical/smrt-tenancy/svelte ` 4 props · 0 bindable · 1 callbacks]() ## Calendar 3 - [**Calendar** ` @happyvertical/smrt-ui/calendar ` 7 props · 0 bindable · 3 callbacks]() - [**CalendarView** ` @happyvertical/smrt-ui/calendar ` 19 props · 0 bindable · 3 callbacks]() - [**DayView** ` @happyvertical/smrt-ui/calendar ` 5 props · 0 bindable · 1 callbacks]() ## Charts 1 - [**Chart** ` @happyvertical/smrt-ui/charts ` 8 props · 0 bindable · 0 callbacks]() ## Chat 3 - [**MessageBubble** ` @happyvertical/smrt-ui/chat ` 10 props · 0 bindable · 0 callbacks]() - [**ReactionPicker** ` @happyvertical/smrt-ui/chat ` 5 props · 0 bindable · 1 callbacks]() - [**TypingIndicator** ` @happyvertical/smrt-ui/chat ` 3 props · 0 bindable · 0 callbacks]() ## Collections and tables 6 - [**CollectionList** ` @happyvertical/smrt-ui/data ` 14 props · 1 bindable · 2 callbacks]() - [**CollectionToolbar** ` @happyvertical/smrt-ui/data ` 16 props · 0 bindable · 2 callbacks]() - [**ContentList** ` @happyvertical/smrt-ui/data ` 14 props · 1 bindable · 2 callbacks]() - [**DataTable** ` @happyvertical/smrt-ui/data ` 57 props · 4 bindable · 7 callbacks]() - [**ListSortSelect** ` @happyvertical/smrt-ui/data ` 7 props · 0 bindable · 1 callbacks]() - [**SortableHeader** ` @happyvertical/smrt-ui/data ` 11 props · 0 bindable · 1 callbacks]() ## Display and status 6 - [**ConfidenceBadge** ` @happyvertical/smrt-ui/display ` 5 props · 0 bindable · 0 callbacks]() - [**CurrencyDisplay** ` @happyvertical/smrt-ui/display ` 8 props · 0 bindable · 0 callbacks]() - [**DateDisplay** ` @happyvertical/smrt-ui/display ` 7 props · 0 bindable · 0 callbacks]() - [**DocumentViewer** ` @happyvertical/smrt-ui/display ` 8 props · 0 bindable · 0 callbacks]() - [**Icon** ` @happyvertical/smrt-ui/display ` 6 props · 0 bindable · 0 callbacks]() - [**StatusBadge** ` @happyvertical/smrt-ui/display ` 6 props · 0 bindable · 0 callbacks]() ## Feedback and overlays 13 - [**Alert** ` @happyvertical/smrt-ui/feedback ` 7 props · 0 bindable · 1 callbacks]() - [**ConfirmDialog** ` @happyvertical/smrt-ui/feedback ` 9 props · 0 bindable · 2 callbacks]() - [**Drawer** ` @happyvertical/smrt-ui/feedback ` 12 props · 0 bindable · 1 callbacks]() - [**LoadingOverlay** ` @happyvertical/smrt-ui/feedback ` 8 props · 0 bindable · 1 callbacks]() - [**Meter** ` @happyvertical/smrt-ui/feedback ` 10 props · 0 bindable · 0 callbacks]() - [**Modal** ` @happyvertical/smrt-ui/feedback ` 14 props · 0 bindable · 1 callbacks]() - [**PhoneSheet** ` @happyvertical/smrt-ui/feedback ` 7 props · 0 bindable · 1 callbacks]() - [**Progress** ` @happyvertical/smrt-ui/feedback ` 8 props · 0 bindable · 0 callbacks]() - [**ProgressBar** ` @happyvertical/smrt-ui/feedback ` 7 props · 0 bindable · 0 callbacks]() - [**Sheet** ` @happyvertical/smrt-ui/feedback ` 12 props · 0 bindable · 1 callbacks]() - [**Spinner** ` @happyvertical/smrt-ui/feedback ` 3 props · 0 bindable · 0 callbacks]() - [**ToastViewport** ` @happyvertical/smrt-ui/feedback ` 5 props · 0 bindable · 0 callbacks]() - [**WorkingStrip** ` @happyvertical/smrt-ui/feedback ` 15 props · 0 bindable · 6 callbacks]() ## Forms and controls 38 - [**CameraCapture** ` @happyvertical/smrt-ui/forms ` 13 props · 0 bindable · 2 callbacks]() - [**Checkbox** ` @happyvertical/smrt-ui/forms ` 6 props · 0 bindable · 0 callbacks]() - [**Combobox** ` @happyvertical/smrt-ui/forms ` 19 props · 0 bindable · 2 callbacks]() - [**CountrySelect** ` @happyvertical/smrt-ui/forms ` 10 props · 0 bindable · 0 callbacks]() - [**CurrencySelect** ` @happyvertical/smrt-ui/forms ` 10 props · 0 bindable · 0 callbacks]() - [**DatePicker** ` @happyvertical/smrt-ui/forms ` 4 props · 0 bindable · 0 callbacks]() - [**DictationButton** ` @happyvertical/smrt-ui/forms ` 6 props · 0 bindable · 0 callbacks]() - [**DictationStatus** ` @happyvertical/smrt-ui/forms ` 3 props · 0 bindable · 0 callbacks]() - [**ErrorSummary** ` @happyvertical/smrt-ui/forms ` 4 props · 0 bindable · 1 callbacks]() - [**Field** ` @happyvertical/smrt-ui/forms ` 7 props · 0 bindable · 0 callbacks]() - [**FieldLabel** ` @happyvertical/smrt-ui/forms ` 4 props · 0 bindable · 0 callbacks]() - [**Fieldset** ` @happyvertical/smrt-ui/forms ` 6 props · 0 bindable · 0 callbacks]() - [**FilePicker** ` @happyvertical/smrt-ui/forms ` 7 props · 0 bindable · 1 callbacks]() - [**Form** ` @happyvertical/smrt-ui/forms ` 7 props · 0 bindable · 1 callbacks]() - [**FormActionBar** ` @happyvertical/smrt-ui/forms ` 3 props · 0 bindable · 0 callbacks]() - [**FormGroup** ` @happyvertical/smrt-ui/forms ` 7 props · 0 bindable · 0 callbacks]() - [**Input** ` @happyvertical/smrt-ui/forms ` 4 props · 0 bindable · 0 callbacks]() - [**InputGroup** ` @happyvertical/smrt-ui/forms ` 4 props · 0 bindable · 0 callbacks]() - [**Listbox** ` @happyvertical/smrt-ui/forms ` 8 props · 0 bindable · 1 callbacks]() - [**MultiSelect** ` @happyvertical/smrt-ui/forms ` 9 props · 0 bindable · 1 callbacks]() - [**NumericKeypad** ` @happyvertical/smrt-ui/forms ` 21 props · 0 bindable · 2 callbacks]() - [**ProvinceSelect** ` @happyvertical/smrt-ui/forms ` 1 props · 0 bindable · 0 callbacks]() - [**Radio** ` @happyvertical/smrt-ui/forms ` 3 props · 0 bindable · 0 callbacks]() - [**RadioGroup** ` @happyvertical/smrt-ui/forms ` 12 props · 0 bindable · 1 callbacks]() - [**RangeSlider** ` @happyvertical/smrt-ui/forms ` 13 props · 0 bindable · 1 callbacks]() - [**RelationInput** ` @happyvertical/smrt-ui/forms ` 20 props · 0 bindable · 2 callbacks]() - [**SearchInput** ` @happyvertical/smrt-ui/forms ` 8 props · 0 bindable · 1 callbacks]() - [**SegmentedControl** ` @happyvertical/smrt-ui/forms ` 11 props · 0 bindable · 1 callbacks]() - [**Select** ` @happyvertical/smrt-ui/forms ` 5 props · 0 bindable · 0 callbacks]() - [**SignaturePad** ` @happyvertical/smrt-ui/forms ` 12 props · 0 bindable · 2 callbacks]() - [**Slider** ` @happyvertical/smrt-ui/forms ` 10 props · 0 bindable · 0 callbacks]() - [**StagedControlReview** ` @happyvertical/smrt-ui/forms ` 5 props · 0 bindable · 0 callbacks]() - [**Switch** ` @happyvertical/smrt-ui/forms ` 7 props · 0 bindable · 0 callbacks]() - [**TagsInput** ` @happyvertical/smrt-ui/forms ` 10 props · 0 bindable · 1 callbacks]() - [**Textarea** ` @happyvertical/smrt-ui/forms ` 5 props · 0 bindable · 0 callbacks]() - [**TimePicker** ` @happyvertical/smrt-ui/forms ` 4 props · 0 bindable · 0 callbacks]() - [**Toggle** ` @happyvertical/smrt-ui/forms ` 10 props · 0 bindable · 1 callbacks]() - [**ToggleButton** ` @happyvertical/smrt-ui/forms ` 4 props · 0 bindable · 0 callbacks]() ## Internationalization 1 - [**Trans** ` @happyvertical/smrt-ui/i18n ` 2 props · 0 bindable · 0 callbacks]() ## Layout 12 - [**ActionGroup** ` @happyvertical/smrt-ui/layout ` 4 props · 0 bindable · 0 callbacks]() - [**Container** ` @happyvertical/smrt-ui/layout ` 2 props · 0 bindable · 0 callbacks]() - [**DescriptionList** ` @happyvertical/smrt-ui/layout ` 3 props · 0 bindable · 0 callbacks]() - [**EmptyState** ` @happyvertical/smrt-ui/layout ` 7 props · 0 bindable · 1 callbacks]() - [**Footer** ` @happyvertical/smrt-ui/layout ` 1 props · 0 bindable · 0 callbacks]() - [**Grid** ` @happyvertical/smrt-ui/layout ` 7 props · 0 bindable · 0 callbacks]() - [**Header** ` @happyvertical/smrt-ui/layout ` 2 props · 0 bindable · 0 callbacks]() - [**Masthead** ` @happyvertical/smrt-ui/layout ` 6 props · 0 bindable · 0 callbacks]() - [**PageHeader** ` @happyvertical/smrt-ui/layout ` 12 props · 0 bindable · 0 callbacks]() - [**PageLayout** ` @happyvertical/smrt-ui/layout ` 4 props · 0 bindable · 0 callbacks]() - [**Stack** ` @happyvertical/smrt-ui/layout ` 7 props · 0 bindable · 0 callbacks]() - [**SummaryCard** ` @happyvertical/smrt-ui/layout ` 8 props · 0 bindable · 0 callbacks]() ## Membership and permissions 2 - [**MembershipCard** ` @happyvertical/smrt-ui ` 5 props · 0 bindable · 2 callbacks]() - [**MembershipList** ` @happyvertical/smrt-ui ` 6 props · 0 bindable · 2 callbacks]() ## Navigation 2 - [**FilterChips** ` @happyvertical/smrt-ui ` 7 props · 0 bindable · 1 callbacks]() - [**Tabs** ` @happyvertical/smrt-ui ` 10 props · 0 bindable · 1 callbacks]() ## Membership and permissions 2 - [**PermissionCheck** ` @happyvertical/smrt-ui ` 6 props · 0 bindable · 0 callbacks]() - [**PermissionPicker** ` @happyvertical/smrt-ui ` 7 props · 0 bindable · 0 callbacks]() ## Membership and permissions 2 - [**RoleBadge** ` @happyvertical/smrt-ui ` 2 props · 0 bindable · 0 callbacks]() - [**RoleSelector** ` @happyvertical/smrt-ui ` 6 props · 0 bindable · 1 callbacks]() ## Themes 3 - [**ColorSchemeToggle** ` @happyvertical/smrt-ui/themes ` 4 props · 0 bindable · 0 callbacks]() - [**ThemeProvider** ` @happyvertical/smrt-ui/themes ` 13 props · 0 bindable · 0 callbacks]() - [**ThemeSwitcher** ` @happyvertical/smrt-ui/themes ` 4 props · 0 bindable · 0 callbacks]() ## Actions and display 17 - [**Accordion** ` @happyvertical/smrt-ui/ui ` 5 props · 0 bindable · 1 callbacks]() - [**AccordionItem** ` @happyvertical/smrt-ui/ui ` 4 props · 0 bindable · 0 callbacks]() - [**Avatar** ` @happyvertical/smrt-ui/ui ` 5 props · 0 bindable · 0 callbacks]() - [**Badge** ` @happyvertical/smrt-ui/ui ` 3 props · 0 bindable · 0 callbacks]() - [**Button** ` @happyvertical/smrt-ui/ui ` 11 props · 0 bindable · 0 callbacks]() - [**Card** ` @happyvertical/smrt-ui/ui ` 6 props · 0 bindable · 0 callbacks]() - [**Chip** ` @happyvertical/smrt-ui/ui ` 9 props · 0 bindable · 2 callbacks]() - [**Disclosure** ` @happyvertical/smrt-ui/ui ` 7 props · 0 bindable · 1 callbacks]() - [**Dropdown** ` @happyvertical/smrt-ui/ui ` 8 props · 0 bindable · 1 callbacks]() - [**IconToggle** ` @happyvertical/smrt-ui/ui ` 7 props · 0 bindable · 0 callbacks]() - [**IconToggleGroup** ` @happyvertical/smrt-ui/ui ` 3 props · 0 bindable · 0 callbacks]() - [**Menu** ` @happyvertical/smrt-ui/ui ` 8 props · 0 bindable · 1 callbacks]() - [**Pagination** ` @happyvertical/smrt-ui/ui ` 8 props · 0 bindable · 1 callbacks]() - [**Popover** ` @happyvertical/smrt-ui/ui ` 11 props · 0 bindable · 1 callbacks]() - [**Skeleton** ` @happyvertical/smrt-ui/ui ` 5 props · 0 bindable · 0 callbacks]() - [**Tooltip** ` @happyvertical/smrt-ui/ui ` 4 props · 0 bindable · 0 callbacks]() - [**Tree** ` @happyvertical/smrt-ui/ui ` 5 props · 0 bindable · 1 callbacks]() ## Users · Components 12 - [**AccountSecurityPanel** ` @happyvertical/smrt-users/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**InviteUserModal** ` @happyvertical/smrt-users/svelte ` 6 props · 0 bindable · 2 callbacks]() - [**MagicLinkForm** ` @happyvertical/smrt-users/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**OidcProviderButtons** ` @happyvertical/smrt-users/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**PasskeySignInButton** ` @happyvertical/smrt-users/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**SignInForm** ` @happyvertical/smrt-users/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**SignUpForm** ` @happyvertical/smrt-users/svelte ` 2 props · 0 bindable · 0 callbacks]() - [**UserAvatar** ` @happyvertical/smrt-users/svelte ` 3 props · 0 bindable · 0 callbacks]() - [**UserCard** ` @happyvertical/smrt-users/svelte ` 6 props · 0 bindable · 1 callbacks]() - [**UserForm** ` @happyvertical/smrt-users/svelte ` 5 props · 0 bindable · 2 callbacks]() - [**UserList** ` @happyvertical/smrt-users/svelte ` 6 props · 0 bindable · 1 callbacks]() - [**UserMenu** ` @happyvertical/smrt-users/svelte ` 6 props · 0 bindable · 0 callbacks]() --- FAQ # Get oriented Short answers to common questions about the application model and newer framework features. 01 ## Starting out What is s-m-r-t?+ A TypeScript application framework built around useful domain objects. It supplies persistence, manifests, generated REST/MCP/CLI interfaces, users, tenants, agents, web data, native-mobile foundations, and a broad set of domain packages. What is a SAADL?+ Software as Agentic Domain Logic means the same domain operations are available to people through ordinary interfaces and to agents through callable tools. Both resolve through the same models, permissions, tenants, and field policies. Do I need every package?+ No. Start with smrt-core, then add packages by capability or domain. They share conventions, but the stack is intentionally modular. Which database should I use?+ SQLite is excellent for development and local-first tools, Postgres is the normal production choice—especially when using row-level security—and DuckDB fits analytical workloads. 02 ## Application foundation Can an agent help someone complete a form?+ Yes. Standard controls can publish their identity, meaning, options, constraints, and state to a chat, voice, tutorial, or test adapter. An agent may point to a field or stage a proposed value, but applying, clearing, or undoing is always refused for an agent by default — only a human, through a real local click, can confirm one — and secret controls remain unavailable. Are users and tenants included?+ Yes. smrt-users includes sessions, memberships, hierarchical tenants, roles, permissions, access requests, and SvelteKit integration. smrt-tenancy enforces data scope on decorated models. How do tenant relationships work?+ Parent/child tenants describe organization. Memberships connect a user to a tenant with one role. Profile relationships describe domain links between people, organizations, or agents. They are separate on purpose. Can permissions differ between REST, MCP, WebMCP, and CLI?+ Yes. Each model declares which operations each interface exposes. Manifest-derived permission slugs and runtime principal checks keep interface policy connected to authorization. 03 ## Newer capabilities What does it mean that agents learn?+ Learning is opt-in. Agents recall confident, scoped memories before work and reinforce or decay them from outcomes afterward. Personas can propose instruction changes, but activating those changes requires a separate permissioned human approval. Is smrt-mobile a JavaScript wrapper?+ No. Shared behavior is Kotlin Multiplatform; Android uses Compose and native adapters, while iOS uses SwiftUI and Apple frameworks. The shared layer covers offline queues, packs, auth, networking, evidence, and presenter state. What is hydration in smrt-web?+ SvelteKit server results seed generated browser collections so the client does not repeat the initial fetch. Live updates, persisted cache versioning, and the offline outbox continue from that initial state. What does WebMCP expose?+ s-m-r-t generates browser tool descriptors for exposed collection actions and registers them with document.modelContext. CRUD tools execute through the normal REST client as the signed-in page user, preserving authentication, tenant, permission, and field policy. 04 ## Why s-m-r-t Why build one application for both people and agents?+ Building two systems — a person-facing application and a separate, reduced set of endpoints or bots for software — means keeping two descriptions of the same operations in sync by hand, and the second one tends to drift and shrink over time. A s-m-r-t application describes each operation once; people reach it through pages, HTTP, or the command line, and agents reach the identical operation as a callable tool, so there is no second definition to fall behind. What is SAADL, and how is it pronounced?+ SAADL — Software as Agentic Domain Logic: software whose domain logic exposes the same operations to human users (UI, HTTP, CLI) and to agents (callable tools). Pronounced "saddle." [Read the full SAADL reference →]() Can an agent do anything a signed-in person cannot?+ No. An agent can do only what three lists all allow: what the signed-in person may do, what its kind of agent may ever do, and what its assigned role permits. The check runs from the moment an agent reads a description to the stored record itself — a description does not by itself grant a session, a tenant, or a permission. [Security defaults →]() Does asking in chat skip the application's rules?+ No. However a request arrives — a click, a typed command, or a natural-language chat message — it enters through the same declared control or operation, and the same tenant, permission, and field-policy checks apply. [Human-agent interaction →]() Is this site itself built with s-m-r-t?+ Yes. s-m-r-t.dev runs on the same released @happyvertical/smrt-\* packages it documents — the component playground, the agent-aware form demo, and the data table on this site are the actual packages, not mockups. [Component playground →]() Why is it spelled s-m-r-t?+ I can't help myself. As I was planning a framework for software that develops and runs itself, a certain scene from The Simpsons was prominently in mind. Still looking for a concept? [Search all packages →]()