useCapabilityManifest

Read the api's capability manifest (procedures + tables + schemas) from the browser, without codegen.

What does this api actually expose? useCapabilityManifest answers that at runtime: a one-shot fetch of /_voltro/inspect/manifest — the same inspect surface useProvenance rides. It is a structural lookup, not a live subscription, so it does not re-fetch on data changes.

import { useCapabilityManifest } from '@voltro/client'

const { manifest, loading, error } = useCapabilityManifest('app')

The manifest carries:

Field Contents
procedures Every procedure's tag, kind, input/output Schema, plus the source table a query reads and the targets ({ table, op }) a mutation writes.
tables The user tables — name, columns (type, nullable, refersTo, enum), and whether the table is reactive. Framework _voltro_* tables are flagged framework.
workflows The discovered workflow names.
widgets The registered widget ids.
version The manifest format version.

Deriving an admin surface

deriveEntityAdmins(manifest) is the pure projection the admin template is built on. It joins each user table to the procedures that read and write it, so a generated back-office binds to tags that actually exist instead of guessing them from a naming convention:

import { useCapabilityManifest, deriveEntityAdmins } from '@voltro/client'

const { manifest } = useCapabilityManifest('app')
const entities = manifest ? deriveEntityAdmins(manifest) : []
// each: { table, columns, reactive, listTag?, createTag?, updateTag?, deleteTag?,
//         createScope, writeScope, deleteScope }

A tag is undefined when the app exposes no procedure for that operation — render that affordance read-only rather than binding to a tag that does not resolve. The *Scope strings are the conventional names the UI gates writes on via useCan; map them to your app's real RBAC scopes.

The inspect surface is open in dev. When a deploy sets an inspect token the manifest GET is bearer-gated, so an admin UI pointed at a locked-down api has to supply that token — a deployment concern, not something this hook handles.