tosijs/agent
Everything that describes an app to a non-human user, behind one door:
import { enableAgentInterface } from 'tosijs/agent'
// nothing is exposed until you say so
const agent = enableAgentInterface({ expose: { roots: ['app'] } })
agent.describe() // the affordance map
| export | what |
|---|---|
enableAgentInterface |
the surface: describe / read / write / observe / call / changes / when / log |
webmcpTools, webmcpAdapter |
the generated WebMCP tool set (auto-registered by enableAgentInterface where a host exists) |
schematicSVG, rasterizeSVG, boundsOf |
the map, drawn (from tosijs-floorplan, vendored) |
schematic |
the same map as DATA (boxes, legend, note) instead of an SVG string |
isInteractive, targetSizeFinding, TARGET_SIZE_DEFAULT |
the shared affordance rules, over a SchematicRecord from describe() — not over a DOM element. isInteractive(someAnchor) compiles in plain JS and is meaningless. |
auditAccessibility, auditFlags, contrastRatio |
findings over the map |
exerciseContract, exerciseComponent |
contracts as tests |
These ARE the audit's rules. Since tosijs-floorplan 0.5.0 there is no divergence and no private adjustment: the three carve-outs
audit.tsused to apply (ignore producerflags, exempt0×0, treat a list-bound element carrying direct evidence as a control — tosijs-floorplan #7/#8/#9) are folded into the shared rule, andauditAccessibility()calls these exports raw.The one knob is
targetSizeFinding'shonorProducerFlags, which defaults tofalse— the lint's answer, where a producer-suppliedtarget-ish flag does not stand the geometry check down.schematic()opts in (honorProducerFlags: true) so a drawing never double-marks a finding it has already painted. So the default is the AUDIT's verdict, and the renderer is the one that adjusts.(Earlier releases said the opposite here, and said it while pointing at a private
auditViewthat no longer exists. If you are working from a cached copy of this page: the exports and the audit agree.)
Why a subpath and not the main entry. The agent surface costs roughly
15 kB gzipped, measured marginally — the same ESM bundle built from
index.ts and from index-browser.ts, which is this library minus the agent
surface by construction. An app that never describes itself should not carry
it. Bundler users would shake it out — but the IIFE (CDN, <script>, our own
doc pages) cannot, and that is the most-loaded artifact we publish. Keeping it
here means the cost falls only on consumers who opt in, and the default bundle
stays roughly where 1.7.x left it.
For the current number, read README — its figure is generated by
bun run build, which prints both on every run. Two are worth telling apart: the marginal cost above, and the largermodule.js−core.jsdelta, which is a different question becausecorealso drops blueprints, share/sync and hotReload and so charges their bytes to the agent surface.This paragraph deliberately states no digits. Three hand-typed figures here said 11 kB for four releases while the truth drifted past 15, and the correction that replaced them was itself wrong — divided by 1000 instead of 1024, so its own two operands did not subtract to its own answer.
ComponentMap (the static contract shape) is exported from both
tosijs and here: declaring a contract is a component-authoring act that
must not require importing the agent surface. It is type-only, so it costs
nothing either way.