# API Service (/docs/api-service)

# API Service

`@specemit/docs` owns the Next.js API route handlers and server modules in
`apps/docs`.

The docs app keeps the retained runtime routes available from the same service:

- `POST /sdk/generate`
- `POST /format-schema`
- `GET /docs/demos`
- `POST /docs/demos/process`
- `/rpc/*` upload, reopen, and delete operations

`/sdk/generate` normalizes SDK generation requests, keeps generated output under
`auto-generated`, and returns operation, type, issue, and generated file
metadata. `/docs/demos` and `/docs/demos/process` expose the fixed curated-demo
entry point without fetching public attribution URLs. `/format-schema` returns
Zod and TypeScript forms for a JSON Schema request body.

Upload and demo successes include data for the Specemit Docs, Code, and
read-only API Reference views. The reference surface is inspection-only; the
docs API does not add an operation proxy, request execution route, or
credential forwarding path for it.

Run:

```sh
bun --filter @specemit/docs run check
bun --filter @specemit/docs run dev
```

# Artifact operations (/docs/artifact-operations)

# Artifact operations

Use Bun 1.3.10 and Node 22+ with the repository lockfile. Install dependencies during
deployment with `bun install --frozen-lockfile`; requests never install dependencies.
Deploy the generator source/templates, its preinstalled node_modules, and the private
app worker/CAS scripts with the Next application. A standalone traced bundle alone
is not the supported deployment layout. Local storage supports macOS and Linux;
R2 uses the existing signed S3 adapter.

Set `ARTIFACT_POSTMAN_ENABLED=true`, `ARTIFACT_MCP_ENABLED=true`, and
`ARTIFACT_JOBS_ENABLED=true` independently to enable production outputs and submissions.
They default off in production. Rollback sets the relevant flags to false and restarts
application processes; existing docs reads, artifact downloads and stored records remain
available. Drain or cancel queued work before stopping workers if it must not execute.

```sh
bun run --cwd apps/docs worker:artifacts
```

Workers use the same project storage environment as the app. Each processes one job,
claims through compare-and-swap, leases for 60 seconds, renews every 15 seconds, and
fences completion by owner and unexpired lease. Retryable infrastructure failures get
at most three attempts. SIGINT/SIGTERM cancels child processes and leaves recoverable
work queued. Queued jobs pin immutable source/revision identities. Two workers may share
local storage through OS advisory locking or a private R2 bucket through ETags. Deploy
immutable generator sources to app and workers together. A queued job from an older
generator version fails with `ARTIFACT_GENERATOR_CHANGED`; resubmit it rather than caching
new output under the previous version’s identity.

## Quotas and limits

Projects receive 20 submissions/hour. Anonymous conversion, inspection, MCP generation
and job-submission requests share a storage-backed limit of 20/minute by default.
For per-IP quotas set `ARTIFACT_TRUSTED_IP_HEADER` to `cf-connecting-ip` or `x-real-ip`
and set a stable secret `ARTIFACT_QUOTA_SALT` of at least 32 characters. The trusted
edge must overwrite that header and prevent direct access to the origin. Arbitrary
forwarded headers are ignored. Also apply received-byte and connection limits at the
edge. Quota storage failure fails closed.

Uploads are limited to 50 MiB. Synchronous conversion/MCP accepts 10 MiB and 100 tools;
larger work uses jobs. Limits include depth 128, reference depth 64 excluding recognized
cycles, 50,000 paths/operations/schemas, 10,000 files, 50 MiB generated/archive output,
120 seconds synchronous and ten minutes background. Child processes use fixed arguments,
sanitized environments and per-phase deadlines. The generated HTTP runtime also enforces
received-byte limits, cancellation, host/origin checks and cleanup.

## Dashboard and maintenance

Set a private `ARTIFACT_OPERATOR_TOKEN` of at least 32 characters, open
`/operator/artifacts`, and enter the token. It remains in memory and is sent only in
an Authorization header. The dashboard exposes bounded counters, phase duration totals,
averages/maxima, CPU/RSS, output/file/operation counts, diagnostic categories, queue age,
retries, failures and cache hits. Worker CPU/RSS excludes separately spawned compiler
resource usage. No source, description, credentials, project IDs or generated code become
metric labels. Monitor `artifact_metrics_write_failed`, `artifact_quota_storage_failed`,
and `artifact_worker_storage_failure` events. The endpoint is uncached and unavailable
without operator authorization.

