tappify extension doctor runs these checks on your
machine, and Tappify runs them again on the bundle you upload, so nothing here should be a
surprise.
What the manifest has to pass
manifest.schema is one id carrying the whole schema, so these all arrive under it:
- A widget’s slot that is not on its page, and a series naming a metric your connector does not declare.
- Contributions that imply a scope you did not declare — rendered UI needs
ui:render, hosted storage needsstorage:write, markers needui:renderandalerts:write, an action needsai:actionsand its own declared scope. - A scope whose definition asks for a justification, without one of 20 to 500 characters.
- Limits: 20 UI contributions, 15 assistant tools, 10 actions, 10 storage collections, 5 skills, 20 prompts, 3 context providers, 30 procedures, 20 telemetry names.
- A banner or marker naming an event your webhooks do not declare.
- A storage collection called
settings, which the settings contribution owns. - A prompt whose
afternames a tool id that is not yours. - A telemetry name that is not
snake_case. server.baseUrlmissing when a connector, webhook, assistant contribution, work destination or procedure exists, and any declared host that is nothttps.- An
sdkrange naming no major Tappify serves. - A
publicextension without all five listing fields. - An
organization-scoped extension declaring pages, tabs, widgets or series. - A
pricingorscoreblock, which the schema reserves and does not accept yet.
What the bundle has to pass
What your server has to answer
There is no check id for this one. After the bundle passes, Tappify asks<base url>/tappify/health for a 200 within three seconds, on server.baseUrl and on
server.sandboxBaseUrl if you declared one. A redirect is a failure, and the publish stops
there. See Deploy your server.
What does not stop a publish
Three rules are warnings. They print underdoctor and a release goes out with them:
storage.pii, a storage schema field named email, name, phone, address or ip,
which a reviewer reads before it goes live; procedures.write_kind, a write-shaped procedure
name without kind: "write"; and bundle.style_injection, built code that writes styles
into the document. A publish reports only what stopped it, so doctor is where you read
them.
Your typecheck, lint, tests and accessibility pass are not run at publish — publish runs
doctor with your own scripts left out, because it has just run your build. doctor runs
them, and they are the reason to run it before you publish rather than after.
doctor also checks the files on your disk before they ever reach a zip — a missing entry,
an icon that is not square, a screenshot at the wrong size, a $ref that points nowhere, a
stale src/tappify.d.ts. Those ids are on
Doctor checks.
What a reviewer reads
Automated checks decide whether a release can be reviewed at all. A person then reads:- Every scope you asked for against the justification you wrote, and whether the contributions need them.
- The diff against your live release: which scopes are new, which contribution kinds are new, and whether the release widens who can install.
- Every word your extension puts in front of the assistant — tool descriptions, skills, prompt templates, knowledge files.
- Your listing, screenshots and privacy URL, for a public extension.
- Your release notes.