Ctrl K
ComunidadGuías…

llms.txt

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<!-- urlcode-current-version:start -->
# URLCode

> A portable runtime for programmable URL behavior, and the framework that grows
> from it: routes in YAML, functions and middleware, then accounts, data, MCP tools and
> stored links as operator-installed extensions. Stable project format
> `version: "1"`. Core is Apache-2.0; this revision is `0.6.6`. `function`/`middleware`
> routes are trusted by default with `sandbox: true` as the per-route opt-in. The
> auth, store and mcp extensions are add-ons released with core and pinned by
> it; a site adds them with `urlcode extensions add <name>`. Only core is published to npm.
<!-- urlcode-current-version:end -->

Use the schema and docs from the runtime revision you run. Do not assume Node,
fetch or database access inside a `sandbox: true` function, regex routes,
global middleware, YAML interpolation, or packages named in YAML. Secrets need external revision-pinned
grants. Unsupported features fail with the route named; nothing degrades silently.

## Start here (read only this section for a first attempt)

1. Before writing anything, run `npx --no --package @jimhoyd/urlcode urlcode bootstrap DIR --capabilities NAME,... --json` (MCP `get_context` with `bootstrap: true`):
   site and route-project roots, entry and host file, pinned/installed runtime against this one, exact commands to run from
   the site root, the site/project path mapping and this runtime's schema fragments for the capabilities you name. It creates
   nothing unless you add `--create` with an explicit DIR ([local agent bootstrap][docs/TOOLING.md#local-agent-bootstrap]).
   If DIR already holds your files (a built `frontend/`, say), add `--adopt` too: the site is written around them, nothing is
   moved or overwritten, and any collision is refused with the paths listed. Then copy or build the frontend into `app/`.
   Then run `npx --no --package @jimhoyd/urlcode urlcode context --project DIR` (MCP `get_context`). For redirect-only work run
   `npx --no --package @jimhoyd/urlcode urlcode context --project DIR --task redirects`: supported shapes with exact YAML, gaps
   with their exact validation error, a paste-ready `starter`, and this project's own redirects.
   For a goal that spans routes, persistence or extensions, `urlcode plan-feature "goal" --project DIR --json` (MCP
   `plan_feature`) names the matching recipes and the extension authoring surfaces the goal asks for (store ownership,
   transitions, membership and readers; auth route protection), from installed or catalog descriptors; its `commands`
   end with `urlcode recipes add NAME --project app`, which merges a recipe into the site's `app/` (routes, includes,
   extension config, fixtures, seed and the audit count; any clash refuses it all, named) instead of copying its files (MCP `merge_recipe` with `--allow-authoring`, for the served project only). With `--host-file`,
   `explain`, `plan-feature`, `context` and `review` read the registrations without a revision pin; anything that
   activates (`validate`, `test`, `dev`, `serve`) still needs the reviewed pin, which `urlcode permissions --project app` prints.
   The site's check scripts and the authoring MCP runners review each edit without a new pin; serving still needs one
   ([the local review loop][docs/EXTENSIONS.md#the-local-review-loop]). The audit's expected route count is committed once
   in `app/tests/audit.json`. Such a hermetic run refuses an extension built for extension contract 1 and any registration
   `composeHost` did not compose on the run's own data directory (`hermetic-host-unconfirmed`), and removes its
   `urlcode-hermetic-<pid>-*` directory even when interrupted ([hermetic runs][docs/EXTENSIONS.md#hermetic-runs-and-test-seeds]).
2. After installing `@jimhoyd/urlcode`, run `npx --no --package @jimhoyd/urlcode urlcode init .` (it works in a directory holding only `package.json`, `package-lock.json`, `node_modules`, `.git`, a pre-registered `.mcp.json` (see next paragraph) or a coding-agent client's own `.claude/` or `.codex/` state, which init never writes into or changes, and preserves existing package metadata). It writes a bare agent-ready site: the route project `app/` (`urlcode.yaml` with no routes), `host.mjs` (the operator host), `package.json` with an exact runtime pin and npm scripts, `AGENTS.md`, local `.mcp.json` (kept as-is if one is already there), and project CI. Then run `npx --no --package @jimhoyd/urlcode urlcode validate --local` and `npx --no --package @jimhoyd/urlcode urlcode test` from the site; `--project` defaults to `app` there. `--no` refuses a registry fetch, so it always uses the installed scoped runtime.
   `.mcp.json` only exists once `init` writes it, so Claude Code, which loads a project's `.mcp.json` at session start, sees no `urlcode` tools on the very first turn that creates a project. To have MCP `get_context` and friends available from that first turn, register `.mcp.json` *before* starting the agent session: `npx --no --package @jimhoyd/urlcode urlcode mcp print-config > .mcp.json` in the target directory, then start the session there. The server answers normally against the still-empty directory (a project-reading tool such as `get_context` returns the same `run urlcode init there to create a project` guidance the CLI prints); once `init` runs, the same session's next MCP call succeeds — no restart needed. Codex does not read `.mcp.json`: register the same pinned command under `[mcp_servers.urlcode]` in `~/.codex/config.toml` or a trusted project `.codex/config.toml`, with the site root as `cwd`, or with `codex mcp add` ([registering the server][docs/TOOLING.md#registering-the-server]). If a client cannot be bootstrapped that way, run `init` as a plain CLI call for the first turn instead, then continue with MCP registered. Where a sandbox forbids writing client configuration (`init-write-denied` naming `.mcp.json`), use `init . --no-mcp`: the same site without `.mcp.json`, reported as `mcpRegistration: skipped`; do not work around the policy.
3. Do not read or grep [llms-full.txt](llms-full.txt) (about 60k tokens) for a routine task; `get_context`,
   `capabilities`/`get_capability`, `search_docs` and `search_recipes` answer it. It is the deliberate
   fallback when those do not: only then, locate the one matching heading (never the whole file) — a
   source checkout also has the matching page directly under `docs/`.
4. Hosted reference and skills are optional: connect a compatible HTTP MCP
   client to `https://urlcode.ai/mcp`, which needs no key and runs no model of
   its own. Keep `urlcode mcp` registered for project-aware inspection and
   validation. Start with the
   hosted [agent guide](https://urlcode.ai/llms.txt), then see
   [hosted AI MCP setup][docs/TOOLING.md#optional-hosted-ai-mcp].
   Only when the user asks for it, the authoring skill's
   [hosted-assisted mode][docs/AI-AUTHORING.md#hosted-assisted-authoring-opt-in]
   calls `urlcode_task_plan` before writing YAML, then verifies locally.

| Shape | Supported? | Use |
|---|---|---|
| Fixed redirect, 301/302/303/307/308 (302 default) | Yes | `redirect: {url, status}` |
| Parameterized path (`/users/{id}` to `/profiles/{id}`) | Yes | `{name}` in `redirect.url`, naming a declared path parameter |
| Root-relative destination (`/users/{id}` to `/profiles/{id}`) | Yes | `redirect.url: /profiles/{id}`: one leading slash, path only |
| Wildcard suffix (`/legacy/**` to `/modern/{**}`, any depth) | Yes | terminal `/**` key with a literal prefix; `{**}` is the remaining segments (redirect only; not static or Cloudflare) |
| Query-string preservation | Yes, opt-in | `redirect.query.pass` / `query.map` |
| Method-preserving redirect | Yes | `methods` plus `status: 307` or `308` |
| 404 for unmatched paths | Yes | `site.notFound` (project-relative `.html`) |
| SPA fallback (client routes answer `index.html`) | Recipe, not native | [recipe `spa-shell`][recipes/spa-shell/README.md]: root `/*` static mount plus an operator plugin in `--host-file`; self-hosted only |
| Host or scheme chosen from the request | No | destination is a literal absolute `https://` URL or a root-relative path; report the gap |

## Declarative-first

Use the highest-level declarative feature before writing a function or middleware. Custom code
only when the framework cannot express the requirement; then report the gap. Never invent fields
or bypass target limits or operator grants ([design principle][docs/PROJECT-DIRECTION.md#design-principle-declarative-first]).

| I need | Use |
|---|---|
| Security headers | `policies.security` ([security][docs/policies/security.md]) |
| Cache headers / cache strategy | `cacheControl` / `policies.cache` ([assets][docs/yaml/assets.md], [cache][docs/policies/cache.md]) |
| Body size, content type, JSON check, per method | `request.body.<METHOD>` ([HTTP][docs/HTTP.md]) |
| One JSON Schema for a route body, an MCP tool and a store collection, or a standalone schema file with local `$ref`s | top-level `schemas:` (inline, or `{file: schemas/x.json}` read offline, remote refs refused), named as `request.body.POST.schema: x`, mcp `inputSchema: x` and a store collection's `schema: x` (a flat record; its `defaults` and `readOnlyProperties` stay on the collection); the OpenAPI export emits it once as a component ([named schemas][docs/HTTP.md#named-schemas]) |
| Restrict HTTP methods | `methods` (default GET/HEAD; 405 with `Allow`, before any extension `authorize()`, so an undeclared method on an `auth: true` route is 405, not 401/403) |
| Rate limiting, bot/AI-crawler blocking, compression | `policies.throttle`, `policies.agents`, `policies.compression` ([policies][docs/POLICIES.md]) |
| Fixed JSON/text/headers | `respond` and `response.headers` |
| robots.txt, sitemap, favicon, security.txt | top-level `site` ([site][docs/SITE.md]) |
| Sign-in, sign-out, protected routes | `extensions.auth: {version: "1", config: {}}` (a thin Better Auth adapter; `urlcode extensions add auth`, then `npx urlcode-auth migrate` for the bundled SQLite file, or the owner's own Better Auth database as `auth({database, testDatabase})` in host.mjs), an `/api/auth/*` mount with `extension: auth` and `methods: [GET, POST]`, then `auth: true` on each protected route (its function reads `context.capabilities.auth.identity.userId`; there is no role, permission or CSRF key); browsers sign in with `createAuthClient({basePath: '/api/auth'})` from `better-auth/client`; roles and permissions are application data ([auth][packages/auth/README.md], [the `auth` short form][docs/EXTENSIONS.md#protecting-a-route-the-auth-short-form]) |
| Application rules needing the signed-in caller | with the bundled store installed, first its declarations: owned collections, declared transitions and membership gates (end-to-end example with no application code: [proofs/private-requests][proofs/private-requests/README.md]); otherwise ordinary YAML function routes with `auth: true`, explicit methods and bounded request bodies, where the trusted function reads the verified user id from `context.capabilities.auth.identity.userId` (not available to `sandbox: true` routes) ([request-bound capabilities][docs/EXTENSIONS.md#request-bound-capabilities], recipe `authenticated-json-api`) |
| Audit log | `audit: true` on a store collection: its writes are recorded in the store's own database, in the same transaction, kept to `auditRetention`, read with `urlcode-store audit`, and forwarded to any sink through the tap `StoreExports.audit` (core's `AuditTap`: `peek`, then `ack`; `status()` counts events pruned before any sink peeked them) ([audited writes][docs/STORE.md#audited-writes]) |
| Persistence | the owner's choice: the bundled store is a default, and a trusted function may call any database library directly instead (end-to-end with `node:sqlite`, `auth: true` and no store extension: [proofs/native-storage][proofs/native-storage/README.md]; store declarations without the store extension are refused, not emulated). The operator-installed store extension: recipes `store-crud`, `store-booking`, `store-credits` and `store-approval`, each collection's record `schema` a JSON Schema 2020-12 object schema in the request body profile, inline or a named project schema, with store behavior (`defaults`, `readOnlyProperties`) beside it on the collection (422 with the body-schema issues; [record schema][docs/STORE.md#record-schema]), described by `urlcode openapi --host-file`, per-record ownership (`ownership: owner` on a collection behind `auth: true`, [store ownership][docs/STORE.md#per-record-ownership]), declared single-record `transitions` and `Idempotency-Key` replay ([transitions][docs/STORE.md#conditional-transitions-and-result-aware-retries]), permissions as data: a `membership: true` collection of principal ids gating a transition or a create (`members`, `create.members`) and named read-only cross-owner `readers` mounts, each with its own gate and optionally a projection of listed properties (`readers.<name>.properties`, a directory that hides balances beside a members-only full view) ([membership gates][docs/STORE.md#membership-gates-and-cross-owner-reads]), a declared non-overlap `intervals` constraint for scheduling, with fixed-length aligned slots (`length`, `step`, and `origin` for a fixed-offset local grid) (`409 interval_conflict`, [intervals][docs/STORE.md#non-overlapping-intervals]), declared `transfers` moving a whole amount between two records' balances with the sum conserved (`409 insufficient_balance`, [transfers][docs/STORE.md#declared-transfers]), `editable`/`deletable` states outside which `PUT`/`PATCH`/increments/`DELETE` answer `409 record_locked` ([edit and delete states][docs/STORE.md#edit-and-delete-states]), `unique` string properties across owners (`409 value_taken`, [unique handle][docs/STORE.md#a-directory-by-a-unique-handle]) and retry-safe host transactions (`StoreExports.transaction(work, {idempotencyKey})`); one serving process per database on local disk, a second one refused by an OS lock ([one serving process][docs/STORE.md#one-serving-process-per-database]); holds and filtering beyond equality are gaps |
| A form: validate a submission, email it, rate-limit it | a frontend posting JSON to a route whose `request.body.POST.schema` validates it before code runs (`format: email` and the other standard formats); `respond` answers and `signals` notifies a hook with no project code (recipe `contact-form`); to email it, a trusted `function` calls the provider's SDK, HTTP API or nodemailer with its credentials in granted `secrets`; `policies.throttle` limits the route |
| A frontend over store collections | the application's own code: `fetch` to the JSON mounts, reading a list's `etags` (send `If-Match`) and `may` (offer only allowed transitions); URLCode ships no component kit or screens. Reference: [proofs/private-requests/client][proofs/private-requests/client/main.js]; for shadcn/ui use the official tooling and `urlcode artifacts stage` |
| Frontend at the site root beside `/api/...` extension mounts | a root `/*` `static` mount (`index: index.html`) plus the extension mounts: the longest mount prefix wins, so each extension keeps its whole mount; a route inside an extension's mount, or an extension mount enclosing another, fails `urlcode validate` naming both routes ([site-root frontend][docs/ROUTING.md#a-site-root-frontend-beside-api-extension-mounts]) |
| Stored short links (create, redirect, click count) | operator-installed store extension's `shortLinks` capability: a collection `key`, a `format: uri` `destination` property (HTTP(S) only), one `increments` counter, and a public `/go`-style redirect mount; no function needed (`urlcode docs search "shortLinks"`, MCP `search_docs`) |

When only code can do it, one function serves one or more routes:

```yaml
  /hello/{name}:
    function: functions/hello.mjs   # binds args.name; context.route.pattern is "/hello/{name}"
```
```js
export default (request, { args, route }) => Response.json({ hello: args.name });
```

Function handler shape: a module whose `export default` is `(request, { args, env, route, requestId })` and returns a
`Response` (or a promise of one). `args` holds the route's declared path inputs; the string form
`function: functions/hello.mjs` and the long form `function: {source: ...}` both bind every declared path input
(write `args: {}` to bind none). `sandbox: true` is a separate route option. `route.pattern` is the matched pattern; `env` holds route-scoped values only; `requestId` is the response's `X-Request-Id`.
Search the docs with bounded output using `npx --no --package @jimhoyd/urlcode urlcode docs search "TEXT" --project app` (MCP `search_docs`)
rather than grepping llms-full.txt. It covers the core agent docs plus the guides and `urlcode.json` schemas of add-ons
installed and verified in the site (core-pinned, or independent with lock integrity and recorded files), reports which sources it did and did not search, and names one section or
config path to read next; no match means no match in those sources, not an unsupported feature.
Draft `tests/requests.json` from `urlcode fixtures suggest --json` (MCP `suggest_fixtures`): it reads urlcode.yaml and its
includes, covers only routes the YAML alone determines and lists function, middleware, proxy, extension, pattern and
binding routes as `gaps` to test by hand. For write-capable or streaming function/middleware routes it adds
`verificationGaps`: the stateful handler verification matrix (`urlcode docs search "stateful handler verification"`) as untested application-supplied
expectations, never coverage; rows a fixture cannot express need an ordinary test. An `auth: true` route is covered by a `steps` fixture that signs in through
the provider's own endpoint, with `"origin": "{{origin}}"` on unsafe requests, and its accounts and memberships are
declared in `tests/seed.json` (each test and audit run starts from a fresh database holding exactly that seed); the auth
mount is a route too, covered by an `expectJson` on each sign-in (`/user/id`) and a `GET /api/auth/get-session` case, as
the `auth: true` recipes' fixtures do, which run unchanged in a site with `urlcode extensions add auth`; `expectJson`
asserts chosen values of a JSON body by JSON Pointer; a passing case counts only with
`expectBody`, `expectJson` or `expectHeaders`, a covered GET implies HEAD, `expectSignals` asserts the signals a request emits
(`urlcode test` and `audit` record them and deliver none; `urlcode dev --signal-sink stdout` prints them), and `audit`'s `coverageNotes` names what is missing
([authenticated routes][docs/READINESS.md#authenticated-routes-auth-true]). `urlcode diff BEFORE --json` (a YAML file, or a directory to compare includes
too; MCP `summarize_yaml_change`) names the routes, code seams and operator grants a change adds;
`urlcode report BEFORE > report.html` renders it, the review findings and each route's request path as a read-only page for a person;
`urlcode studio BEFORE` serves that page on localhost and rebuilds it on every reload.
The default `urlcode mcp` tools never execute project code: run fixtures with `urlcode test`. MCP `run_tests` executes the
project's trusted functions, middleware and extensions, so it exists only when the operator adds `--allow-authoring`.

Handler for the response: fixed text or JSON is `respond`; one HTML file is `page`; a directory is
`static`; an attachment is `download`; a short HTML snippet is `respond` `text` with a
`Content-Type: text/html; charset=utf-8` header. Functions are trusted by default; add
`sandbox: true` to opt a route in ([function security][docs/FUNCTION-SECURITY.md]).

After a real attempt, draft feedback only for a capability gap, repeated workaround, documentation
gap or suspected defect, with sanitized YAML and validation evidence. Search existing issues first;
never publish or comment without the user's approval.

## Reference (load one only when needed)

- Authoring: [AI authoring contract][docs/AI-AUTHORING.md], [YAML guide][docs/YAML-GUIDE.md], [field reference][docs/YAML-REFERENCE.md], [JSON Schema](schemas/urlcode.schema.json), [semantics][docs/SPECIFICATION.md], [cookbook](examples/cookbook/README.md), [recipes][docs/RECIPES.md].
- Skills (MCP `list_skills` returns all three with their own descriptions): [authoring loop](skills/urlcode/SKILL.md), [authoring](.claude/skills/urlcode-authoring/SKILL.md), [operations](.claude/skills/urlcode-operations/SKILL.md).
- Routes and handlers: [routing][docs/ROUTING.md], [HTTP][docs/HTTP.md], [middleware][docs/MIDDLEWARE.md], [assets][docs/ASSETS.md], [conditions][docs/CONDITIONS.md], [egress][docs/EGRESS.md], [prerender][docs/PRERENDER.md], [site][docs/SITE.md], [organization][docs/ORGANIZATION.md].
- Extension keys: core's field reference stops at `extensions.<name>.config`; every first-party extension's configuration, route-policy and hook fields are in its package README's generated field reference, indexed with a capability-to-keys map in [extension field references][docs/EXTENSION-REFERENCE.md]. For an installed add-on, `urlcode docs search "<key>" --project app` (MCP `search_docs`) reaches the same section.
- Extensions: [extensions][docs/EXTENSIONS.md] (including [add-ons: extensions and artifacts][docs/EXTENSIONS.md#add-ons-extensions-and-artifacts]; MCP `get_extension_artifacts` and `inspect_extension_artifact`, CLI `urlcode artifacts inspect`, installed files checked offline against `addon-files.lock.json` by `list --strict` and `urlcode extensions|artifacts verify` ([the installed file record][docs/EXTENSIONS.md#the-installed-file-record]), re-running `add <spec>` upgrades an independent package and `outdated` reports newer registry versions ([upgrading an independent package][docs/EXTENSIONS.md#upgrading-an-independent-package]), [independent artifact packages][docs/EXTENSIONS.md#independent-artifact-packages]; every released add-on's agent references: MCP `get_release_addon_catalog`, [release-wide discovery][docs/EXTENSIONS.md#the-release-wide-agent-catalog], not evidence of installation; writing one: [generic add-on authoring rules][docs/EXTENSIONS.md#generic-add-on-authoring-rules]), [the composition contract][docs/FRAMEWORK.md#the-composition-contract], [package and channel alignment][docs/VERSION-ALIGNMENT.md]. Add an extension with `urlcode extensions add <name>` (it installs the tarball core pins, writes its YAML and routes, and wires `host.mjs`); it writes the capability only, and `--example` also writes that extension's demo (store's `/api/todos`); use that managed installer for first-party add-ons. Inspect the installed stack first; first-party extensions are defaults, not requirements, and a trusted function may use any npm library directly ([owner choice][docs/EXTENSIONS.md#native-independent-integration-or-bundled-default]); external/private extensions are allowed and installed separately, then explicitly wired into the operator host. Follow the [external-extension workflow][docs/EXTENSIONS.md#external-extensions-and-ai-tooling], including host-aware discovery and validation. [urlcode-auth][packages/auth/], [urlcode-store][packages/store/], and [urlcode-mcp][packages/mcp/] are the extension sources; an independent package may take one of their names (the name is the role) while the first-party one is not installed. An `extension:` mount may declare route `env` under the same operator grant as a function route; it reaches the extension as `ExtensionRequest.env`, and hooks/handlers are called as `(input, {requestId, env, ...})` ([request context][docs/EXTENSIONS.md#request-context-route-env-and-request-id]). A site served on several origins keeps one canonical `--origin` and lists the others with the operator's repeatable `--alias-origin` (never YAML); every extension's same-origin check admits them through core's one rule, `isSameOriginRequest` ([site origins][docs/EXTENSIONS.md#site-origins-and-same-origin-checks]). Per-route middleware is native core (`middleware:` array), not a retired extension; core has no native `link` handler, but the store extension's `shortLinks` capability covers create, invalid-destination, redirect, missing-code and click-count for stored short links without a function — declare it under `extensions.store.config.shortLinks` (`urlcode docs search "shortLinks"`, MCP `search_docs`). Only report a gap for stored-link needs beyond that (custom redirect status, non-HTTP(S) destinations, per-record ownership).
- Tooling: [tooling and MCP][docs/TOOLING.md], [TypeScript][docs/TYPESCRIPT.md], [capabilities][docs/CAPABILITIES.md], [plugins][docs/PLUGINS.md], [bulk import][docs/BULK.md].
- Operations: [operations][docs/OPERATIONS.md], [hosting inside another framework][docs/OPERATIONS.md#hosting-urlcode-inside-another-framework] (`createEmbeddedHandler`), [install][docs/INSTALL.md], [deployment checks][docs/DEPLOYMENT-CHECKS.md], [readiness][docs/READINESS.md], [capacity][docs/CAPACITY.md], [resilience][docs/RESILIENCE.md], [observability][docs/OBSERVABILITY.md], [Vercel][docs/VERCEL.md], [AWS][docs/AWS.md], [Cloudflare][docs/CLOUDFLARE.md], [static hosting][docs/STATIC.md], [production readiness][docs/RELEASE-OPERATIONS.md#production-readiness], [roadmap][ROADMAP.md].

<!-- urlcode-current-version:start -->
[docs/TOOLING.md#local-agent-bootstrap]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/TOOLING.md#local-agent-bootstrap
[docs/TOOLING.md#registering-the-server]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/TOOLING.md#registering-the-server
[docs/TOOLING.md#optional-hosted-ai-mcp]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/TOOLING.md#optional-hosted-ai-mcp
[docs/AI-AUTHORING.md#hosted-assisted-authoring-opt-in]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/AI-AUTHORING.md#hosted-assisted-authoring-opt-in
[recipes/spa-shell/README.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/recipes/spa-shell/README.md
[docs/PROJECT-DIRECTION.md#design-principle-declarative-first]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/PROJECT-DIRECTION.md#design-principle-declarative-first
[docs/policies/security.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/policies/security.md
[docs/yaml/assets.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/yaml/assets.md
[docs/policies/cache.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/policies/cache.md
[docs/HTTP.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/HTTP.md
[docs/HTTP.md#named-schemas]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/HTTP.md#named-schemas
[docs/POLICIES.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/POLICIES.md
[docs/SITE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/SITE.md
[packages/auth/README.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/packages/auth/README.md
[docs/EXTENSIONS.md#protecting-a-route-the-auth-short-form]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#protecting-a-route-the-auth-short-form
[proofs/private-requests/README.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/proofs/private-requests/README.md
[docs/EXTENSIONS.md#request-bound-capabilities]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#request-bound-capabilities
[docs/STORE.md#audited-writes]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#audited-writes
[proofs/native-storage/README.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/proofs/native-storage/README.md
[docs/STORE.md#record-schema]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#record-schema
[docs/STORE.md#per-record-ownership]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#per-record-ownership
[docs/STORE.md#conditional-transitions-and-result-aware-retries]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#conditional-transitions-and-result-aware-retries
[docs/STORE.md#membership-gates-and-cross-owner-reads]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#membership-gates-and-cross-owner-reads
[docs/STORE.md#non-overlapping-intervals]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#non-overlapping-intervals
[docs/STORE.md#declared-transfers]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#declared-transfers
[docs/STORE.md#edit-and-delete-states]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#edit-and-delete-states
[docs/STORE.md#a-directory-by-a-unique-handle]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#a-directory-by-a-unique-handle
[docs/STORE.md#one-serving-process-per-database]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#one-serving-process-per-database
[proofs/private-requests/client/main.js]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/proofs/private-requests/client/main.js
[docs/ROUTING.md#a-site-root-frontend-beside-api-extension-mounts]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/ROUTING.md#a-site-root-frontend-beside-api-extension-mounts
[docs/READINESS.md#authenticated-routes-auth-true]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/READINESS.md#authenticated-routes-auth-true
[docs/FUNCTION-SECURITY.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/FUNCTION-SECURITY.md
[docs/AI-AUTHORING.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/AI-AUTHORING.md
[docs/YAML-GUIDE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/YAML-GUIDE.md
[docs/YAML-REFERENCE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/YAML-REFERENCE.md
[docs/SPECIFICATION.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/SPECIFICATION.md
[docs/RECIPES.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/RECIPES.md
[docs/ROUTING.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/ROUTING.md
[docs/MIDDLEWARE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/MIDDLEWARE.md
[docs/ASSETS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/ASSETS.md
[docs/CONDITIONS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/CONDITIONS.md
[docs/EGRESS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EGRESS.md
[docs/PRERENDER.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/PRERENDER.md
[docs/ORGANIZATION.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/ORGANIZATION.md
[docs/EXTENSION-REFERENCE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSION-REFERENCE.md
[docs/EXTENSIONS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md
[docs/EXTENSIONS.md#add-ons-extensions-and-artifacts]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#add-ons-extensions-and-artifacts
[docs/EXTENSIONS.md#the-installed-file-record]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#the-installed-file-record
[docs/EXTENSIONS.md#upgrading-an-independent-package]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#upgrading-an-independent-package
[docs/EXTENSIONS.md#independent-artifact-packages]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#independent-artifact-packages
[docs/EXTENSIONS.md#the-release-wide-agent-catalog]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#the-release-wide-agent-catalog
[docs/EXTENSIONS.md#generic-add-on-authoring-rules]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#generic-add-on-authoring-rules
[docs/FRAMEWORK.md#the-composition-contract]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/FRAMEWORK.md#the-composition-contract
[docs/VERSION-ALIGNMENT.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/VERSION-ALIGNMENT.md
[docs/EXTENSIONS.md#external-extensions-and-ai-tooling]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#external-extensions-and-ai-tooling
[docs/EXTENSIONS.md#native-independent-integration-or-bundled-default]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#native-independent-integration-or-bundled-default
[packages/auth/]: https://github.com/jimhoyd-com/urlcode/tree/v0.6.6/packages/auth
[packages/store/]: https://github.com/jimhoyd-com/urlcode/tree/v0.6.6/packages/store
[packages/mcp/]: https://github.com/jimhoyd-com/urlcode/tree/v0.6.6/packages/mcp
[docs/EXTENSIONS.md#request-context-route-env-and-request-id]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#request-context-route-env-and-request-id
[docs/EXTENSIONS.md#site-origins-and-same-origin-checks]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#site-origins-and-same-origin-checks
[docs/TOOLING.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/TOOLING.md
[docs/TYPESCRIPT.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/TYPESCRIPT.md
[docs/CAPABILITIES.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/CAPABILITIES.md
[docs/PLUGINS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/PLUGINS.md
[docs/BULK.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/BULK.md
[docs/OPERATIONS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/OPERATIONS.md
[docs/OPERATIONS.md#hosting-urlcode-inside-another-framework]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/OPERATIONS.md#hosting-urlcode-inside-another-framework
[docs/INSTALL.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/INSTALL.md
[docs/DEPLOYMENT-CHECKS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/DEPLOYMENT-CHECKS.md
[docs/READINESS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/READINESS.md
[docs/CAPACITY.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/CAPACITY.md
[docs/RESILIENCE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/RESILIENCE.md
[docs/OBSERVABILITY.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/OBSERVABILITY.md
[docs/VERCEL.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/VERCEL.md
[docs/AWS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/AWS.md
[docs/CLOUDFLARE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/CLOUDFLARE.md
[docs/STATIC.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STATIC.md
[docs/RELEASE-OPERATIONS.md#production-readiness]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/RELEASE-OPERATIONS.md#production-readiness
[ROADMAP.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/ROADMAP.md
[docs/EXTENSIONS.md#the-local-review-loop]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#the-local-review-loop
[docs/EXTENSIONS.md#hermetic-runs-and-test-seeds]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#hermetic-runs-and-test-seeds
<!-- urlcode-current-version:end -->