Live projects retain their complete artifact history. Operator cleanup removes workflow
objects only after a permanent project tombstone is at least seven days old and no active
lease remains. This preserves current project retention and protects reachable artifacts.
R2 cleanup does not assume support for conditional DELETE; all CAS operations use PUT.

```sh
bun run --cwd apps/docs artifacts:cleanup PROJECT_ID
```

Run cleanup only for intended deleted projects. Keep project tombstones; never resurrect
a deleted project ID. Retain backups and private bucket permissions. Anonymous synchronous
requests create no project history and their temporary directories are removed after use.

## Verification and rollout

Run `bun run test:artifacts`, `bun run test:generated`, and `bun run test:browser` after
building the Next application. Generated tests install fresh dependencies, compile, run
trusted mock-HTTP protocol fixtures over both backends/transports, and build/start Docker.
`bun run benchmark:artifacts` writes resource measurements for 10/100/500 operations and
schema/example/recursive/deep cases, including sampled memory for the entire worker and
compiler process tree. CI runs larger benchmarks and isolated converter-upgrade probes
on a schedule; candidate dependency versions are never auto-merged. No acceptance
gate is satisfied by a skipped generated-project, browser, Docker, or R2 test.

Start with local storage, then an isolated private R2 staging bucket. The existing staging
smoke requires all `R2_*` configuration and `R2_STAGING_SMOKE=1`. That smoke includes workflow CAS/list/read checks and cleanup. The local and mocked R2
suites exercise competing claims and recovery; run additional staged worker interruption
checks before enabling production jobs.
Never point staging checks at a production bucket. Exact unverified gates are recorded in
`packages/sdk-generator/ARTIFACT-WORKFLOWS.md`.

## Unified upload and Scalar rollout

`ARTIFACT_SCALAR_ENABLED=true` enables new Scalar downloads.
`ARTIFACT_INGESTION_ENABLED=true` enables background home uploads independently of
`ARTIFACT_JOBS_ENABLED`. The existing `bun server/artifact-worker.ts` worker processes
both queues, one job at a time. Enable the applicable flags on the app and worker.
Disabling submissions preserves existing projects and downloads.

Ingestion uses project edit capabilities, content-addressed inputs and prepared
snapshots, 60-second leases, 15-second renewal, and a maximum of three infrastructure
attempts. After preparation wins its lease-fenced compare-and-swap, publication is
immutable and recoverable; cancellation is rejected while the completed upload is
being saved. No raw edit token is stored in job or queue records. The same browser
retains its temporary capability to recover progress.

New generation manifests reference a separate immutable canonical snapshot object.
Both local and R2 readers hydrate it and retention protects reachable snapshot keys.
Older generation manifests remain readable without destructive migration.

# One upload, docs and API tools (/docs/artifact-workflows)

# One upload, docs and API tools

Upload OpenAPI 3.0/3.1, Swagger 2.0, or Postman Collection v2.0/v2.1 at the
[home page](/#upload-docs). JSON and YAML are detected from content. Postman imports
are converted automatically to canonical OpenAPI 3.1 before docs and SDK generation.

Your workspace has **Docs**, **SDK**, **API Reference**, and **Tools & Exports**.
The saved canonical snapshot powers Postman, MCP, Scalar, and OpenAPI downloads;
opening the project or generating another output does not reconvert its upload.
Documentation edits remain separate from the API contract. Switching tabs preserves
an open editor draft. Download the current documentation archive or SDK from the
workspace header. The former `/artifacts` entry redirects to the home upload.

Uploads above 10 MiB use a durable background upload job. Keep the same browser to
recover progress after refresh, cancel, or retry without uploading the file again.
If project storage fails after synchronous generation, the current-session preview
and downloads remain available. A session preview can be saved from Tools & Exports.

## Convert and synchronize Postman

Choose Postman Collection v2.1 to export, or OpenAPI JSON and YAML to import a
collection. Both OpenAPI serializations describe the same canonical object.
Choose folders by tags or paths, request naming, schema/example resolution,
authentication examples, and generated examples. Review the compatibility report:
**Inferred** identifies contracts reconstructed from examples; **Dropped** identifies
behavior that cannot be represented; **Unsupported** describes a known limitation;
**Blocking** prevents a successful artifact.

Collection scripts, chaining, runner behavior, dynamic variables, local file
references, disabled fields, and inference limitations are reported. Scripts are
never executed and local files are never read. Credential values become runtime
placeholders in imported contracts. Review inferred request and response schemas
before using them as your API contract.

For synchronization, select an OpenAPI revision and upload the existing collection.
Review added, changed, removed, and retained requests and collection settings.
Unmatched requests are preserved unless you explicitly enable removal. Collection
scripts remain inert custom data. A review acknowledgement enables the candidate
download. The uploaded file and remote Postman workspaces are never overwritten.

## Generate an MCP server

Zod and stdio are the defaults. Valibot emits its own runtime schemas and has no
**direct** Zod dependency or generated Zod imports; MCP SDK v2 has its own Zod
dependency. Choose stdio, stateless Streamable HTTP, or both. Both entrypoints use
the same server factory, tools, request adapter, and validation.

Filter by resource/tag, operation, or method. Include filters intersect and
exclusions win. Deprecated and internal operations are excluded by default;
read-only selection is explicit. Empty selections are rejected. More than 50 tools
produces a warning; more than 100 needs acknowledgement and a project job; 500 is
the hard limit. An operation that cannot be represented faithfully blocks generation
and is identified in diagnostics.

Inputs use `pathParams`, `queryParams`, `headerParams`, `cookieParams`, and
`bodyParams`. Required fields and names shared between locations retain their
meaning. File inputs use bounded inline base64 data with optional `filename` and
`contentType`; filesystem paths and file URLs are unsupported. Structured responses
use `{ data: ... }`, including primitives, arrays, and no-content responses.

Download the ZIP and run `bun install`. Use `bun run dev` for the Hono server during
development, or `bun run build` followed by `bun run start` for compiled execution.
Use `bun run start:stdio` when an MCP client launches the compiled server itself.
Node 22 or newer and Bun are supported. Production generation validates and typechecks
output against preinstalled pinned dependencies; it never installs packages or runs
the generated server. Executable verification uses trusted repository fixtures only.

## Authentication and deployment

The UI and `.env.example` list environment-variable names, without credential values.
The runtime supports header/query API keys, bearer tokens, basic authentication, and
existing OAuth bearer tokens. Each operation chooses its own security requirements,
including OR alternatives, AND combinations, and anonymous alternatives. Ordinary
arguments cannot replace configured API credentials. Redirects are not followed.
OAuth authorization/refresh storage, mTLS, and request signing remain out of scope.

Operation servers override path/document servers. `SPECEMIT_API_BASE_URL` or a fixed
generation option overrides the selected server. Declared server variables are
validated against their defaults/enums. Set outgoing credentials in the environment
of the generated server; do not distribute a populated environment file.

HTTP binds to loopback by default. `/mcp` is separate from `/health`.
`SPECEMIT_MCP_TOKEN` optionally protects incoming MCP requests and is independent of
outgoing API authentication. Remote deployments should use it or equivalent
authentication at a TLS reverse proxy, plus allowed host/origin configuration.
Source OpenAPI and Dockerfile inclusion are explicit, default-off options. The
generated README documents the selected transport.

## Project history and background work

Create a documentation project and open **Artifacts** to generate from a saved
revision. Jobs survive browser closure and worker restarts. History, metadata,
cancellation, and downloads require the existing project edit token. Public readers
cannot access original uploads, job details, or private history. Generation never
replaces prose edits or switches the current reader/editor view.

Source bytes, options, templates, and pinned dependencies determine cache identity.
Identical inputs produce identical files and ZIPs. Manifests contain fixed build
timestamps, source hashes, file hashes, versions, selected/excluded operations and
diagnostics; history preserves real submission and completion times. Old project
records are read without destructive migration.

See `/docs/artifact-operations.md` for rollout, workers, quotas, maintenance and CI.

## Scalar API reference viewer

Choose **Scalar API reference viewer** under Tools & Exports. The ZIP includes a
pinned Scalar 1.67.0 browser bundle, canonical `openapi.json`, manifest, compatibility
report, license, and a small Bun server. Run `bun start` in the extracted directory.
No dependency installation or CDN connection is required. The server binds to
127.0.0.1; set `PORT` to select another port. This is a reference viewer, not a mock API.

The in-workspace preview runs in an opaque sandbox. API execution, authentication
persistence, telemetry, remote fonts, and external images are disabled. The original
read-only API Reference remains a separate workspace view.

# AI and LLM Access (/docs/llms)

# AI and LLM Access

The docs app exposes static documentation in Markdown for AI tools and crawlers.
These endpoints only include the public docs content under `apps/docs/content/docs`;
uploaded or saved generated docs are not included.

- `/llms.txt` lists the available docs pages.
- `/llms-full.txt` returns the complete static docs corpus.
- `/docs/sdk-generator.md` returns a single docs page as Markdown.

Use the same paths on the deployed docs domain, for example
`https://your-docs-domain.com/llms.txt`.

# Migration Map (/docs/migration-map)

# Migration Map

Runtime APIs live in the Next.js application. SDK parsing, generation, and artifact
workflows belong to the SDK generator package; shared presentation belongs to the UI package.

| Old Path or Command         | New Path or Command                                          | Notes                      | Owner                               | Status  |
| --------------------------- | ------------------------------------------------------------ | -------------------------- | ----------------------------------- | ------- |
| `src/index.ts`              | `apps/docs app route handlers and server/api modules`        | Current workspace boundary | `@specemit/docs`                    | retired |
| `src/sdk-generate-utils.ts` | `apps/docs/server/api/sdk-generate-utils.ts`                 | Current workspace boundary | `@specemit/docs`                    | moved   |
| `src/utils/`                | `Effect-backed createClient runtime`                         | Current workspace boundary | `@specemit/sdk-generator`           | retired |
| `openapi-sdk/`              | `packages/sdk-generator/src/`                                | Current workspace boundary | `@specemit/sdk-generator`           | moved   |
| `openapi-sdk/templates/`    | `packages/sdk-generator-templates/src/typescript/templates/` | Current workspace boundary | `@specemit/sdk-generator-templates` | moved   |
| `2025/`                     | `Effect-backed createClient runtime`                         | Current workspace boundary | `@specemit/sdk-generator`           | retired |
| `src/*.json`                | `packages/sdk-generator/fixtures/`                           | Current workspace boundary | `@specemit/sdk-generator`           | moved   |
| `bun run dev`               | `bun --filter @specemit/docs run dev`                        | Current workspace boundary | `@specemit/docs`                    | renamed |
| `bun run test`              | `bunx turbo run check plus targeted bun test`                | Current workspace boundary | `root`                              | renamed |

New artifact workflows extend `packages/sdk-generator/src/generator/artifact-workflows` and `apps/docs/server/api`. MCP templates live in `packages/sdk-generator/templates/mcp`; existing SDK templates remain in `packages/sdk-generator-templates`. Vendored repositories under `repos/` remain read-only references.

# SDK Generator (/docs/sdk-generator)

# SDK Generator

`@specemit/sdk-generator` owns the moved OpenAPI parser, generator, templates,
fixtures, and public `createClient` export. Its source fixtures live in
`packages/sdk-generator/fixtures`.

Users can generate from the homepage upload flow. Successful sessions open a
Specemit workspace with **Docs**, **Code**, and **API Reference** views. The API
Reference is read-only; it does not send requests, collect credentials, or use
a proxy route.

Generated SDK samples must stay tied to a source fixture, the generator path, the
command that produced them, and generated-output review evidence.

Run:

```sh
bun --filter @specemit/sdk-generator run check
```

# Verification (/docs/verification)

# Verification

Run story-specific integration checks before the full Turborepo check:

```sh
bun test tests/integration/api-service-boundary.test.ts tests/integration/docs-content.test.ts
bun --filter @specemit/docs run check
```

When the docs service is started, verify the implemented UI with agentbrowser.
Cover the homepage upload flow. Generated sessions must keep Docs, Code, and the
read-only API Reference reachable without horizontal overflow, hidden focus
indicators, request sending controls, credential inputs, or operation-server
network calls. If credentials are required for a protected screen, request them
from the user.

After any Bun, Next.js, or Turborepo dev service is started, stop it and
record cleanup with:

```sh
bun scripts/verify-port-cleanup.ts 3001
```