Skip to content

feat(web): API docs section and agent skill zip on the Developers page - #226

Merged
josue-commits merged 11 commits into
developfrom
feat/api-v1-skill-zip
Oct 13, 2026
Merged

josue-commits merged 11 commits into
developfrom
feat/api-v1-skill-zip

Conversation

@josue-commits

Copy link
Copy Markdown
Contributor

Summary

Adds the API docs section to the Developers page and a downloadable agent skill (zip) so members can point an AI agent at the dForms public API. The zip is served only to signed-in members and has the workspace's public API address injected into its files.

Changes

  • Zip writer and a resolver for the public API address (PUBLIC_API_URL); internal and private hosts are never exposed.
  • JSON Schema for the form config, with fields the API does not control removed and steps required.
  • Skill files (SKILL.md, endpoints, errors, examples) describing the v1 endpoints, roles and error codes.
  • Session-only route /api/developers/skill that serves the zip (401 without session, 403 when the workspace is not accessible, 503 when the API URL is not configured).
  • API docs section on the Developers page, EN and ES, with a "not configured" state.
  • Changeset.

How it was tested

  • pnpm typecheck, pnpm lint, pnpm test all green.
  • PUBLISH_GATE_LOCAL=1 pnpm run publish-gate passed.
  • Built a real zip; unzip -t reports 10 files OK and it unpacks to dforms-api/ with the injected URLs.
  • JSON Schema compiles in ajv (draft-07).
  • Rendered the section in headless Chromium (EN, ES, no API URL) at 375 px and 1280 px with no horizontal overflow.

Review notes (fixed by independent review)

  • The skill route now refreshes an expired access token once before answering 401.
  • DeveloperDocs accepts an optional locale prop so it composes with the Developers page shell.
  • Private and link-local IPv4/IPv6 hosts are treated as internal for the public API address.
  • Docs now list every owner/admin-gated area and the correct list order for GET /v1/forms.
  • A 403 from the session check is reported as 403 instead of 502.
  • Not changed: the section copy lives in its own catalog next to the component (to avoid colliding with the shared catalog edits in the Developers page PR); zip timestamps are written in UTC.

Coordination

  • Expected add/add conflict with the Developers page PR on apps/web/app/admin/developers/developer-docs.tsx: resolve to this branch. It accepts the locale prop, so page.tsx needs no change.
  • After both merge, the admin.developerDocs keys from that PR become unused; follow-up to move this section's strings into the shared catalog.
  • PUBLIC_API_URL must be set in each environment's web config. Until then the page shows the "not configured" notice and the zip route returns 503.
  • Docs assume the validation contract from the API validation PR: issue paths relative to the request body, and UNSUPPORTED_FIELD / EMPTY_QUESTION issue codes.

🤖 Generated with Claude Code

josue-commits and others added 8 commits October 12, 2026 16:59
A dependency-free ZIP writer (deflate or store, UTF-8 names) for the skill
archive, and publicApiUrl: the API address a customer can reach, read at
runtime from PUBLIC_API_URL, never a cluster-internal API_URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josue Hernandez <josue@daptatech.com>
Generated from formConfigSchema with zod-to-json-schema (zod 3), every
sub-schema inlined, minus the fields the editor has no control for. ajv
(dev only) checks it is a valid draft-07 schema that accepts the recipe
configs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josue Hernandez <josue@daptatech.com>
SKILL.md with its rules, the endpoint and error references, the config
schema, five recipes and INSTALL.md for Claude Code, Codex and Cursor.
The API and dashboard URLs are parameters, injected per request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josue Hernandez <josue@daptatech.com>
GET /api/developers/skill confirms the session with the API (401 without
one), then builds the zip with this environment's public API address and
dashboard origin. PUBLIC_API_URL is documented in .env.example.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josue Hernandez <josue@daptatech.com>
DeveloperDocs shows the runtime API URL, Bearer auth, the create, edit,
publish and revert flow, the traps, and the skill download, in English
and Spanish from its own catalog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josue Hernandez <josue@daptatech.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josue Hernandez <josue@daptatech.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josue Hernandez <josue@daptatech.com>
- The skill route refreshes an expired access token once before answering
  401, like hostFetch, so a download clicked long after the page loaded
  works for a member who is still signed in. A 403 from the API (workspace
  no longer theirs) answers 403 instead of a 502.
- DeveloperDocs takes the optional locale prop the Developers page already
  passes (<DeveloperDocs locale={locale} />), so the two branches merge
  without a type error.
- publicApiUrl treats private and link-local addresses as internal, so a
  Docker or VPC API_URL is never printed to customers.
- The skill docs name every role gate a member's key hits (notifications,
  brand kit apply and revert, webhook test) and list forms in the order
  the API returns them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josue Hernandez <josue@daptatech.com>
josue-commits and others added 3 commits October 12, 2026 17:13
…I_URL

When API_URL is cluster-internal, fall back to NEXT_PUBLIC_API_URL read from
the runtime environment instead of reporting the address as unconfigured.
Deployments that already set it per environment need no new variable.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josue Hernandez <josue@daptatech.com>
# Conflicts:
#	apps/web/app/admin/developers/developer-docs.tsx
The "How to use the API" section read its copy from a local catalog next to
the component. All UI copy belongs in the shared catalog, so it now lives in
admin.developerDocs, replacing the placeholder keys from the Developers page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Josue Hernandez <josue@daptatech.com>
@josue-commits
josue-commits merged commit e11b6fe into develop Oct 13, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant