From 854c23651efa4d367aca19969b71169e680a5863 Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Mon, 19 Oct 2026 14:33:46 +0530 Subject: [PATCH] remove vet from docs hub and all files --- .drone.yml | 1 - Dockerfile | 4 +- _index/index.html | 7 - config.yml | 19 - standards/lib/sitemap.xml.gz | Bin 127 -> 127 bytes standards/mcp/modules/wiki_mcp_setup.json | 2 +- standards/src/mkdocs.wiki.yml | 5 +- standards/src/wiki/05_mcp_setup.md | 33 +- standards/src/wiki/06_ui_api_reference.md | 115 -- standards/wiki/05_mcp_setup/index.html | 105 +- standards/wiki/search/search_index.json | 2 +- standards/wiki/sitemap.xml.gz | Bin 127 -> 127 bytes vet/lib/.nojekyll | 1 - vet/lib/assets/hierarchy.js | 1 - vet/lib/assets/highlight.css | 92 - vet/lib/assets/icons.js | 18 - vet/lib/assets/icons.svg | 1 - vet/lib/assets/main.js | 60 - vet/lib/assets/navigation.js | 1 - vet/lib/assets/search.js | 1 - vet/lib/assets/style.css | 1611 ----------------- vet/lib/functions/src_Footer.default.html | 3 - vet/lib/functions/src_Header.default.html | 5 - vet/lib/functions/src_Home.default.html | 5 - .../src_shared-theme_AppTheme.default.html | 11 - ...d-theme_themeConfig.getSemanticColors.html | 9 - ...theme_themePrimitives.getDesignTokens.html | 8 - vet/lib/index.html | 1 - ...ared-theme_themeConfig.SemanticColors.html | 17 - .../interfaces/src_vite-env.ImportMeta.html | 12 - .../src_vite-env.ImportMetaEnv.html | 8 - vet/lib/modules/src_Footer.html | 6 - vet/lib/modules/src_Header.html | 6 - vet/lib/modules/src_Home.html | 13 - vet/lib/modules/src_main.html | 6 - vet/lib/modules/src_openapi-config.html | 5 - .../modules/src_shared-theme_AppTheme.html | 9 - ...ared-theme_customizations_dataDisplay.html | 4 - ..._shared-theme_customizations_feedback.html | 4 - ...rc_shared-theme_customizations_inputs.html | 5 - ...hared-theme_customizations_navigation.html | 5 - ..._shared-theme_customizations_surfaces.html | 4 - .../modules/src_shared-theme_themeConfig.html | 5 - .../src_shared-theme_themePrimitives.html | 6 - vet/lib/modules/src_vite-env.html | 1 - .../src_shared-theme_AppTheme.ColorMode.html | 2 - ...d-theme_themeConfig.SemanticColorMode.html | 2 - .../src_openapi-config.specConfiguration.html | 8 - ...hared-theme_AppTheme.ColorModeContext.html | 2 - ...dataDisplay.dataDisplayCustomizations.html | 2 - ...tions_feedback.feedbackCustomizations.html | 2 - ...mizations_inputs.inputsCustomizations.html | 2 - ...s_navigation.navigationCustomizations.html | 2 - ...tions_surfaces.surfacesCustomizations.html | 2 - ...rc_shared-theme_themePrimitives.brand.html | 2 - ...ed-theme_themePrimitives.colorSchemes.html | 2 - ...src_shared-theme_themePrimitives.gray.html | 2 - ...rc_shared-theme_themePrimitives.green.html | 2 - ...c_shared-theme_themePrimitives.orange.html | 2 - .../src_shared-theme_themePrimitives.red.html | 2 - ..._shared-theme_themePrimitives.shadows.html | 2 - ...rc_shared-theme_themePrimitives.shape.html | 2 - ...ared-theme_themePrimitives.typography.html | 2 - vet/mcp/index.json | 6 - vet/mcp/modules/Footer.json | 16 - vet/mcp/modules/Header.json | 16 - vet/mcp/modules/Home.json | 16 - vet/mcp/modules/main.json | 8 - vet/mcp/modules/openapi-config.json | 16 - vet/mcp/modules/shared-theme.AppTheme.json | 30 - ...ared-theme.customizations.dataDisplay.json | 16 - .../shared-theme.customizations.feedback.json | 16 - .../shared-theme.customizations.inputs.json | 16 - ...hared-theme.customizations.navigation.json | 16 - .../shared-theme.customizations.surfaces.json | 16 - vet/mcp/modules/shared-theme.themeConfig.json | 53 - .../modules/shared-theme.themePrimitives.json | 79 - vet/mcp/modules/src_vite-env.json | 132 -- vet/mcp/nav.json | 58 - 79 files changed, 49 insertions(+), 2740 deletions(-) delete mode 100644 standards/src/wiki/06_ui_api_reference.md delete mode 100644 vet/lib/.nojekyll delete mode 100644 vet/lib/assets/hierarchy.js delete mode 100644 vet/lib/assets/highlight.css delete mode 100644 vet/lib/assets/icons.js delete mode 100644 vet/lib/assets/icons.svg delete mode 100644 vet/lib/assets/main.js delete mode 100644 vet/lib/assets/navigation.js delete mode 100644 vet/lib/assets/search.js delete mode 100644 vet/lib/assets/style.css delete mode 100644 vet/lib/functions/src_Footer.default.html delete mode 100644 vet/lib/functions/src_Header.default.html delete mode 100644 vet/lib/functions/src_Home.default.html delete mode 100644 vet/lib/functions/src_shared-theme_AppTheme.default.html delete mode 100644 vet/lib/functions/src_shared-theme_themeConfig.getSemanticColors.html delete mode 100644 vet/lib/functions/src_shared-theme_themePrimitives.getDesignTokens.html delete mode 100644 vet/lib/index.html delete mode 100644 vet/lib/interfaces/src_shared-theme_themeConfig.SemanticColors.html delete mode 100644 vet/lib/interfaces/src_vite-env.ImportMeta.html delete mode 100644 vet/lib/interfaces/src_vite-env.ImportMetaEnv.html delete mode 100644 vet/lib/modules/src_Footer.html delete mode 100644 vet/lib/modules/src_Header.html delete mode 100644 vet/lib/modules/src_Home.html delete mode 100644 vet/lib/modules/src_main.html delete mode 100644 vet/lib/modules/src_openapi-config.html delete mode 100644 vet/lib/modules/src_shared-theme_AppTheme.html delete mode 100644 vet/lib/modules/src_shared-theme_customizations_dataDisplay.html delete mode 100644 vet/lib/modules/src_shared-theme_customizations_feedback.html delete mode 100644 vet/lib/modules/src_shared-theme_customizations_inputs.html delete mode 100644 vet/lib/modules/src_shared-theme_customizations_navigation.html delete mode 100644 vet/lib/modules/src_shared-theme_customizations_surfaces.html delete mode 100644 vet/lib/modules/src_shared-theme_themeConfig.html delete mode 100644 vet/lib/modules/src_shared-theme_themePrimitives.html delete mode 100644 vet/lib/modules/src_vite-env.html delete mode 100644 vet/lib/types/src_shared-theme_AppTheme.ColorMode.html delete mode 100644 vet/lib/types/src_shared-theme_themeConfig.SemanticColorMode.html delete mode 100644 vet/lib/variables/src_openapi-config.specConfiguration.html delete mode 100644 vet/lib/variables/src_shared-theme_AppTheme.ColorModeContext.html delete mode 100644 vet/lib/variables/src_shared-theme_customizations_dataDisplay.dataDisplayCustomizations.html delete mode 100644 vet/lib/variables/src_shared-theme_customizations_feedback.feedbackCustomizations.html delete mode 100644 vet/lib/variables/src_shared-theme_customizations_inputs.inputsCustomizations.html delete mode 100644 vet/lib/variables/src_shared-theme_customizations_navigation.navigationCustomizations.html delete mode 100644 vet/lib/variables/src_shared-theme_customizations_surfaces.surfacesCustomizations.html delete mode 100644 vet/lib/variables/src_shared-theme_themePrimitives.brand.html delete mode 100644 vet/lib/variables/src_shared-theme_themePrimitives.colorSchemes.html delete mode 100644 vet/lib/variables/src_shared-theme_themePrimitives.gray.html delete mode 100644 vet/lib/variables/src_shared-theme_themePrimitives.green.html delete mode 100644 vet/lib/variables/src_shared-theme_themePrimitives.orange.html delete mode 100644 vet/lib/variables/src_shared-theme_themePrimitives.red.html delete mode 100644 vet/lib/variables/src_shared-theme_themePrimitives.shadows.html delete mode 100644 vet/lib/variables/src_shared-theme_themePrimitives.shape.html delete mode 100644 vet/lib/variables/src_shared-theme_themePrimitives.typography.html delete mode 100644 vet/mcp/index.json delete mode 100644 vet/mcp/modules/Footer.json delete mode 100644 vet/mcp/modules/Header.json delete mode 100644 vet/mcp/modules/Home.json delete mode 100644 vet/mcp/modules/main.json delete mode 100644 vet/mcp/modules/openapi-config.json delete mode 100644 vet/mcp/modules/shared-theme.AppTheme.json delete mode 100644 vet/mcp/modules/shared-theme.customizations.dataDisplay.json delete mode 100644 vet/mcp/modules/shared-theme.customizations.feedback.json delete mode 100644 vet/mcp/modules/shared-theme.customizations.inputs.json delete mode 100644 vet/mcp/modules/shared-theme.customizations.navigation.json delete mode 100644 vet/mcp/modules/shared-theme.customizations.surfaces.json delete mode 100644 vet/mcp/modules/shared-theme.themeConfig.json delete mode 100644 vet/mcp/modules/shared-theme.themePrimitives.json delete mode 100644 vet/mcp/modules/src_vite-env.json delete mode 100644 vet/mcp/nav.json diff --git a/.drone.yml b/.drone.yml index d7376f7..7819a5f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -79,7 +79,6 @@ steps: -p 8010:8010 \ -p 8011:8011 \ -p 8012:8012 \ - -p 8013:8013 \ --restart always \ aetos/docs:latest diff --git a/Dockerfile b/Dockerfile index 6bfc10f..133155a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,7 +36,6 @@ COPY doc-forge /usr/share/nginx/html/doc-forge COPY doc-weaver /usr/share/nginx/html/doc-weaver COPY react-auth /usr/share/nginx/html/react-auth COPY react-openapi /usr/share/nginx/html/react-openapi -COPY vet /usr/share/nginx/html/vet COPY dagpipe /usr/share/nginx/html/dagpipe COPY mail-intake /usr/share/nginx/html/mail-intake COPY omniread /usr/share/nginx/html/omniread @@ -54,7 +53,6 @@ COPY doc-forge/mcp /app/doc-forge/mcp COPY doc-weaver/mcp /app/doc-weaver/mcp COPY react-auth/mcp /app/react-auth/mcp COPY react-openapi/mcp /app/react-openapi/mcp -COPY vet/mcp /app/vet/mcp COPY dagpipe/mcp /app/dagpipe/mcp COPY mail-intake/mcp /app/mail-intake/mcp COPY omniread/mcp /app/omniread/mcp @@ -63,6 +61,6 @@ COPY hexa/mcp /app/hexa/mcp COPY mongo-ops/mcp /app/mongo-ops/mcp COPY standards/mcp /app/standards/mcp -EXPOSE 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 9000 +EXPOSE 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 9000 CMD ["python", "main.py"] \ No newline at end of file diff --git a/_index/index.html b/_index/index.html index b3e207b..59635af 100644 --- a/_index/index.html +++ b/_index/index.html @@ -106,13 +106,6 @@ view lib -
-

Vet

-

Veterinary clinic demo front-end built on react-openapi — shows the spec-driven admin, theming and routing in one runnable app.

-
- view lib -
-
diff --git a/config.yml b/config.yml index 17bc68b..4850717 100644 --- a/config.yml +++ b/config.yml @@ -151,25 +151,6 @@ repos: lib: site api: site - - name: vet - source: ../react/vet - title: Vet - description: Veterinary clinic demo front-end built on react-openapi — shows the spec-driven admin, theming and routing in one runnable app. - section: apps - docs: - lib: site - mcp: { bundle: docs/mcp, server: vet, port: 8013 } - - - name: vet-app - source: ../react/vet/server - title: Vet Server - description: Veterinary clinic backend API (OpenAPI-first) with JWT auth and dual in-memory/Mongo persistence. - section: apps - docs: - wiki: site - lib: site - api: site - static: - kind: wiki repo: standards diff --git a/standards/lib/sitemap.xml.gz b/standards/lib/sitemap.xml.gz index 43b6693ea67df02dd9f5455bc82850339c9ac646..7140084f63cdc7ac094f9b92e2c304376b6ad4a8 100644 GIT binary patch delta 13 Ucmb=gXP58h;An`wI+48s03EOdf&c&j delta 13 Ucmb=gXP58h;9%gnGLgLk02vnpumAu6 diff --git a/standards/mcp/modules/wiki_mcp_setup.json b/standards/mcp/modules/wiki_mcp_setup.json index 5aa3f40..75b46f7 100644 --- a/standards/mcp/modules/wiki_mcp_setup.json +++ b/standards/mcp/modules/wiki_mcp_setup.json @@ -2,7 +2,7 @@ "module": "wiki_mcp_setup", "content": { "path": "wiki_mcp_setup", - "docstring": "# 🔌 MCP Setup\n\nEvery repository ships its documentation as a **Model Context Protocol (MCP)**\nserver, and the `standards` registry server ties them together. The `docs`\nportal runs each one as a FastMCP **streamable-http** app bound to\n`0.0.0.0:`, exposing the endpoint at `/mcp` (see `docs/main.py` and\n`docs/config.yml`).\n\nConnect your agent to the **`standards`** server first: it answers\n`find_library`, `list_repos`, and the `start_app` prompt, so the agent reaches\nfor an internal library instead of reimplementing one (see the\n[Library Registry](../lib/13_library_registry/)).\n\n---\n\n## ▶️ Run the servers locally\n\nFrom the `docs` checkout:\n\n```bash\n.venv\\Scripts\\python.exe main.py # every server\n.venv\\Scripts\\python.exe main.py --servers standards # just the registry\n```\n\n`:8000` is the health endpoint (`GET /healthz`), **not** an MCP server.\n\n---\n\n## 🧭 Servers\n\n| Slug | MCP server | Port | localhost | mcp.aetoskia.com |\n|------|------------|------|-----------|------------------|\n| `standards` | `standards` | 8009 | `http://localhost:8009/mcp` | `https://mcp.aetoskia.com/standards/mcp` |\n| `doc-forge` | `docforge` | 8001 | `http://localhost:8001/mcp` | `https://mcp.aetoskia.com/doc-forge/mcp` |\n| `mail-intake` | `mail_intake` | 8002 | `http://localhost:8002/mcp` | `https://mcp.aetoskia.com/mail-intake/mcp` |\n| `omniread` | `omniread` | 8003 | `http://localhost:8003/mcp` | `https://mcp.aetoskia.com/omniread/mcp` |\n| `openapi-first` | `openapi_first` | 8004 | `http://localhost:8004/mcp` | `https://mcp.aetoskia.com/openapi-first/mcp` |\n| `py-jwt` | `jwtlib` | 8005 | `http://localhost:8005/mcp` | `https://mcp.aetoskia.com/py-jwt/mcp` |\n| `dagpipe` | `dagpipe` | 8006 | `http://localhost:8006/mcp` | `https://mcp.aetoskia.com/dagpipe/mcp` |\n| `mongo-ops` | `mongo_ops` | 8007 | `http://localhost:8007/mcp` | `https://mcp.aetoskia.com/mongo-ops/mcp` |\n| `hexa` | `hexa` | 8008 | `http://localhost:8008/mcp` | `https://mcp.aetoskia.com/hexa/mcp` |\n| `doc-weaver` | `doc-weaver` | 8010 | `http://localhost:8010/mcp` | `https://mcp.aetoskia.com/doc-weaver/mcp` |\n| `react-auth` | `react-auth` | 8011 | `http://localhost:8011/mcp` | `https://mcp.aetoskia.com/react-auth/mcp` |\n| `react-openapi` | `react-openapi` | 8012 | `http://localhost:8012/mcp` | `https://mcp.aetoskia.com/react-openapi/mcp` |\n| `vet` | `vet` | 8013 | `http://localhost:8013/mcp` | `https://mcp.aetoskia.com/vet/mcp` |\n\nThe hosted endpoints are served over HTTPS at `https://mcp.aetoskia.com//mcp`.\nThe tabs below are linked (`content.tabs.link`): switching one switches all of\nthem. Every snippet registers **all thirteen** servers, so a single paste is\nenough.\n\n---\n\n## 🤖 Claude Code\n\nProject-scoped `.mcp.json` at the repo root. The `type` field is required — an\nentry with a `url` but no `type` is read as a stdio server and skipped.\n\n=== \"localhost\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"type\": \"http\", \"url\": \"http://localhost:8009/mcp\" },\n \"doc-forge\": { \"type\": \"http\", \"url\": \"http://localhost:8001/mcp\" },\n \"mail-intake\": { \"type\": \"http\", \"url\": \"http://localhost:8002/mcp\" },\n \"omniread\": { \"type\": \"http\", \"url\": \"http://localhost:8003/mcp\" },\n \"openapi-first\": { \"type\": \"http\", \"url\": \"http://localhost:8004/mcp\" },\n \"py-jwt\": { \"type\": \"http\", \"url\": \"http://localhost:8005/mcp\" },\n \"dagpipe\": { \"type\": \"http\", \"url\": \"http://localhost:8006/mcp\" },\n \"mongo-ops\": { \"type\": \"http\", \"url\": \"http://localhost:8007/mcp\" },\n \"hexa\": { \"type\": \"http\", \"url\": \"http://localhost:8008/mcp\" },\n \"doc-weaver\": { \"type\": \"http\", \"url\": \"http://localhost:8010/mcp\" },\n \"react-auth\": { \"type\": \"http\", \"url\": \"http://localhost:8011/mcp\" },\n \"react-openapi\": { \"type\": \"http\", \"url\": \"http://localhost:8012/mcp\" },\n \"vet\": { \"type\": \"http\", \"url\": \"http://localhost:8013/mcp\" }\n }\n }\n ```\n\n=== \"mcp.aetoskia.com\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/standards/mcp\" },\n \"doc-forge\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n \"mail-intake\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n \"omniread\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n \"openapi-first\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n \"py-jwt\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n \"dagpipe\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n \"mongo-ops\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n \"hexa\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n \"doc-weaver\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n \"react-auth\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n \"react-openapi\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\" },\n \"vet\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/vet/mcp\" }\n }\n }\n ```\n\nOr add them with the CLI:\n`claude mcp add --transport http standards http://localhost:8009/mcp`.\n\n---\n\n## 🤖 Codex\n\n`~/.codex/config.toml` (or a project-scoped `.codex/config.toml`).\n\n=== \"localhost\"\n\n ```toml\n [mcp_servers.standards]\n url = \"http://localhost:8009/mcp\"\n\n [mcp_servers.doc-forge]\n url = \"http://localhost:8001/mcp\"\n\n [mcp_servers.mail-intake]\n url = \"http://localhost:8002/mcp\"\n\n [mcp_servers.omniread]\n url = \"http://localhost:8003/mcp\"\n\n [mcp_servers.openapi-first]\n url = \"http://localhost:8004/mcp\"\n\n [mcp_servers.py-jwt]\n url = \"http://localhost:8005/mcp\"\n\n [mcp_servers.dagpipe]\n url = \"http://localhost:8006/mcp\"\n\n [mcp_servers.mongo-ops]\n url = \"http://localhost:8007/mcp\"\n\n [mcp_servers.hexa]\n url = \"http://localhost:8008/mcp\"\n\n [mcp_servers.doc-weaver]\n url = \"http://localhost:8010/mcp\"\n\n [mcp_servers.react-auth]\n url = \"http://localhost:8011/mcp\"\n\n [mcp_servers.react-openapi]\n url = \"http://localhost:8012/mcp\"\n\n [mcp_servers.vet]\n url = \"http://localhost:8013/mcp\"\n ```\n\n=== \"mcp.aetoskia.com\"\n\n ```toml\n [mcp_servers.standards]\n url = \"https://mcp.aetoskia.com/standards/mcp\"\n\n [mcp_servers.doc-forge]\n url = \"https://mcp.aetoskia.com/doc-forge/mcp\"\n\n [mcp_servers.mail-intake]\n url = \"https://mcp.aetoskia.com/mail-intake/mcp\"\n\n [mcp_servers.omniread]\n url = \"https://mcp.aetoskia.com/omniread/mcp\"\n\n [mcp_servers.openapi-first]\n url = \"https://mcp.aetoskia.com/openapi-first/mcp\"\n\n [mcp_servers.py-jwt]\n url = \"https://mcp.aetoskia.com/py-jwt/mcp\"\n\n [mcp_servers.dagpipe]\n url = \"https://mcp.aetoskia.com/dagpipe/mcp\"\n\n [mcp_servers.mongo-ops]\n url = \"https://mcp.aetoskia.com/mongo-ops/mcp\"\n\n [mcp_servers.hexa]\n url = \"https://mcp.aetoskia.com/hexa/mcp\"\n\n [mcp_servers.doc-weaver]\n url = \"https://mcp.aetoskia.com/doc-weaver/mcp\"\n\n [mcp_servers.react-auth]\n url = \"https://mcp.aetoskia.com/react-auth/mcp\"\n\n [mcp_servers.react-openapi]\n url = \"https://mcp.aetoskia.com/react-openapi/mcp\"\n\n [mcp_servers.vet]\n url = \"https://mcp.aetoskia.com/vet/mcp\"\n ```\n\nOr add them with the CLI:\n`codex mcp add standards --url http://localhost:8009/mcp`.\n\n---\n\n## 🤖 Antigravity\n\n`~/.gemini/antigravity/mcp_config.json` (IDE) or\n`~/.gemini/config/mcp_config.json` (CLI). Antigravity uses **`serverUrl`**, not\n`url`, for HTTP endpoints.\n\n=== \"localhost\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"serverUrl\": \"http://localhost:8009/mcp\" },\n \"doc-forge\": { \"serverUrl\": \"http://localhost:8001/mcp\" },\n \"mail-intake\": { \"serverUrl\": \"http://localhost:8002/mcp\" },\n \"omniread\": { \"serverUrl\": \"http://localhost:8003/mcp\" },\n \"openapi-first\": { \"serverUrl\": \"http://localhost:8004/mcp\" },\n \"py-jwt\": { \"serverUrl\": \"http://localhost:8005/mcp\" },\n \"dagpipe\": { \"serverUrl\": \"http://localhost:8006/mcp\" },\n \"mongo-ops\": { \"serverUrl\": \"http://localhost:8007/mcp\" },\n \"hexa\": { \"serverUrl\": \"http://localhost:8008/mcp\" },\n \"doc-weaver\": { \"serverUrl\": \"http://localhost:8010/mcp\" },\n \"react-auth\": { \"serverUrl\": \"http://localhost:8011/mcp\" },\n \"react-openapi\": { \"serverUrl\": \"http://localhost:8012/mcp\" },\n \"vet\": { \"serverUrl\": \"http://localhost:8013/mcp\" }\n }\n }\n ```\n\n=== \"mcp.aetoskia.com\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"serverUrl\": \"https://mcp.aetoskia.com/standards/mcp\" },\n \"doc-forge\": { \"serverUrl\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n \"mail-intake\": { \"serverUrl\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n \"omniread\": { \"serverUrl\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n \"openapi-first\": { \"serverUrl\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n \"py-jwt\": { \"serverUrl\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n \"dagpipe\": { \"serverUrl\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n \"mongo-ops\": { \"serverUrl\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n \"hexa\": { \"serverUrl\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n \"doc-weaver\": { \"serverUrl\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n \"react-auth\": { \"serverUrl\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n \"react-openapi\": { \"serverUrl\": \"https://mcp.aetoskia.com/react-openapi/mcp\" },\n \"vet\": { \"serverUrl\": \"https://mcp.aetoskia.com/vet/mcp\" }\n }\n }\n ```\n\n---\n\n## 🤖 OpenCode\n\n`opencode.json` (project) or `~/.config/opencode/opencode.json` (global).\n\n=== \"localhost\"\n\n ```json\n {\n \"$schema\": \"https://opencode.ai/config.json\",\n \"mcp\": {\n \"standards\": { \"type\": \"remote\", \"url\": \"http://localhost:8009/mcp\", \"enabled\": true },\n \"doc-forge\": { \"type\": \"remote\", \"url\": \"http://localhost:8001/mcp\", \"enabled\": true },\n \"mail-intake\": { \"type\": \"remote\", \"url\": \"http://localhost:8002/mcp\", \"enabled\": true },\n \"omniread\": { \"type\": \"remote\", \"url\": \"http://localhost:8003/mcp\", \"enabled\": true },\n \"openapi-first\": { \"type\": \"remote\", \"url\": \"http://localhost:8004/mcp\", \"enabled\": true },\n \"py-jwt\": { \"type\": \"remote\", \"url\": \"http://localhost:8005/mcp\", \"enabled\": true },\n \"dagpipe\": { \"type\": \"remote\", \"url\": \"http://localhost:8006/mcp\", \"enabled\": true },\n \"mongo-ops\": { \"type\": \"remote\", \"url\": \"http://localhost:8007/mcp\", \"enabled\": true },\n \"hexa\": { \"type\": \"remote\", \"url\": \"http://localhost:8008/mcp\", \"enabled\": true },\n \"doc-weaver\": { \"type\": \"remote\", \"url\": \"http://localhost:8010/mcp\", \"enabled\": true },\n \"react-auth\": { \"type\": \"remote\", \"url\": \"http://localhost:8011/mcp\", \"enabled\": true },\n \"react-openapi\": { \"type\": \"remote\", \"url\": \"http://localhost:8012/mcp\", \"enabled\": true },\n \"vet\": { \"type\": \"remote\", \"url\": \"http://localhost:8013/mcp\", \"enabled\": true }\n }\n }\n ```\n\n=== \"mcp.aetoskia.com\"\n\n ```json\n {\n \"$schema\": \"https://opencode.ai/config.json\",\n \"mcp\": {\n \"standards\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/standards/mcp\", \"enabled\": true },\n \"doc-forge\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\", \"enabled\": true },\n \"mail-intake\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\", \"enabled\": true },\n \"omniread\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/omniread/mcp\", \"enabled\": true },\n \"openapi-first\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\", \"enabled\": true },\n \"py-jwt\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\", \"enabled\": true },\n \"dagpipe\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\", \"enabled\": true },\n \"mongo-ops\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\", \"enabled\": true },\n \"hexa\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/hexa/mcp\", \"enabled\": true },\n \"doc-weaver\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\", \"enabled\": true },\n \"react-auth\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\", \"enabled\": true },\n \"react-openapi\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\", \"enabled\": true },\n \"vet\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/vet/mcp\", \"enabled\": true }\n }\n }\n ```\n\nOr add them with the CLI:\n`opencode mcp add standards --url http://localhost:8009/mcp --global`.\n\n---\n\n## 🤖 PyCharm (Junie / AI Assistant)\n\n`~/.junie/mcp/mcp.json` (user scope) or `.junie/mcp/mcp.json` (project scope).\nThe same config is reachable from **Settings | Tools | MCP Server → Manual\nClient Configuration → Copy HTTP Stream Config**.\n\n=== \"localhost\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"url\": \"http://localhost:8009/mcp\" },\n \"doc-forge\": { \"url\": \"http://localhost:8001/mcp\" },\n \"mail-intake\": { \"url\": \"http://localhost:8002/mcp\" },\n \"omniread\": { \"url\": \"http://localhost:8003/mcp\" },\n \"openapi-first\": { \"url\": \"http://localhost:8004/mcp\" },\n \"py-jwt\": { \"url\": \"http://localhost:8005/mcp\" },\n \"dagpipe\": { \"url\": \"http://localhost:8006/mcp\" },\n \"mongo-ops\": { \"url\": \"http://localhost:8007/mcp\" },\n \"hexa\": { \"url\": \"http://localhost:8008/mcp\" },\n \"doc-weaver\": { \"url\": \"http://localhost:8010/mcp\" },\n \"react-auth\": { \"url\": \"http://localhost:8011/mcp\" },\n \"react-openapi\": { \"url\": \"http://localhost:8012/mcp\" },\n \"vet\": { \"url\": \"http://localhost:8013/mcp\" }\n }\n }\n ```\n\n=== \"mcp.aetoskia.com\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"url\": \"https://mcp.aetoskia.com/standards/mcp\" },\n \"doc-forge\": { \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n \"mail-intake\": { \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n \"omniread\": { \"url\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n \"openapi-first\": { \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n \"py-jwt\": { \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n \"dagpipe\": { \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n \"mongo-ops\": { \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n \"hexa\": { \"url\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n \"doc-weaver\": { \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n \"react-auth\": { \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n \"react-openapi\": { \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\" },\n \"vet\": { \"url\": \"https://mcp.aetoskia.com/vet/mcp\" }\n }\n }\n ```\n\n---\n\n## ✅ Verify\n\n- Health check: `curl http://localhost:8000/healthz` → `ok`.\n- Claude Code: `claude mcp list` → each server … `✓ Connected`.\n- Codex: `codex mcp list` → each server … `http`.\n- OpenCode: `opencode mcp list` → each server … `connected`.\n- In-session: run `/mcp` to list the connected servers and their tools.\n\n---\n\n## 📚 Reference\n\n- [Library Registry](../lib/13_library_registry/) — the catalog each server\n mirrors, and where `find_library` resolves\n- [Start an App](03_start_an_app.md) — connect `standards`, then invoke\n `start_app`\n- [App Components](02_components.md) — the component model\n\n---\n\n## Related\n\n- [Start an App](03_start_an_app.md) · [Testing & Quality](04_development/01_testing.md) · [Library Registry](../lib/13_library_registry/)\n", + "docstring": "# 🔌 MCP Setup\n\nEvery repository ships its documentation as a **Model Context Protocol (MCP)**\nserver, and the `standards` registry server ties them together. The `docs`\nportal runs each one as a FastMCP **streamable-http** app bound to\n`0.0.0.0:`, exposing the endpoint at `/mcp` (see `docs/main.py` and\n`docs/config.yml`).\n\nConnect your agent to the **`standards`** server first: it answers\n`find_library`, `list_repos`, and the `start_app` prompt, so the agent reaches\nfor an internal library instead of reimplementing one (see the\n[Library Registry](../lib/13_library_registry/)).\n\n---\n\n## ▶️ Run the servers locally\n\nFrom the `docs` checkout:\n\n```bash\n.venv\\Scripts\\python.exe main.py # every server\n.venv\\Scripts\\python.exe main.py --servers standards # just the registry\n```\n\n`:8000` is the health endpoint (`GET /healthz`), **not** an MCP server.\n\n---\n\n## 🧭 Servers\n\n| Slug | MCP server | Port | localhost | mcp.aetoskia.com |\n|------|------------|------|-----------|------------------|\n| `standards` | `standards` | 8009 | `http://localhost:8009/mcp` | `https://mcp.aetoskia.com/standards/mcp` |\n| `doc-forge` | `docforge` | 8001 | `http://localhost:8001/mcp` | `https://mcp.aetoskia.com/doc-forge/mcp` |\n| `mail-intake` | `mail_intake` | 8002 | `http://localhost:8002/mcp` | `https://mcp.aetoskia.com/mail-intake/mcp` |\n| `omniread` | `omniread` | 8003 | `http://localhost:8003/mcp` | `https://mcp.aetoskia.com/omniread/mcp` |\n| `openapi-first` | `openapi_first` | 8004 | `http://localhost:8004/mcp` | `https://mcp.aetoskia.com/openapi-first/mcp` |\n| `py-jwt` | `jwtlib` | 8005 | `http://localhost:8005/mcp` | `https://mcp.aetoskia.com/py-jwt/mcp` |\n| `dagpipe` | `dagpipe` | 8006 | `http://localhost:8006/mcp` | `https://mcp.aetoskia.com/dagpipe/mcp` |\n| `mongo-ops` | `mongo_ops` | 8007 | `http://localhost:8007/mcp` | `https://mcp.aetoskia.com/mongo-ops/mcp` |\n| `hexa` | `hexa` | 8008 | `http://localhost:8008/mcp` | `https://mcp.aetoskia.com/hexa/mcp` |\n| `doc-weaver` | `doc-weaver` | 8010 | `http://localhost:8010/mcp` | `https://mcp.aetoskia.com/doc-weaver/mcp` |\n| `react-auth` | `react-auth` | 8011 | `http://localhost:8011/mcp` | `https://mcp.aetoskia.com/react-auth/mcp` |\n| `react-openapi` | `react-openapi` | 8012 | `http://localhost:8012/mcp` | `https://mcp.aetoskia.com/react-openapi/mcp` |\n\nThe hosted endpoints are served over HTTPS at `https://mcp.aetoskia.com//mcp`.\nThe tabs below are linked (`content.tabs.link`): switching one switches all of\nthem. Every snippet registers **all twelve** servers, so a single paste is\nenough.\n\n---\n\n## 🤖 Claude Code\n\nProject-scoped `.mcp.json` at the repo root. The `type` field is required — an\nentry with a `url` but no `type` is read as a stdio server and skipped.\n\n=== \"localhost\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"type\": \"http\", \"url\": \"http://localhost:8009/mcp\" },\n \"doc-forge\": { \"type\": \"http\", \"url\": \"http://localhost:8001/mcp\" },\n \"mail-intake\": { \"type\": \"http\", \"url\": \"http://localhost:8002/mcp\" },\n \"omniread\": { \"type\": \"http\", \"url\": \"http://localhost:8003/mcp\" },\n \"openapi-first\": { \"type\": \"http\", \"url\": \"http://localhost:8004/mcp\" },\n \"py-jwt\": { \"type\": \"http\", \"url\": \"http://localhost:8005/mcp\" },\n \"dagpipe\": { \"type\": \"http\", \"url\": \"http://localhost:8006/mcp\" },\n \"mongo-ops\": { \"type\": \"http\", \"url\": \"http://localhost:8007/mcp\" },\n \"hexa\": { \"type\": \"http\", \"url\": \"http://localhost:8008/mcp\" },\n \"doc-weaver\": { \"type\": \"http\", \"url\": \"http://localhost:8010/mcp\" },\n \"react-auth\": { \"type\": \"http\", \"url\": \"http://localhost:8011/mcp\" },\n \"react-openapi\": { \"type\": \"http\", \"url\": \"http://localhost:8012/mcp\" }\n }\n }\n ```\n\n=== \"mcp.aetoskia.com\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/standards/mcp\" },\n \"doc-forge\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n \"mail-intake\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n \"omniread\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n \"openapi-first\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n \"py-jwt\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n \"dagpipe\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n \"mongo-ops\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n \"hexa\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n \"doc-weaver\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n \"react-auth\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n \"react-openapi\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\" }\n }\n }\n ```\n\nOr add them with the CLI:\n`claude mcp add --transport http standards http://localhost:8009/mcp`.\n\n---\n\n## 🤖 Codex\n\n`~/.codex/config.toml` (or a project-scoped `.codex/config.toml`).\n\n=== \"localhost\"\n\n ```toml\n [mcp_servers.standards]\n url = \"http://localhost:8009/mcp\"\n\n [mcp_servers.doc-forge]\n url = \"http://localhost:8001/mcp\"\n\n [mcp_servers.mail-intake]\n url = \"http://localhost:8002/mcp\"\n\n [mcp_servers.omniread]\n url = \"http://localhost:8003/mcp\"\n\n [mcp_servers.openapi-first]\n url = \"http://localhost:8004/mcp\"\n\n [mcp_servers.py-jwt]\n url = \"http://localhost:8005/mcp\"\n\n [mcp_servers.dagpipe]\n url = \"http://localhost:8006/mcp\"\n\n [mcp_servers.mongo-ops]\n url = \"http://localhost:8007/mcp\"\n\n [mcp_servers.hexa]\n url = \"http://localhost:8008/mcp\"\n\n [mcp_servers.doc-weaver]\n url = \"http://localhost:8010/mcp\"\n\n [mcp_servers.react-auth]\n url = \"http://localhost:8011/mcp\"\n\n [mcp_servers.react-openapi]\n url = \"http://localhost:8012/mcp\"\n ```\n\n=== \"mcp.aetoskia.com\"\n\n ```toml\n [mcp_servers.standards]\n url = \"https://mcp.aetoskia.com/standards/mcp\"\n\n [mcp_servers.doc-forge]\n url = \"https://mcp.aetoskia.com/doc-forge/mcp\"\n\n [mcp_servers.mail-intake]\n url = \"https://mcp.aetoskia.com/mail-intake/mcp\"\n\n [mcp_servers.omniread]\n url = \"https://mcp.aetoskia.com/omniread/mcp\"\n\n [mcp_servers.openapi-first]\n url = \"https://mcp.aetoskia.com/openapi-first/mcp\"\n\n [mcp_servers.py-jwt]\n url = \"https://mcp.aetoskia.com/py-jwt/mcp\"\n\n [mcp_servers.dagpipe]\n url = \"https://mcp.aetoskia.com/dagpipe/mcp\"\n\n [mcp_servers.mongo-ops]\n url = \"https://mcp.aetoskia.com/mongo-ops/mcp\"\n\n [mcp_servers.hexa]\n url = \"https://mcp.aetoskia.com/hexa/mcp\"\n\n [mcp_servers.doc-weaver]\n url = \"https://mcp.aetoskia.com/doc-weaver/mcp\"\n\n [mcp_servers.react-auth]\n url = \"https://mcp.aetoskia.com/react-auth/mcp\"\n\n [mcp_servers.react-openapi]\n url = \"https://mcp.aetoskia.com/react-openapi/mcp\"\n ```\n\nOr add them with the CLI:\n`codex mcp add standards --url http://localhost:8009/mcp`.\n\n---\n\n## 🤖 Antigravity\n\n`~/.gemini/antigravity/mcp_config.json` (IDE) or\n`~/.gemini/config/mcp_config.json` (CLI). Antigravity uses **`serverUrl`**, not\n`url`, for HTTP endpoints.\n\n=== \"localhost\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"serverUrl\": \"http://localhost:8009/mcp\" },\n \"doc-forge\": { \"serverUrl\": \"http://localhost:8001/mcp\" },\n \"mail-intake\": { \"serverUrl\": \"http://localhost:8002/mcp\" },\n \"omniread\": { \"serverUrl\": \"http://localhost:8003/mcp\" },\n \"openapi-first\": { \"serverUrl\": \"http://localhost:8004/mcp\" },\n \"py-jwt\": { \"serverUrl\": \"http://localhost:8005/mcp\" },\n \"dagpipe\": { \"serverUrl\": \"http://localhost:8006/mcp\" },\n \"mongo-ops\": { \"serverUrl\": \"http://localhost:8007/mcp\" },\n \"hexa\": { \"serverUrl\": \"http://localhost:8008/mcp\" },\n \"doc-weaver\": { \"serverUrl\": \"http://localhost:8010/mcp\" },\n \"react-auth\": { \"serverUrl\": \"http://localhost:8011/mcp\" },\n \"react-openapi\": { \"serverUrl\": \"http://localhost:8012/mcp\" }\n }\n }\n ```\n\n=== \"mcp.aetoskia.com\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"serverUrl\": \"https://mcp.aetoskia.com/standards/mcp\" },\n \"doc-forge\": { \"serverUrl\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n \"mail-intake\": { \"serverUrl\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n \"omniread\": { \"serverUrl\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n \"openapi-first\": { \"serverUrl\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n \"py-jwt\": { \"serverUrl\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n \"dagpipe\": { \"serverUrl\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n \"mongo-ops\": { \"serverUrl\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n \"hexa\": { \"serverUrl\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n \"doc-weaver\": { \"serverUrl\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n \"react-auth\": { \"serverUrl\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n \"react-openapi\": { \"serverUrl\": \"https://mcp.aetoskia.com/react-openapi/mcp\" }\n }\n }\n ```\n\n---\n\n## 🤖 OpenCode\n\n`opencode.json` (project) or `~/.config/opencode/opencode.json` (global).\n\n=== \"localhost\"\n\n ```json\n {\n \"$schema\": \"https://opencode.ai/config.json\",\n \"mcp\": {\n \"standards\": { \"type\": \"remote\", \"url\": \"http://localhost:8009/mcp\", \"enabled\": true },\n \"doc-forge\": { \"type\": \"remote\", \"url\": \"http://localhost:8001/mcp\", \"enabled\": true },\n \"mail-intake\": { \"type\": \"remote\", \"url\": \"http://localhost:8002/mcp\", \"enabled\": true },\n \"omniread\": { \"type\": \"remote\", \"url\": \"http://localhost:8003/mcp\", \"enabled\": true },\n \"openapi-first\": { \"type\": \"remote\", \"url\": \"http://localhost:8004/mcp\", \"enabled\": true },\n \"py-jwt\": { \"type\": \"remote\", \"url\": \"http://localhost:8005/mcp\", \"enabled\": true },\n \"dagpipe\": { \"type\": \"remote\", \"url\": \"http://localhost:8006/mcp\", \"enabled\": true },\n \"mongo-ops\": { \"type\": \"remote\", \"url\": \"http://localhost:8007/mcp\", \"enabled\": true },\n \"hexa\": { \"type\": \"remote\", \"url\": \"http://localhost:8008/mcp\", \"enabled\": true },\n \"doc-weaver\": { \"type\": \"remote\", \"url\": \"http://localhost:8010/mcp\", \"enabled\": true },\n \"react-auth\": { \"type\": \"remote\", \"url\": \"http://localhost:8011/mcp\", \"enabled\": true },\n \"react-openapi\": { \"type\": \"remote\", \"url\": \"http://localhost:8012/mcp\", \"enabled\": true }\n }\n }\n ```\n\n=== \"mcp.aetoskia.com\"\n\n ```json\n {\n \"$schema\": \"https://opencode.ai/config.json\",\n \"mcp\": {\n \"standards\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/standards/mcp\", \"enabled\": true },\n \"doc-forge\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\", \"enabled\": true },\n \"mail-intake\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\", \"enabled\": true },\n \"omniread\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/omniread/mcp\", \"enabled\": true },\n \"openapi-first\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\", \"enabled\": true },\n \"py-jwt\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\", \"enabled\": true },\n \"dagpipe\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\", \"enabled\": true },\n \"mongo-ops\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\", \"enabled\": true },\n \"hexa\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/hexa/mcp\", \"enabled\": true },\n \"doc-weaver\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\", \"enabled\": true },\n \"react-auth\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\", \"enabled\": true },\n \"react-openapi\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\", \"enabled\": true }\n }\n }\n ```\n\nOr add them with the CLI:\n`opencode mcp add standards --url http://localhost:8009/mcp --global`.\n\n---\n\n## 🤖 PyCharm (Junie / AI Assistant)\n\n`~/.junie/mcp/mcp.json` (user scope) or `.junie/mcp/mcp.json` (project scope).\nThe same config is reachable from **Settings | Tools | MCP Server → Manual\nClient Configuration → Copy HTTP Stream Config**.\n\n=== \"localhost\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"url\": \"http://localhost:8009/mcp\" },\n \"doc-forge\": { \"url\": \"http://localhost:8001/mcp\" },\n \"mail-intake\": { \"url\": \"http://localhost:8002/mcp\" },\n \"omniread\": { \"url\": \"http://localhost:8003/mcp\" },\n \"openapi-first\": { \"url\": \"http://localhost:8004/mcp\" },\n \"py-jwt\": { \"url\": \"http://localhost:8005/mcp\" },\n \"dagpipe\": { \"url\": \"http://localhost:8006/mcp\" },\n \"mongo-ops\": { \"url\": \"http://localhost:8007/mcp\" },\n \"hexa\": { \"url\": \"http://localhost:8008/mcp\" },\n \"doc-weaver\": { \"url\": \"http://localhost:8010/mcp\" },\n \"react-auth\": { \"url\": \"http://localhost:8011/mcp\" },\n \"react-openapi\": { \"url\": \"http://localhost:8012/mcp\" }\n }\n }\n ```\n\n=== \"mcp.aetoskia.com\"\n\n ```json\n {\n \"mcpServers\": {\n \"standards\": { \"url\": \"https://mcp.aetoskia.com/standards/mcp\" },\n \"doc-forge\": { \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n \"mail-intake\": { \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n \"omniread\": { \"url\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n \"openapi-first\": { \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n \"py-jwt\": { \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n \"dagpipe\": { \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n \"mongo-ops\": { \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n \"hexa\": { \"url\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n \"doc-weaver\": { \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n \"react-auth\": { \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n \"react-openapi\": { \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\" }\n }\n }\n ```\n\n---\n\n## ✅ Verify\n\n- Health check: `curl http://localhost:8000/healthz` → `ok`.\n- Claude Code: `claude mcp list` → each server … `✓ Connected`.\n- Codex: `codex mcp list` → each server … `http`.\n- OpenCode: `opencode mcp list` → each server … `connected`.\n- In-session: run `/mcp` to list the connected servers and their tools.\n\n---\n\n## 📚 Reference\n\n- [Library Registry](../lib/13_library_registry/) — the catalog each server\n mirrors, and where `find_library` resolves\n- [Start an App](03_start_an_app.md) — connect `standards`, then invoke\n `start_app`\n- [App Components](02_components.md) — the component model\n\n---\n\n## Related\n\n- [Start an App](03_start_an_app.md) · [Testing & Quality](04_development/01_testing.md) · [Library Registry](../lib/13_library_registry/)\n", "objects": {} } } \ No newline at end of file diff --git a/standards/src/mkdocs.wiki.yml b/standards/src/mkdocs.wiki.yml index 5b15b51..39a6e77 100644 --- a/standards/src/mkdocs.wiki.yml +++ b/standards/src/mkdocs.wiki.yml @@ -69,9 +69,8 @@ nav: - Home: index.md - Overview: 01_overview.md - App Components: 02_components.md - - Start an App: 03_start_an_app.md - - UI + API Reference: 06_ui_api_reference.md - - MCP: + - Start an App: 03_start_an_app.md + - MCP: - Setup: 05_mcp_setup.md - Testing & Quality: 04_development/01_testing.md - Releasing & Versioning: 04_development/02_releasing.md \ No newline at end of file diff --git a/standards/src/wiki/05_mcp_setup.md b/standards/src/wiki/05_mcp_setup.md index acb3294..4e50a0c 100644 --- a/standards/src/wiki/05_mcp_setup.md +++ b/standards/src/wiki/05_mcp_setup.md @@ -42,11 +42,10 @@ From the `docs` checkout: | `doc-weaver` | `doc-weaver` | 8010 | `http://localhost:8010/mcp` | `https://mcp.aetoskia.com/doc-weaver/mcp` | | `react-auth` | `react-auth` | 8011 | `http://localhost:8011/mcp` | `https://mcp.aetoskia.com/react-auth/mcp` | | `react-openapi` | `react-openapi` | 8012 | `http://localhost:8012/mcp` | `https://mcp.aetoskia.com/react-openapi/mcp` | -| `vet` | `vet` | 8013 | `http://localhost:8013/mcp` | `https://mcp.aetoskia.com/vet/mcp` | The hosted endpoints are served over HTTPS at `https://mcp.aetoskia.com//mcp`. The tabs below are linked (`content.tabs.link`): switching one switches all of -them. Every snippet registers **all thirteen** servers, so a single paste is +them. Every snippet registers **all twelve** servers, so a single paste is enough. --- @@ -72,8 +71,7 @@ entry with a `url` but no `type` is read as a stdio server and skipped. "hexa": { "type": "http", "url": "http://localhost:8008/mcp" }, "doc-weaver": { "type": "http", "url": "http://localhost:8010/mcp" }, "react-auth": { "type": "http", "url": "http://localhost:8011/mcp" }, - "react-openapi": { "type": "http", "url": "http://localhost:8012/mcp" }, - "vet": { "type": "http", "url": "http://localhost:8013/mcp" } + "react-openapi": { "type": "http", "url": "http://localhost:8012/mcp" } } } ``` @@ -94,8 +92,7 @@ entry with a `url` but no `type` is read as a stdio server and skipped. "hexa": { "type": "http", "url": "https://mcp.aetoskia.com/hexa/mcp" }, "doc-weaver": { "type": "http", "url": "https://mcp.aetoskia.com/doc-weaver/mcp" }, "react-auth": { "type": "http", "url": "https://mcp.aetoskia.com/react-auth/mcp" }, - "react-openapi": { "type": "http", "url": "https://mcp.aetoskia.com/react-openapi/mcp" }, - "vet": { "type": "http", "url": "https://mcp.aetoskia.com/vet/mcp" } + "react-openapi": { "type": "http", "url": "https://mcp.aetoskia.com/react-openapi/mcp" } } } ``` @@ -147,9 +144,6 @@ Or add them with the CLI: [mcp_servers.react-openapi] url = "http://localhost:8012/mcp" - - [mcp_servers.vet] - url = "http://localhost:8013/mcp" ``` === "mcp.aetoskia.com" @@ -190,9 +184,6 @@ Or add them with the CLI: [mcp_servers.react-openapi] url = "https://mcp.aetoskia.com/react-openapi/mcp" - - [mcp_servers.vet] - url = "https://mcp.aetoskia.com/vet/mcp" ``` Or add them with the CLI: @@ -222,8 +213,7 @@ Or add them with the CLI: "hexa": { "serverUrl": "http://localhost:8008/mcp" }, "doc-weaver": { "serverUrl": "http://localhost:8010/mcp" }, "react-auth": { "serverUrl": "http://localhost:8011/mcp" }, - "react-openapi": { "serverUrl": "http://localhost:8012/mcp" }, - "vet": { "serverUrl": "http://localhost:8013/mcp" } + "react-openapi": { "serverUrl": "http://localhost:8012/mcp" } } } ``` @@ -244,8 +234,7 @@ Or add them with the CLI: "hexa": { "serverUrl": "https://mcp.aetoskia.com/hexa/mcp" }, "doc-weaver": { "serverUrl": "https://mcp.aetoskia.com/doc-weaver/mcp" }, "react-auth": { "serverUrl": "https://mcp.aetoskia.com/react-auth/mcp" }, - "react-openapi": { "serverUrl": "https://mcp.aetoskia.com/react-openapi/mcp" }, - "vet": { "serverUrl": "https://mcp.aetoskia.com/vet/mcp" } + "react-openapi": { "serverUrl": "https://mcp.aetoskia.com/react-openapi/mcp" } } } ``` @@ -273,8 +262,7 @@ Or add them with the CLI: "hexa": { "type": "remote", "url": "http://localhost:8008/mcp", "enabled": true }, "doc-weaver": { "type": "remote", "url": "http://localhost:8010/mcp", "enabled": true }, "react-auth": { "type": "remote", "url": "http://localhost:8011/mcp", "enabled": true }, - "react-openapi": { "type": "remote", "url": "http://localhost:8012/mcp", "enabled": true }, - "vet": { "type": "remote", "url": "http://localhost:8013/mcp", "enabled": true } + "react-openapi": { "type": "remote", "url": "http://localhost:8012/mcp", "enabled": true } } } ``` @@ -296,8 +284,7 @@ Or add them with the CLI: "hexa": { "type": "remote", "url": "https://mcp.aetoskia.com/hexa/mcp", "enabled": true }, "doc-weaver": { "type": "remote", "url": "https://mcp.aetoskia.com/doc-weaver/mcp", "enabled": true }, "react-auth": { "type": "remote", "url": "https://mcp.aetoskia.com/react-auth/mcp", "enabled": true }, - "react-openapi": { "type": "remote", "url": "https://mcp.aetoskia.com/react-openapi/mcp", "enabled": true }, - "vet": { "type": "remote", "url": "https://mcp.aetoskia.com/vet/mcp", "enabled": true } + "react-openapi": { "type": "remote", "url": "https://mcp.aetoskia.com/react-openapi/mcp", "enabled": true } } } ``` @@ -329,8 +316,7 @@ Client Configuration → Copy HTTP Stream Config**. "hexa": { "url": "http://localhost:8008/mcp" }, "doc-weaver": { "url": "http://localhost:8010/mcp" }, "react-auth": { "url": "http://localhost:8011/mcp" }, - "react-openapi": { "url": "http://localhost:8012/mcp" }, - "vet": { "url": "http://localhost:8013/mcp" } + "react-openapi": { "url": "http://localhost:8012/mcp" } } } ``` @@ -351,8 +337,7 @@ Client Configuration → Copy HTTP Stream Config**. "hexa": { "url": "https://mcp.aetoskia.com/hexa/mcp" }, "doc-weaver": { "url": "https://mcp.aetoskia.com/doc-weaver/mcp" }, "react-auth": { "url": "https://mcp.aetoskia.com/react-auth/mcp" }, - "react-openapi": { "url": "https://mcp.aetoskia.com/react-openapi/mcp" }, - "vet": { "url": "https://mcp.aetoskia.com/vet/mcp" } + "react-openapi": { "url": "https://mcp.aetoskia.com/react-openapi/mcp" } } } ``` diff --git a/standards/src/wiki/06_ui_api_reference.md b/standards/src/wiki/06_ui_api_reference.md deleted file mode 100644 index f87afce..0000000 --- a/standards/src/wiki/06_ui_api_reference.md +++ /dev/null @@ -1,115 +0,0 @@ -# UI + API Reference - -The vet application is the reference implementation of the **UI + API -pattern**: a spec-first backend (`react/vet/server`) paired with a -react-openapi frontend (`react/vet`) that renders itself directly from the -backend's OpenAPI document. Everything about the pairing — auth, persistence, -uploads, SSE — is driven from `openapi.yaml`. - ---- - -## Architecture - -``` -react/vet/ # frontend (vite, react-openapi, react-auth) - src/ - openapi-config.ts # reads VITE_API_BASE_URL + VITE_AUTH_BASE_URL - .env # VITE_API_BASE_URL=http://localhost:8020 - -react/vet/server/ # backend (OpenAPIFirstApp, port 8020) - openapi.yaml # single source of truth (24 operations) - domain/ # parents, vets, treatments, pets, appointments - infra/db/repos/ # IntIdMemoryRepository / IntIdMongoRepository - interfaces/ # one route module per resource + system (health) -``` - -The frontend's `specConfiguration` passes `specUrl` and `baseApiUrl` derived -from `VITE_API_BASE_URL`; `react-openapi` fetches `${base}/openapi.json` and -builds the admin UI from the `x-` extensions in the spec. - ---- - -## Auth (bearer JWT) - -`openapi.yaml` declares a single `bearerAuth` security scheme -(`type: http`, `bearerFormat: JWT`) with `x-server-url: "{AUTH_SERVER}"` and -`x-introspect-path: "/introspect"`. `openapi_first` resolves `{AUTH_SERVER}` -from the environment at app build time and generates a `Depends` that calls -the auth-server's `/introspect` endpoint per request. No hand-written auth -code exists in the backend. - -The frontend uses `react-auth`'s `AuthProvider` and `AuthPage` gate; the API -client attaches `Authorization: Bearer ` via -`specConfiguration.getToken = () => tokenStore.get()`. - ---- - -## Persistence (dual backend) - -`REPO_BACKEND` selects the repository flavor: - -| Value | Adapter | Notes | -| ------ | ---------------------------- | ------------------------------------------ | -| `memory` (default) | `IntIdMemoryRepository` | Process-local dict + counter; zero deps | -| `mongo` | `IntIdMongoRepository` | Motor via `MongoConnectionManager`; counter via `_counters` collection | - -Both adapters expose the same duck-type (`create`, `get_by_id`, `get_many`, -`update`, `patch`, `delete`) consumed by the hexa-wired -`CrudsServiceAdaptor` services, so domain code and route handlers are -backend-agnostic. **Integer ids** are used end-to-end (the wire contract -declares `type: integer` primary keys); this is a documented deviation from -mongo-ops' default `ObjectId` allocation. - ---- - -## Resource modelling - -Every resource follows the same slice: - -- `domain//models.py` — plain pydantic models (`extra: "ignore"`) -- `domain//ports/db.py` — `XDocument(X, BaseDocument)` + `create_x_repo()` -- `domain//ports/service.py` — `XCrudsService(CrudsServiceAdaptor)` + `get_x_service(repo)` -- `interfaces//routes.py` — handlers named after operationIds - -Foreign keys are embedded objects on the wire (e.g. `Appointment.pet` is a -full `Pet`). Create/update handlers accept either a bare id or an expanded -object and normalize through `expand_ref` / `expand_ref_list` before -persisting. Unresolvable references return `422`. - ---- - -## Non-CRUD surface - -- **File upload** — `POST /pets/{id}/photo` (multipart) writes to - `UPLOADS_DIR` and stores the path on the pet document. -- **SSE** — `GET /pets/{id}/actions` returns `text/event-stream` with random - species-scoped behaviors (see `infra/adapters/actions_stream.py`). -- **Health** — `GET /health` is public (`security: []`) and used by the - Docker healthcheck. - ---- - -## Running - -```bash -cd react/vet/server -python -m venv .venv && .venv\Scripts\pip install -e .[dev] -AUTH_SERVER=https://auth.aetoskia.com REPO_BACKEND=memory .venv\Scripts\uvicorn main:app --port 8020 -``` - -The frontend (`react/vet`) reads `VITE_API_BASE_URL` from `.env` and proxies -nothing — CORS is open (`allow_origins=["*"]`) in `main.py`. - ---- - -## What the standards say - -The backend follows the [Start an App](03_start_an_app.md) blueprint -(composition root, hexa wiring, `CrudsServiceAdaptor` services, spec-first -routing via `openapi_first`). The deviations are intentional and documented: - -- **No worker/pipelines** — no background jobs for this app. -- **Integer-id repositories** — required by the wire contract; replaces the - ObjectId-based `mongo_ops.BaseRepository`. -- **Both persistence flavors** — memory (default, zero-dep) and Mongo - (production) selected via `REPO_BACKEND`. diff --git a/standards/wiki/05_mcp_setup/index.html b/standards/wiki/05_mcp_setup/index.html index fc8cf97..8bb236b 100644 --- a/standards/wiki/05_mcp_setup/index.html +++ b/standards/wiki/05_mcp_setup/index.html @@ -844,18 +844,11 @@ for an internal library instead of reimplementing one (see the http://localhost:8012/mcp https://mcp.aetoskia.com/react-openapi/mcp - -vet -vet -8013 -http://localhost:8013/mcp -https://mcp.aetoskia.com/vet/mcp -

The hosted endpoints are served over HTTPS at https://mcp.aetoskia.com/<slug>/mcp. The tabs below are linked (content.tabs.link): switching one switches all of -them. Every snippet registers all thirteen servers, so a single paste is +them. Every snippet registers all twelve servers, so a single paste is enough.


🤖 Claude Code

@@ -879,8 +872,7 @@ entry with a url but no type is read as a stdio server 13 14 15 -16 -17
{
+16
{
   "mcpServers": {
     "standards": { "type": "http", "url": "http://localhost:8009/mcp" },
     "doc-forge": { "type": "http", "url": "http://localhost:8001/mcp" },
@@ -893,10 +885,9 @@ entry with a url but no type is read as a stdio server
     "hexa": { "type": "http", "url": "http://localhost:8008/mcp" },
     "doc-weaver": { "type": "http", "url": "http://localhost:8010/mcp" },
     "react-auth": { "type": "http", "url": "http://localhost:8011/mcp" },
-    "react-openapi": { "type": "http", "url": "http://localhost:8012/mcp" },
-    "vet": { "type": "http", "url": "http://localhost:8013/mcp" }
-  }
-}
+    "react-openapi": { "type": "http", "url": "http://localhost:8012/mcp" }
+  }
+}
 
@@ -915,8 +906,7 @@ entry with a url but no type is read as a stdio server 13 14 15 -16 -17
{
+16
{
   "mcpServers": {
     "standards": { "type": "http", "url": "https://mcp.aetoskia.com/standards/mcp" },
     "doc-forge": { "type": "http", "url": "https://mcp.aetoskia.com/doc-forge/mcp" },
@@ -929,10 +919,9 @@ entry with a url but no type is read as a stdio server
     "hexa": { "type": "http", "url": "https://mcp.aetoskia.com/hexa/mcp" },
     "doc-weaver": { "type": "http", "url": "https://mcp.aetoskia.com/doc-weaver/mcp" },
     "react-auth": { "type": "http", "url": "https://mcp.aetoskia.com/react-auth/mcp" },
-    "react-openapi": { "type": "http", "url": "https://mcp.aetoskia.com/react-openapi/mcp" },
-    "vet": { "type": "http", "url": "https://mcp.aetoskia.com/vet/mcp" }
-  }
-}
+    "react-openapi": { "type": "http", "url": "https://mcp.aetoskia.com/react-openapi/mcp" }
+  }
+}
 
@@ -979,10 +968,7 @@ entry with a url but no type is read as a stdio server 32 33 34 -35 -36 -37 -38
[mcp_servers.standards]
+35
[mcp_servers.standards]
 url = "http://localhost:8009/mcp"
 
 [mcp_servers.doc-forge]
@@ -1017,9 +1003,6 @@ entry with a url but no type is read as a stdio server
 
 [mcp_servers.react-openapi]
 url = "http://localhost:8012/mcp"
-
-[mcp_servers.vet]
-url = "http://localhost:8013/mcp"
 
@@ -1057,10 +1040,7 @@ entry with a url but no type is read as a stdio server 32 33 34 -35 -36 -37 -38
[mcp_servers.standards]
+35
[mcp_servers.standards]
 url = "https://mcp.aetoskia.com/standards/mcp"
 
 [mcp_servers.doc-forge]
@@ -1095,9 +1075,6 @@ entry with a url but no type is read as a stdio server
 
 [mcp_servers.react-openapi]
 url = "https://mcp.aetoskia.com/react-openapi/mcp"
-
-[mcp_servers.vet]
-url = "https://mcp.aetoskia.com/vet/mcp"
 
@@ -1127,8 +1104,7 @@ entry with a url but no type is read as a stdio server 13 14 15 -16 -17
{
+16
{
   "mcpServers": {
     "standards": { "serverUrl": "http://localhost:8009/mcp" },
     "doc-forge": { "serverUrl": "http://localhost:8001/mcp" },
@@ -1141,10 +1117,9 @@ entry with a url but no type is read as a stdio server
     "hexa": { "serverUrl": "http://localhost:8008/mcp" },
     "doc-weaver": { "serverUrl": "http://localhost:8010/mcp" },
     "react-auth": { "serverUrl": "http://localhost:8011/mcp" },
-    "react-openapi": { "serverUrl": "http://localhost:8012/mcp" },
-    "vet": { "serverUrl": "http://localhost:8013/mcp" }
-  }
-}
+    "react-openapi": { "serverUrl": "http://localhost:8012/mcp" }
+  }
+}
 
@@ -1163,8 +1138,7 @@ entry with a url but no type is read as a stdio server 13 14 15 -16 -17
{
+16
{
   "mcpServers": {
     "standards": { "serverUrl": "https://mcp.aetoskia.com/standards/mcp" },
     "doc-forge": { "serverUrl": "https://mcp.aetoskia.com/doc-forge/mcp" },
@@ -1177,10 +1151,9 @@ entry with a url but no type is read as a stdio server
     "hexa": { "serverUrl": "https://mcp.aetoskia.com/hexa/mcp" },
     "doc-weaver": { "serverUrl": "https://mcp.aetoskia.com/doc-weaver/mcp" },
     "react-auth": { "serverUrl": "https://mcp.aetoskia.com/react-auth/mcp" },
-    "react-openapi": { "serverUrl": "https://mcp.aetoskia.com/react-openapi/mcp" },
-    "vet": { "serverUrl": "https://mcp.aetoskia.com/vet/mcp" }
-  }
-}
+    "react-openapi": { "serverUrl": "https://mcp.aetoskia.com/react-openapi/mcp" }
+  }
+}
 
@@ -1207,8 +1180,7 @@ entry with a url but no type is read as a stdio server 14 15 16 -17 -18
{
+17
{
   "$schema": "https://opencode.ai/config.json",
   "mcp": {
     "standards": { "type": "remote", "url": "http://localhost:8009/mcp", "enabled": true },
@@ -1222,10 +1194,9 @@ entry with a url but no type is read as a stdio server
     "hexa": { "type": "remote", "url": "http://localhost:8008/mcp", "enabled": true },
     "doc-weaver": { "type": "remote", "url": "http://localhost:8010/mcp", "enabled": true },
     "react-auth": { "type": "remote", "url": "http://localhost:8011/mcp", "enabled": true },
-    "react-openapi": { "type": "remote", "url": "http://localhost:8012/mcp", "enabled": true },
-    "vet": { "type": "remote", "url": "http://localhost:8013/mcp", "enabled": true }
-  }
-}
+    "react-openapi": { "type": "remote", "url": "http://localhost:8012/mcp", "enabled": true }
+  }
+}
 
@@ -1245,8 +1216,7 @@ entry with a url but no type is read as a stdio server 14 15 16 -17 -18
{
+17
{
   "$schema": "https://opencode.ai/config.json",
   "mcp": {
     "standards": { "type": "remote", "url": "https://mcp.aetoskia.com/standards/mcp", "enabled": true },
@@ -1260,10 +1230,9 @@ entry with a url but no type is read as a stdio server
     "hexa": { "type": "remote", "url": "https://mcp.aetoskia.com/hexa/mcp", "enabled": true },
     "doc-weaver": { "type": "remote", "url": "https://mcp.aetoskia.com/doc-weaver/mcp", "enabled": true },
     "react-auth": { "type": "remote", "url": "https://mcp.aetoskia.com/react-auth/mcp", "enabled": true },
-    "react-openapi": { "type": "remote", "url": "https://mcp.aetoskia.com/react-openapi/mcp", "enabled": true },
-    "vet": { "type": "remote", "url": "https://mcp.aetoskia.com/vet/mcp", "enabled": true }
-  }
-}
+    "react-openapi": { "type": "remote", "url": "https://mcp.aetoskia.com/react-openapi/mcp", "enabled": true }
+  }
+}
 
@@ -1293,8 +1262,7 @@ Client Configuration → Copy HTTP Stream Config.

13 14 15 -16 -17
{
+16
{
   "mcpServers": {
     "standards": { "url": "http://localhost:8009/mcp" },
     "doc-forge": { "url": "http://localhost:8001/mcp" },
@@ -1307,10 +1275,9 @@ Client Configuration → Copy HTTP Stream Config.

"hexa": { "url": "http://localhost:8008/mcp" }, "doc-weaver": { "url": "http://localhost:8010/mcp" }, "react-auth": { "url": "http://localhost:8011/mcp" }, - "react-openapi": { "url": "http://localhost:8012/mcp" }, - "vet": { "url": "http://localhost:8013/mcp" } - } -} + "react-openapi": { "url": "http://localhost:8012/mcp" } + } +}
@@ -1329,8 +1296,7 @@ Client Configuration → Copy HTTP Stream Config.

13 14 15 -16 -17
{
+16
{
   "mcpServers": {
     "standards": { "url": "https://mcp.aetoskia.com/standards/mcp" },
     "doc-forge": { "url": "https://mcp.aetoskia.com/doc-forge/mcp" },
@@ -1343,10 +1309,9 @@ Client Configuration → Copy HTTP Stream Config.

"hexa": { "url": "https://mcp.aetoskia.com/hexa/mcp" }, "doc-weaver": { "url": "https://mcp.aetoskia.com/doc-weaver/mcp" }, "react-auth": { "url": "https://mcp.aetoskia.com/react-auth/mcp" }, - "react-openapi": { "url": "https://mcp.aetoskia.com/react-openapi/mcp" }, - "vet": { "url": "https://mcp.aetoskia.com/vet/mcp" } - } -} + "react-openapi": { "url": "https://mcp.aetoskia.com/react-openapi/mcp" } + } +}
diff --git a/standards/wiki/search/search_index.json b/standards/wiki/search/search_index.json index 5c19e82..d24affe 100644 --- a/standards/wiki/search/search_index.json +++ b/standards/wiki/search/search_index.json @@ -1 +1 @@ -{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"\ud83e\udde9 Standards \u2014 the Aetos App Blueprint","text":"

One reusable architecture for every backend application in the Aetos ecosystem: a spec-first HTTP edge, a framework-free domain core, a pluggable infrastructure layer, and a single composition root.

Fill in two axes only and a new app is done: your resource model, and (if needed) your pipeline family. The blueprint itself never names a business domain \u2014 expenses, health metrics, inventory, and analytics are all the same shape underneath.

Doc model: this wiki is written for humans \u2014 how-to guides, the build recipe, and quality gates. The enforceable rules (layering, composition root, CRUD template, pipeline scaffold) and the library registry live in the reference pages, mirrored by the machine-readable standards MCP bundle. Query find_library before writing any infrastructure.

"},{"location":"#key-features","title":"\ud83d\ude80 Key Features","text":"
  • \ud83e\udded Spec-first routing \u2014 the OpenAPI document, not decorator routers, is the source of truth (operationId lookup)
  • \ud83c\udfd7\ufe0f One-way layering \u2014 interfaces \u2192 domain \u2192 infra, enforced
  • \ud83d\udd0c Single composition root \u2014 every dependency is wired in exactly one place
  • \ud83e\udde9 Generic, not app-specific \u2014 reusable rules versus two authoring axes
  • \ud83d\udcda Library-backed \u2014 DB, DI, pipelines, ingestion, auth, and docs come from internal libraries, never hand-written
  • \ud83d\udea6 Explicit state machines \u2014 durable job statuses, progress, and human-in-the-loop pauses
"},{"location":"#documentation-structure","title":"\ud83d\udcc1 Documentation Structure","text":"Section Description Overview Philosophy, the one-way dependency rule, architecture App Components The component model and how the pieces wire together Start an App The entry point: gather the two axes, then build Testing & Quality Test layout and acceptance gates

Reference (separate site, mirrors the MCP bundle): the enforceable rules \u2014 Build Recipe, Layering, Composition Root, Spec-First Routing, CRUD Template, Pipeline Scaffold, Worker & Progress, Human-in-the-Loop, Infra Adapters, Genericity Matrix, Library Registry.

"},{"location":"#related-resources","title":"\ud83d\udd17 Related Resources","text":"
  • MCP bundle \u2014 standards server on :8009: read docs://index, docs://nav, docs://modules/{module}; call find_library(capability)
  • Library registry \u2014 the catalog of internal libraries behind every app (libraries.json, served as registry://libraries)
  • Template \u2014 the runnable skeleton at standards/src/templates/app/
  • Start a build \u2014 invoke the start_app prompt on the standards server, or read the Start an App guide

\u00a9 Aetoskia Internal \u2014 standards

"},{"location":"01_overview/","title":"Overview","text":"

The blueprint is a hexagonal (ports & adapters) application with a spec-first web edge and a single composition root. It favors explicit wiring over implicit magic and existing internal libraries over hand-written infrastructure. Start here to build the mental model; the enforceable details live in the reference pages.

"},{"location":"01_overview/#architecture","title":"\ud83c\udfd7\ufe0f Architecture","text":"
flowchart LR\n    subgraph EDGE[\"interfaces/ \u2014 HTTP edge\"]\n        OAS[\"openapi.yaml<br/>operationId contract\"]\n        RT[\"<resource>/routes.py<br/>thin handlers\"]\n    end\n\n    subgraph CORE[\"domain/ \u2014 business core\"]\n        MD[\"models\"]\n        PT[\"ports (adapter binding seam)\"]\n        SV[\"services\"]\n    end\n\n    subgraph INFRA[\"infra/ \u2014 adapters\"]\n        RP[\"mongo repos (mongo-ops)\"]\n        AD[\"cache \u00b7 stores \u00b7 llm \u00b7 mail\"]\n        DB[(\"MongoDB\")]\n    end\n\n    CR[\"init.py<br/>composition root\"]\n\n    OAS --> RT\n    RT --> SV\n    SV --> PT\n    SV --> RP\n    PT -. depends on .- RP\n    CR --- RT\n    CR --- SV\n    CR --- RP\n    RP --> DB\n    AD --- CR

The rule holds at every edge: code in an outer ring may depend on a ring closer to the core, never the reverse. domain/ never imports a web framework; only its ports/ seam reaches into infra/ to bind adapters.

Legend \u2014 solid arrows are compile-time calls; dotted arrows are the port/adapter binding, performed by the composition root at startup.

"},{"location":"01_overview/#the-one-way-dependency-rule","title":"\ud83d\udd04 The one-way dependency rule","text":"Ring May import Never imports interfaces/ domain, framework glue (glue only) business logic, infra directly domain/ its own models + its ports/ seam (which binds infra/libraries) web frameworks, interfaces/ infra/ domain ports, drivers, libraries \u2014 init.py everything (the wiring point) \u2014"},{"location":"01_overview/#core-principles","title":"\ud83e\udded Core principles","text":"
  1. One-way dependencies. interfaces -> domain -> infra is allowed; the reverse is forbidden.
  2. Ports in the domain, adapters in infra. A service depends on a port; the port's factory binds the concrete adapter, and the composition root calls those factories.
  3. One composition root. Nothing constructs its own dependencies. All wiring lives in one module (init.py) exposed as a flat resource registry.
  4. Spec-first. The HTTP contract is declared in openapi.yaml; route handlers are looked up by operationId. There are no decorator routers.
  5. Reuse the libraries. Orchestration, DI, Mongo repositories, ingestion, auth, and docs come from internal libraries \u2014 see the Library Registry.
  6. Explicit state machines. Long-running work moves through explicit, durable statuses and can pause for human input.
"},{"location":"01_overview/#runtime-processes","title":"\u2699\ufe0f Runtime processes","text":"

A standard app may run as up to three processes that share the same composition root:

Process Entry point Responsibility API main.py serve HTTP; start/stop resources via lifespan Worker worker.py poll durable jobs, run pipelines, publish progress Scripts python -m scripts.<name> one-shot operator tasks"},{"location":"01_overview/#read-next","title":"\u27a1\ufe0f Read Next","text":"
  • 02 \u2013 App Components \u00b7 03 \u2013 Start an App
"},{"location":"02_components/","title":"App Components","text":"

What ships in every standard app, and how the pieces relate. This is the blueprint's component model \u2014 templates/app/ is a runnable instance of it.

"},{"location":"02_components/#component-model","title":"\ud83d\uddc2\ufe0f Component model","text":"

The blueprint has two orthogonal views: runtime flow (who calls whom) and composition-root wiring (who constructs whom). Keeping them separate makes the layering visible instead of hiding it behind a hub.

"},{"location":"02_components/#runtime-flow","title":"\ud83d\udd00 Runtime flow","text":"

Who calls whom at request and job time:

%%{init: {\"flowchart\": {\"nodeSpacing\": 50, \"rankSpacing\": 80}}}%%\nflowchart TB\n    subgraph REQ[\"Request path \u2014 API process\"]\n        direction LR\n        CL([\"Client<br/>operationId\"]) --> RT[\"interfaces/&lt;resource&gt;/routes.py\"]\n        RT --> SVC[\"&lt;resource&gt;_svc\"]\n        SVC --> REPO[\"&lt;resource&gt;_repo\"]\n    end\n\n    subgraph WRK[\"Background path \u2014 worker process\"]\n        direction LR\n        W[\"worker.py\"] --> JSVC[\"job_svc\"]\n        W --> PIPE[\"pipelines/&lt;family&gt;\"]\n        PIPE --> ISVC[\"item_svc\"]\n        JSVC --> JREPO[\"job_repo\"]\n        ISVC --> IREPO[\"item_repo\"]\n    end\n\n    subgraph INFRA[\"infra/ \u2014 adapters\"]\n        MONGO[(\"MongoDB / mongo_ops\")]\n    end\n\n    REPO --> MONGO\n    JREPO --> MONGO\n    IREPO --> MONGO

Legend \u2014 solid arrows are runtime calls. Nothing is self-constructed.

"},{"location":"02_components/#composition-root-wiring","title":"\ud83e\uddf5 Composition-root wiring","text":"

Who constructs what at startup:

%%{init: {\"flowchart\": {\"nodeSpacing\": 50, \"rankSpacing\": 80}}}%%\nflowchart TB\n    INIT[\"init.py \u2014 composition root\"]\n    SETUP[\"infra/db/setup.py\"]\n    FACT[\"domain/*/ports/*<br/>factory seams\"]\n    REPOS[\"repos<br/>infra/db/repos/mongo.py\"]\n    SVCES[\"services<br/>CrudsServiceAdaptor\"]\n    STATE[\"app.state.db_resources\"]\n    HEXA[\"hexa.build\"]\n    RT[\"routes.py\"]\n    WK[\"worker.py\"]\n\n    INIT --> SETUP\n    INIT --> FACT\n    FACT --> REPOS\n    FACT --> SVCES\n    REPOS --> SVCES\n    HEXA -.-> SVCES\n    INIT --> STATE\n    STATE --> RT\n    INIT --> WK

Legend \u2014 init.py is the only place that imports concrete adapters. The ports/ factory seams bind infra; the API reads resources from app.state.db_resources, the worker calls init() directly.

"},{"location":"02_components/#component-roles","title":"\ud83d\udce6 Component roles","text":""},{"location":"02_components/#1-interfaces-the-edge","title":"1. interfaces/ \u2014 the edge","text":"

Thin handlers bound to openapi.yaml operationIds. They parse the request, call a service, and shape the response. No business rules, no I/O.

  • interfaces/openapi.py re-exports every route module so the OpenAPI-first app can resolve handlers.
  • Routes may mount the cache decorator on read endpoints.
"},{"location":"02_components/#2-domain-the-core","title":"2. domain/ \u2014 the core","text":"

Models, ports, and services (use cases). No framework imports. The ports/ package is the one seam allowed to reach into infra/: each port module declares the document shape and a factory that binds the adapter.

  • <aggregate>/models.py \u2014 dataclasses, enums, document shapes.
  • <aggregate>/ports/db.py \u2014 document model + create_<aggregate>_repo().
  • <aggregate>/ports/service.py \u2014 service + get_<aggregate>_service(repo).
  • Services compose ports and enforce the business rules; the port factories bind the implementations, and the composition root calls them.
"},{"location":"02_components/#3-infra-the-adapters","title":"3. infra/ \u2014 the adapters","text":"

Concrete implementations of the domain ports plus cross-cutting infrastructure:

  • db/ \u2014 mongo-ops repositories and the connection lifecycle.
  • adapters/ \u2014 cache store, progress bus, storages, fetchers (library-backed).
  • Anything else the domain needs, implemented against its ports.
"},{"location":"02_components/#4-pipelines-data-driven-families-optional","title":"4. pipelines/ \u2014 data-driven families (optional)","text":"

Extraction and enrichment families, each a deterministic step chain (abc.py / impl.py / pipeline.yaml / resources/). Roots are registered in the pattern registry and driven either by a worker job or a CLI.

"},{"location":"02_components/#5-workerpy-the-job-worker-optional","title":"5. worker.py \u2014 the job worker (optional)","text":"

A separate process that polls durable job collections, runs pipeline roots, and publishes progress to the progress bus. It shares the same composition root as the API.

"},{"location":"02_components/#6-initpy-the-composition-root","title":"6. init.py \u2014 the composition root","text":"

The only place anything is constructed: leaf repositories \u2192 dependent repositories \u2192 services \u2192 adapters. Exposes get_svc overloads and starts / stops resources on the app lifespan.

"},{"location":"02_components/#how-the-request-flows","title":"\ud83d\udd17 How the request flows","text":"
sequenceDiagram\n    participant C as Client\n    participant R as route (interfaces)\n    participant S as service (port factory / adapter)\n    participant P as repo (infra)\n    participant DB as MongoDB\n\n    C->>R: POST /items (operationId)\n    R->>S: svc.create(payload)\n    S->>P: repo.insert(doc)\n    P->>DB: insert\n    DB-->>P: ack\n    P-->>S: doc\n    S-->>R: result\n    R-->>C: 200 JSON
"},{"location":"02_components/#related","title":"Related","text":"
  • 01 \u2013 Overview \u00b7 03 \u2013 Start an App \u00b7 04 \u2013 Testing & Quality
"},{"location":"03_start_an_app/","title":"\ud83d\ude80 Start an App","text":"

This is the entry point for building a new application from the blueprint. The goal is one deterministic pass: you supply only the two axes, and the agent does the rest by reading the standards MCP, importing Tier A libraries, and copying Tier B template components.

Doc model: this page is the human entry point. The deterministic, machine-facing checklist lives in the reference page Build Recipe, served as docs://modules/build_recipe.

"},{"location":"03_start_an_app/#what-the-agent-needs-from-you","title":"\ud83e\uddfe What the agent needs from you","text":"

Gather these before starting \u2014 the start_app MCP prompt asks for them:

  1. App name + one-line purpose.
  2. Axis 1 \u2014 resources. Each resource, its fields, and relationships. Paste openapi.yaml if you already have it.
  3. Axis 2 \u2014 pipelines. Only if an input needs a multi-step transformation: the families and their input formats (or \"none\").
  4. Auth needed now? Default no. Auth is deferred (py-jwt primitives only), and an authless app is just a spec with no security keys \u2014 see Spec-First Routing \u2192 Authless apps.
  5. Integrations. Mongo, ingestion formats, email, LLM provider.

If you can state axes 1 and 2, the rest is mechanical.

"},{"location":"03_start_an_app/#how-to-start","title":"\u25b6\ufe0f How to start","text":"

From an MCP client connected to the standards server:

  1. Invoke the intake prompt (or start_app with no arguments) to get the intake questions.
  2. Answer them, then invoke build (build(app_name=..., resources=..., pipelines=..., auth=...)), or use start_app to intake-and-build in one call.
  3. The prompt hands off to docs://modules/build_recipe; the agent scaffolds with get_app_template() and pulls exact files with get_app_component(kind, resource=..., family=...), authoring only the app-specific parts.
  4. To validate the standard without touching a real app, invoke trial (trial(app_name=..., build_path=...)) to build into a scratch directory, prove it builds, and report findings.

Manual alternative \u2014 copy the skeleton and follow the reference recipe:

cp -r <docs>/standards/src/templates/app apps/<your-app>\n
"},{"location":"03_start_an_app/#reference","title":"\ud83d\udcda Reference","text":"
  • Build Recipe \u2014 the deterministic checklist
  • Genericity Matrix \u2014 Tier A / B / C
  • Library Registry \u2014 the Tier A catalog
  • App Components \u2014 the component model
"},{"location":"03_start_an_app/#related","title":"Related","text":"
  • 01 \u2013 Overview \u00b7 02 \u2013 App Components \u00b7 04 \u2013 Testing & Quality
"},{"location":"05_mcp_setup/","title":"\ud83d\udd0c MCP Setup","text":"

Every repository ships its documentation as a Model Context Protocol (MCP) server, and the standards registry server ties them together. The docs portal runs each one as a FastMCP streamable-http app bound to 0.0.0.0:<port>, exposing the endpoint at /mcp (see docs/main.py and docs/config.yml).

Connect your agent to the standards server first: it answers find_library, list_repos, and the start_app prompt, so the agent reaches for an internal library instead of reimplementing one (see the Library Registry).

"},{"location":"05_mcp_setup/#run-the-servers-locally","title":"\u25b6\ufe0f Run the servers locally","text":"

From the docs checkout:

.venv\\Scripts\\python.exe main.py                      # every server\n.venv\\Scripts\\python.exe main.py --servers standards   # just the registry\n

:8000 is the health endpoint (GET /healthz), not an MCP server.

"},{"location":"05_mcp_setup/#servers","title":"\ud83e\udded Servers","text":"Slug MCP server Port localhost mcp.aetoskia.com standards standards 8009 http://localhost:8009/mcp https://mcp.aetoskia.com/standards/mcp doc-forge docforge 8001 http://localhost:8001/mcp https://mcp.aetoskia.com/doc-forge/mcp mail-intake mail_intake 8002 http://localhost:8002/mcp https://mcp.aetoskia.com/mail-intake/mcp omniread omniread 8003 http://localhost:8003/mcp https://mcp.aetoskia.com/omniread/mcp openapi-first openapi_first 8004 http://localhost:8004/mcp https://mcp.aetoskia.com/openapi-first/mcp py-jwt jwtlib 8005 http://localhost:8005/mcp https://mcp.aetoskia.com/py-jwt/mcp dagpipe dagpipe 8006 http://localhost:8006/mcp https://mcp.aetoskia.com/dagpipe/mcp mongo-ops mongo_ops 8007 http://localhost:8007/mcp https://mcp.aetoskia.com/mongo-ops/mcp hexa hexa 8008 http://localhost:8008/mcp https://mcp.aetoskia.com/hexa/mcp doc-weaver doc-weaver 8010 http://localhost:8010/mcp https://mcp.aetoskia.com/doc-weaver/mcp react-auth react-auth 8011 http://localhost:8011/mcp https://mcp.aetoskia.com/react-auth/mcp react-openapi react-openapi 8012 http://localhost:8012/mcp https://mcp.aetoskia.com/react-openapi/mcp vet vet 8013 http://localhost:8013/mcp https://mcp.aetoskia.com/vet/mcp

The hosted endpoints are served over HTTPS at https://mcp.aetoskia.com/<slug>/mcp. The tabs below are linked (content.tabs.link): switching one switches all of them. Every snippet registers all thirteen servers, so a single paste is enough.

"},{"location":"05_mcp_setup/#claude-code","title":"\ud83e\udd16 Claude Code","text":"

Project-scoped .mcp.json at the repo root. The type field is required \u2014 an entry with a url but no type is read as a stdio server and skipped.

localhostmcp.aetoskia.com
{\n  \"mcpServers\": {\n    \"standards\": { \"type\": \"http\", \"url\": \"http://localhost:8009/mcp\" },\n    \"doc-forge\": { \"type\": \"http\", \"url\": \"http://localhost:8001/mcp\" },\n    \"mail-intake\": { \"type\": \"http\", \"url\": \"http://localhost:8002/mcp\" },\n    \"omniread\": { \"type\": \"http\", \"url\": \"http://localhost:8003/mcp\" },\n    \"openapi-first\": { \"type\": \"http\", \"url\": \"http://localhost:8004/mcp\" },\n    \"py-jwt\": { \"type\": \"http\", \"url\": \"http://localhost:8005/mcp\" },\n    \"dagpipe\": { \"type\": \"http\", \"url\": \"http://localhost:8006/mcp\" },\n    \"mongo-ops\": { \"type\": \"http\", \"url\": \"http://localhost:8007/mcp\" },\n    \"hexa\": { \"type\": \"http\", \"url\": \"http://localhost:8008/mcp\" },\n    \"doc-weaver\": { \"type\": \"http\", \"url\": \"http://localhost:8010/mcp\" },\n    \"react-auth\": { \"type\": \"http\", \"url\": \"http://localhost:8011/mcp\" },\n    \"react-openapi\": { \"type\": \"http\", \"url\": \"http://localhost:8012/mcp\" },\n    \"vet\": { \"type\": \"http\", \"url\": \"http://localhost:8013/mcp\" }\n  }\n}\n
{\n  \"mcpServers\": {\n    \"standards\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/standards/mcp\" },\n    \"doc-forge\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n    \"mail-intake\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n    \"omniread\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n    \"openapi-first\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n    \"py-jwt\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n    \"dagpipe\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n    \"mongo-ops\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n    \"hexa\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n    \"doc-weaver\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n    \"react-auth\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n    \"react-openapi\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\" },\n    \"vet\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/vet/mcp\" }\n  }\n}\n

Or add them with the CLI: claude mcp add --transport http standards http://localhost:8009/mcp.

"},{"location":"05_mcp_setup/#codex","title":"\ud83e\udd16 Codex","text":"

~/.codex/config.toml (or a project-scoped .codex/config.toml).

localhostmcp.aetoskia.com
[mcp_servers.standards]\nurl = \"http://localhost:8009/mcp\"\n\n[mcp_servers.doc-forge]\nurl = \"http://localhost:8001/mcp\"\n\n[mcp_servers.mail-intake]\nurl = \"http://localhost:8002/mcp\"\n\n[mcp_servers.omniread]\nurl = \"http://localhost:8003/mcp\"\n\n[mcp_servers.openapi-first]\nurl = \"http://localhost:8004/mcp\"\n\n[mcp_servers.py-jwt]\nurl = \"http://localhost:8005/mcp\"\n\n[mcp_servers.dagpipe]\nurl = \"http://localhost:8006/mcp\"\n\n[mcp_servers.mongo-ops]\nurl = \"http://localhost:8007/mcp\"\n\n[mcp_servers.hexa]\nurl = \"http://localhost:8008/mcp\"\n\n[mcp_servers.doc-weaver]\nurl = \"http://localhost:8010/mcp\"\n\n[mcp_servers.react-auth]\nurl = \"http://localhost:8011/mcp\"\n\n[mcp_servers.react-openapi]\nurl = \"http://localhost:8012/mcp\"\n\n[mcp_servers.vet]\nurl = \"http://localhost:8013/mcp\"\n
[mcp_servers.standards]\nurl = \"https://mcp.aetoskia.com/standards/mcp\"\n\n[mcp_servers.doc-forge]\nurl = \"https://mcp.aetoskia.com/doc-forge/mcp\"\n\n[mcp_servers.mail-intake]\nurl = \"https://mcp.aetoskia.com/mail-intake/mcp\"\n\n[mcp_servers.omniread]\nurl = \"https://mcp.aetoskia.com/omniread/mcp\"\n\n[mcp_servers.openapi-first]\nurl = \"https://mcp.aetoskia.com/openapi-first/mcp\"\n\n[mcp_servers.py-jwt]\nurl = \"https://mcp.aetoskia.com/py-jwt/mcp\"\n\n[mcp_servers.dagpipe]\nurl = \"https://mcp.aetoskia.com/dagpipe/mcp\"\n\n[mcp_servers.mongo-ops]\nurl = \"https://mcp.aetoskia.com/mongo-ops/mcp\"\n\n[mcp_servers.hexa]\nurl = \"https://mcp.aetoskia.com/hexa/mcp\"\n\n[mcp_servers.doc-weaver]\nurl = \"https://mcp.aetoskia.com/doc-weaver/mcp\"\n\n[mcp_servers.react-auth]\nurl = \"https://mcp.aetoskia.com/react-auth/mcp\"\n\n[mcp_servers.react-openapi]\nurl = \"https://mcp.aetoskia.com/react-openapi/mcp\"\n\n[mcp_servers.vet]\nurl = \"https://mcp.aetoskia.com/vet/mcp\"\n

Or add them with the CLI: codex mcp add standards --url http://localhost:8009/mcp.

"},{"location":"05_mcp_setup/#antigravity","title":"\ud83e\udd16 Antigravity","text":"

~/.gemini/antigravity/mcp_config.json (IDE) or ~/.gemini/config/mcp_config.json (CLI). Antigravity uses serverUrl, not url, for HTTP endpoints.

localhostmcp.aetoskia.com
{\n  \"mcpServers\": {\n    \"standards\": { \"serverUrl\": \"http://localhost:8009/mcp\" },\n    \"doc-forge\": { \"serverUrl\": \"http://localhost:8001/mcp\" },\n    \"mail-intake\": { \"serverUrl\": \"http://localhost:8002/mcp\" },\n    \"omniread\": { \"serverUrl\": \"http://localhost:8003/mcp\" },\n    \"openapi-first\": { \"serverUrl\": \"http://localhost:8004/mcp\" },\n    \"py-jwt\": { \"serverUrl\": \"http://localhost:8005/mcp\" },\n    \"dagpipe\": { \"serverUrl\": \"http://localhost:8006/mcp\" },\n    \"mongo-ops\": { \"serverUrl\": \"http://localhost:8007/mcp\" },\n    \"hexa\": { \"serverUrl\": \"http://localhost:8008/mcp\" },\n    \"doc-weaver\": { \"serverUrl\": \"http://localhost:8010/mcp\" },\n    \"react-auth\": { \"serverUrl\": \"http://localhost:8011/mcp\" },\n    \"react-openapi\": { \"serverUrl\": \"http://localhost:8012/mcp\" },\n    \"vet\": { \"serverUrl\": \"http://localhost:8013/mcp\" }\n  }\n}\n
{\n  \"mcpServers\": {\n    \"standards\": { \"serverUrl\": \"https://mcp.aetoskia.com/standards/mcp\" },\n    \"doc-forge\": { \"serverUrl\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n    \"mail-intake\": { \"serverUrl\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n    \"omniread\": { \"serverUrl\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n    \"openapi-first\": { \"serverUrl\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n    \"py-jwt\": { \"serverUrl\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n    \"dagpipe\": { \"serverUrl\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n    \"mongo-ops\": { \"serverUrl\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n    \"hexa\": { \"serverUrl\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n    \"doc-weaver\": { \"serverUrl\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n    \"react-auth\": { \"serverUrl\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n    \"react-openapi\": { \"serverUrl\": \"https://mcp.aetoskia.com/react-openapi/mcp\" },\n    \"vet\": { \"serverUrl\": \"https://mcp.aetoskia.com/vet/mcp\" }\n  }\n}\n
"},{"location":"05_mcp_setup/#opencode","title":"\ud83e\udd16 OpenCode","text":"

opencode.json (project) or ~/.config/opencode/opencode.json (global).

localhostmcp.aetoskia.com
{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"standards\": { \"type\": \"remote\", \"url\": \"http://localhost:8009/mcp\", \"enabled\": true },\n    \"doc-forge\": { \"type\": \"remote\", \"url\": \"http://localhost:8001/mcp\", \"enabled\": true },\n    \"mail-intake\": { \"type\": \"remote\", \"url\": \"http://localhost:8002/mcp\", \"enabled\": true },\n    \"omniread\": { \"type\": \"remote\", \"url\": \"http://localhost:8003/mcp\", \"enabled\": true },\n    \"openapi-first\": { \"type\": \"remote\", \"url\": \"http://localhost:8004/mcp\", \"enabled\": true },\n    \"py-jwt\": { \"type\": \"remote\", \"url\": \"http://localhost:8005/mcp\", \"enabled\": true },\n    \"dagpipe\": { \"type\": \"remote\", \"url\": \"http://localhost:8006/mcp\", \"enabled\": true },\n    \"mongo-ops\": { \"type\": \"remote\", \"url\": \"http://localhost:8007/mcp\", \"enabled\": true },\n    \"hexa\": { \"type\": \"remote\", \"url\": \"http://localhost:8008/mcp\", \"enabled\": true },\n    \"doc-weaver\": { \"type\": \"remote\", \"url\": \"http://localhost:8010/mcp\", \"enabled\": true },\n    \"react-auth\": { \"type\": \"remote\", \"url\": \"http://localhost:8011/mcp\", \"enabled\": true },\n    \"react-openapi\": { \"type\": \"remote\", \"url\": \"http://localhost:8012/mcp\", \"enabled\": true },\n    \"vet\": { \"type\": \"remote\", \"url\": \"http://localhost:8013/mcp\", \"enabled\": true }\n  }\n}\n
{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"standards\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/standards/mcp\", \"enabled\": true },\n    \"doc-forge\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\", \"enabled\": true },\n    \"mail-intake\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\", \"enabled\": true },\n    \"omniread\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/omniread/mcp\", \"enabled\": true },\n    \"openapi-first\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\", \"enabled\": true },\n    \"py-jwt\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\", \"enabled\": true },\n    \"dagpipe\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\", \"enabled\": true },\n    \"mongo-ops\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\", \"enabled\": true },\n    \"hexa\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/hexa/mcp\", \"enabled\": true },\n    \"doc-weaver\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\", \"enabled\": true },\n    \"react-auth\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\", \"enabled\": true },\n    \"react-openapi\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\", \"enabled\": true },\n    \"vet\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/vet/mcp\", \"enabled\": true }\n  }\n}\n

Or add them with the CLI: opencode mcp add standards --url http://localhost:8009/mcp --global.

"},{"location":"05_mcp_setup/#pycharm-junie-ai-assistant","title":"\ud83e\udd16 PyCharm (Junie / AI Assistant)","text":"

~/.junie/mcp/mcp.json (user scope) or .junie/mcp/mcp.json (project scope). The same config is reachable from Settings | Tools | MCP Server \u2192 Manual Client Configuration \u2192 Copy HTTP Stream Config.

localhostmcp.aetoskia.com
{\n  \"mcpServers\": {\n    \"standards\": { \"url\": \"http://localhost:8009/mcp\" },\n    \"doc-forge\": { \"url\": \"http://localhost:8001/mcp\" },\n    \"mail-intake\": { \"url\": \"http://localhost:8002/mcp\" },\n    \"omniread\": { \"url\": \"http://localhost:8003/mcp\" },\n    \"openapi-first\": { \"url\": \"http://localhost:8004/mcp\" },\n    \"py-jwt\": { \"url\": \"http://localhost:8005/mcp\" },\n    \"dagpipe\": { \"url\": \"http://localhost:8006/mcp\" },\n    \"mongo-ops\": { \"url\": \"http://localhost:8007/mcp\" },\n    \"hexa\": { \"url\": \"http://localhost:8008/mcp\" },\n    \"doc-weaver\": { \"url\": \"http://localhost:8010/mcp\" },\n    \"react-auth\": { \"url\": \"http://localhost:8011/mcp\" },\n    \"react-openapi\": { \"url\": \"http://localhost:8012/mcp\" },\n    \"vet\": { \"url\": \"http://localhost:8013/mcp\" }\n  }\n}\n
{\n  \"mcpServers\": {\n    \"standards\": { \"url\": \"https://mcp.aetoskia.com/standards/mcp\" },\n    \"doc-forge\": { \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n    \"mail-intake\": { \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n    \"omniread\": { \"url\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n    \"openapi-first\": { \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n    \"py-jwt\": { \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n    \"dagpipe\": { \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n    \"mongo-ops\": { \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n    \"hexa\": { \"url\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n    \"doc-weaver\": { \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n    \"react-auth\": { \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n    \"react-openapi\": { \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\" },\n    \"vet\": { \"url\": \"https://mcp.aetoskia.com/vet/mcp\" }\n  }\n}\n
"},{"location":"05_mcp_setup/#verify","title":"\u2705 Verify","text":"
  • Health check: curl http://localhost:8000/healthz \u2192 ok.
  • Claude Code: claude mcp list \u2192 each server \u2026 \u2713 Connected.
  • Codex: codex mcp list \u2192 each server \u2026 http.
  • OpenCode: opencode mcp list \u2192 each server \u2026 connected.
  • In-session: run /mcp to list the connected servers and their tools.
"},{"location":"05_mcp_setup/#reference","title":"\ud83d\udcda Reference","text":"
  • Library Registry \u2014 the catalog each server mirrors, and where find_library resolves
  • Start an App \u2014 connect standards, then invoke start_app
  • App Components \u2014 the component model
"},{"location":"05_mcp_setup/#related","title":"Related","text":"
  • Start an App \u00b7 Testing & Quality \u00b7 Library Registry
"},{"location":"04_development/01_testing/","title":"Testing & Quality Gates","text":"

Two suites run under pytest with asyncio auto mode: integration (the HTTP edge against fakes) and unit (pure domain and pipeline logic). Finish a blueprint app only when every gate below passes.

"},{"location":"04_development/01_testing/#layout","title":"\ud83d\uddc2\ufe0f Layout","text":"
tests/\n    integration/     # TestClient(app) + mocked resources\n    unit/            # models, converters, pipeline stages/roots\n    conftest.py      # fixtures\n
"},{"location":"04_development/01_testing/#integration-tests","title":"\ud83d\ude80 Integration tests","text":"
  • Build the app with TestClient.
  • Replace app.state.db_resources with fake repositories/services so no database is required.
  • Patch the auth introspection call (httpx.AsyncClient.post) to return a canned identity.
  • Assert status codes and bodies for list/get/create/update/delete, plus 400, 404, 204, and the streaming endpoint's fallback.
client = TestClient(app)\napp.state.db_resources = {\"item_svc\": FakeItemService(), ...}\n\ndef test_create_item():\n    r = client.post(\"/items\", json={\"name\": \"x\"})\n    assert r.status_code == 200\n
"},{"location":"04_development/01_testing/#unit-tests","title":"\ud83e\uddea Unit tests","text":"
  • Domain models and converters: pure, no I/O.
  • Pipeline stages: feed a fixture state, assert the transformed state.
  • Assembled pipeline roots: fixture parity \u2014 replay a stored fixture input and compare against a golden output file.
"},{"location":"04_development/01_testing/#config-consistency-tests","title":"\ud83d\udd10 Config-consistency tests","text":"

For rule-driven pipelines, add a test that cross-references rules against the declared pattern registry: every flag emitted must be defined; every defined flag must be reachable. This catches drift without running the pipeline.

"},{"location":"04_development/01_testing/#quality-gates","title":"\u2705 Quality gates","text":"

A definition of done for any standard app:

  • python -c \"import main\" succeeds.
  • pytest passes.
  • The app serves the spec's operations; the worker drains its queue.
  • No domain module imports a web framework.
  • No infrastructure was reimplemented that a library already provides.
"},{"location":"04_development/01_testing/#conventions","title":"\ud83d\udca1 Conventions","text":"
  • asyncio_mode = \"auto\"; no manual event loops.
  • Fixtures are checked into the repo (inputs + golden outputs).
  • Tests skip (not fail) when a required fixture is absent.
  • Do not mock the domain; mock only the infrastructure edge.
"},{"location":"04_development/01_testing/#related","title":"Related","text":"
  • 02 \u2013 App Components \u00b7 03 \u2013 Start an App \u00b7 Overview
"},{"location":"04_development/02_releasing/","title":"Releasing & Versioning","text":"

How to cut a release of any Aetos repository. The rule lives in the reference page Versioning & Changelog; this is the runbook you follow.

Every repository is one of two Drone shapes \u2014 a PyPI package or a Docker deployment (Drone Pipelines). Both release the same way: the version bump and changelog promotion go in the merge request, and the tag is created on the merged commit.

"},{"location":"04_development/02_releasing/#before-you-start","title":"\ud83e\uddfe Before you start","text":"
  • You have an open merge request holding the change, and main is green (the Drone quality gate passed on the last run).
  • You know whether this is a breaking, feature, or fix release.
  • The version file exists:
  • package \u2192 version in pyproject.toml
  • service \u2192 VERSION at the repo root
"},{"location":"04_development/02_releasing/#pick-the-next-version","title":"\ud83d\udea6 Pick the next version","text":"

The version file and the tag must be identical. For 0.y.z, 0.y is the major line (see the reference page); once at 1.0.0, normal SemVer applies.

Change 0.y.z \u2192 1.0.0+ \u2192 Breaking 0.(y+1).0 (x+1).0.0 Feature 0.y.(z+1) x.(y+1).0 Fix 0.y.(z+1) x.y.(z+1)"},{"location":"04_development/02_releasing/#release-in-the-mr","title":"\ud83c\udf3f Release in the MR","text":"

The version is known while the change is still a merge request, so the bump rides along with it. Do all edits in the MR:

  • Reconcile the changelog first. [Unreleased] is a draft, not the source of truth: diff the change against the last tag (git log <last-tag>..HEAD, git diff --stat <last-tag>..HEAD) and add an entry for every user-facing change that is missing. Always show the proposed additions to the user and wait for approval before promoting \u2014 ask rather than guess when an entry is ambiguous.

  • Promote the changelog in CHANGELOG.md: move the (now reconciled) [Unreleased] content under a new ## [x.y.z] - YYYY-MM-DD heading, leave a fresh empty [Unreleased] on top, and add the compare links \u2014 naming the version/tag, never a commit id:

[Unreleased]: https://git.aetoskia.com/aetos/<repo>/compare/x.y.z...HEAD\n[x.y.z]: https://git.aetoskia.com/aetos/<repo>/compare/x.y.(z-1)...x.y.z\n
  • Bump the version file to the intended release version: version = \"x.y.z\" in pyproject.toml (packages) or the VERSION file (services).
"},{"location":"04_development/02_releasing/#tag-the-merged-commit","title":"\ud83c\udff7\ufe0f Tag the merged commit","text":"
  1. Merge or squash the MR into main.
  2. Create the tag on the resulting commit: git tag x.y.z (lightweight).
  3. Push the tag (git push origin x.y.z) \u2014 Drone builds the release.
"},{"location":"04_development/02_releasing/#agent-assisted-tagging","title":"\ud83e\udd16 Agent-assisted tagging","text":"

The agent does not author or merge the MR and never tags before the merge. After you confirm the MR is merged/squashed and tell it to proceed, the agent:

  1. Waits for that explicit go-ahead.
  2. Finds the commit that introduced the bump:
  3. package: git log -S 'version = \"x.y.z\"' -n 1 --format='%H %s' -- pyproject.toml
  4. service: git log -S 'x.y.z' -n 1 --format='%H %s' -- VERSION
  5. Verifies that commit's version file equals x.y.z, then tags only that commit: git tag x.y.z <sha>.
  6. Does not push \u2014 it asks you to run git push origin x.y.z.
"},{"location":"04_development/02_releasing/#what-drone-does","title":"\ud83e\udd16 What Drone does","text":"
  • Type A (package): asserts tag == pyproject version, then skips if that version already exists on the index, runs the quality gate, builds, and uploads the wheel + sdist.
  • Type B (service): asserts tag == VERSION, resolves the tag, skips if the image already exists, runs the quality gate, builds, pushes, and restarts the container.

If the guard fails, nothing is published \u2014 fix the version file, amend the commit, and move the tag only if it was never pushed.

"},{"location":"04_development/02_releasing/#backfill-recovery","title":"\ud83d\udedf Backfill / recovery","text":"

If an older tag never published (a past version-file mismatch, an index outage):

  • Package: run the backfill-pypi-from-tags pipeline (custom event). It checks out every tag, verifies tag == pyproject version at that commit, and uploads the ones missing from the index. Already-fixed history is never rewritten.
  • Service: rebuild the image for the missing tag with a fresh commit and a new patch version; do not move a published tag.
"},{"location":"04_development/02_releasing/#if-a-release-is-wrong","title":"\ud83d\udd01 If a release is wrong","text":"
  • Never reuse or force-move a pushed tag.
  • Fix forward: bump to the next patch, promote the changelog, tag again.
"},{"location":"04_development/02_releasing/#related","title":"Related","text":"
  • Testing & Quality Gates \u00b7 Versioning & Changelog \u00b7 Drone Pipelines
"}]} \ No newline at end of file +{"config":{"lang":["en"],"separator":"[\\s\\-]+","pipeline":["stopWordFilter"]},"docs":[{"location":"","title":"\ud83e\udde9 Standards \u2014 the Aetos App Blueprint","text":"

One reusable architecture for every backend application in the Aetos ecosystem: a spec-first HTTP edge, a framework-free domain core, a pluggable infrastructure layer, and a single composition root.

Fill in two axes only and a new app is done: your resource model, and (if needed) your pipeline family. The blueprint itself never names a business domain \u2014 expenses, health metrics, inventory, and analytics are all the same shape underneath.

Doc model: this wiki is written for humans \u2014 how-to guides, the build recipe, and quality gates. The enforceable rules (layering, composition root, CRUD template, pipeline scaffold) and the library registry live in the reference pages, mirrored by the machine-readable standards MCP bundle. Query find_library before writing any infrastructure.

"},{"location":"#key-features","title":"\ud83d\ude80 Key Features","text":"
  • \ud83e\udded Spec-first routing \u2014 the OpenAPI document, not decorator routers, is the source of truth (operationId lookup)
  • \ud83c\udfd7\ufe0f One-way layering \u2014 interfaces \u2192 domain \u2192 infra, enforced
  • \ud83d\udd0c Single composition root \u2014 every dependency is wired in exactly one place
  • \ud83e\udde9 Generic, not app-specific \u2014 reusable rules versus two authoring axes
  • \ud83d\udcda Library-backed \u2014 DB, DI, pipelines, ingestion, auth, and docs come from internal libraries, never hand-written
  • \ud83d\udea6 Explicit state machines \u2014 durable job statuses, progress, and human-in-the-loop pauses
"},{"location":"#documentation-structure","title":"\ud83d\udcc1 Documentation Structure","text":"Section Description Overview Philosophy, the one-way dependency rule, architecture App Components The component model and how the pieces wire together Start an App The entry point: gather the two axes, then build Testing & Quality Test layout and acceptance gates

Reference (separate site, mirrors the MCP bundle): the enforceable rules \u2014 Build Recipe, Layering, Composition Root, Spec-First Routing, CRUD Template, Pipeline Scaffold, Worker & Progress, Human-in-the-Loop, Infra Adapters, Genericity Matrix, Library Registry.

"},{"location":"#related-resources","title":"\ud83d\udd17 Related Resources","text":"
  • MCP bundle \u2014 standards server on :8009: read docs://index, docs://nav, docs://modules/{module}; call find_library(capability)
  • Library registry \u2014 the catalog of internal libraries behind every app (libraries.json, served as registry://libraries)
  • Template \u2014 the runnable skeleton at standards/src/templates/app/
  • Start a build \u2014 invoke the start_app prompt on the standards server, or read the Start an App guide

\u00a9 Aetoskia Internal \u2014 standards

"},{"location":"01_overview/","title":"Overview","text":"

The blueprint is a hexagonal (ports & adapters) application with a spec-first web edge and a single composition root. It favors explicit wiring over implicit magic and existing internal libraries over hand-written infrastructure. Start here to build the mental model; the enforceable details live in the reference pages.

"},{"location":"01_overview/#architecture","title":"\ud83c\udfd7\ufe0f Architecture","text":"
flowchart LR\n    subgraph EDGE[\"interfaces/ \u2014 HTTP edge\"]\n        OAS[\"openapi.yaml<br/>operationId contract\"]\n        RT[\"<resource>/routes.py<br/>thin handlers\"]\n    end\n\n    subgraph CORE[\"domain/ \u2014 business core\"]\n        MD[\"models\"]\n        PT[\"ports (adapter binding seam)\"]\n        SV[\"services\"]\n    end\n\n    subgraph INFRA[\"infra/ \u2014 adapters\"]\n        RP[\"mongo repos (mongo-ops)\"]\n        AD[\"cache \u00b7 stores \u00b7 llm \u00b7 mail\"]\n        DB[(\"MongoDB\")]\n    end\n\n    CR[\"init.py<br/>composition root\"]\n\n    OAS --> RT\n    RT --> SV\n    SV --> PT\n    SV --> RP\n    PT -. depends on .- RP\n    CR --- RT\n    CR --- SV\n    CR --- RP\n    RP --> DB\n    AD --- CR

The rule holds at every edge: code in an outer ring may depend on a ring closer to the core, never the reverse. domain/ never imports a web framework; only its ports/ seam reaches into infra/ to bind adapters.

Legend \u2014 solid arrows are compile-time calls; dotted arrows are the port/adapter binding, performed by the composition root at startup.

"},{"location":"01_overview/#the-one-way-dependency-rule","title":"\ud83d\udd04 The one-way dependency rule","text":"Ring May import Never imports interfaces/ domain, framework glue (glue only) business logic, infra directly domain/ its own models + its ports/ seam (which binds infra/libraries) web frameworks, interfaces/ infra/ domain ports, drivers, libraries \u2014 init.py everything (the wiring point) \u2014"},{"location":"01_overview/#core-principles","title":"\ud83e\udded Core principles","text":"
  1. One-way dependencies. interfaces -> domain -> infra is allowed; the reverse is forbidden.
  2. Ports in the domain, adapters in infra. A service depends on a port; the port's factory binds the concrete adapter, and the composition root calls those factories.
  3. One composition root. Nothing constructs its own dependencies. All wiring lives in one module (init.py) exposed as a flat resource registry.
  4. Spec-first. The HTTP contract is declared in openapi.yaml; route handlers are looked up by operationId. There are no decorator routers.
  5. Reuse the libraries. Orchestration, DI, Mongo repositories, ingestion, auth, and docs come from internal libraries \u2014 see the Library Registry.
  6. Explicit state machines. Long-running work moves through explicit, durable statuses and can pause for human input.
"},{"location":"01_overview/#runtime-processes","title":"\u2699\ufe0f Runtime processes","text":"

A standard app may run as up to three processes that share the same composition root:

Process Entry point Responsibility API main.py serve HTTP; start/stop resources via lifespan Worker worker.py poll durable jobs, run pipelines, publish progress Scripts python -m scripts.<name> one-shot operator tasks"},{"location":"01_overview/#read-next","title":"\u27a1\ufe0f Read Next","text":"
  • 02 \u2013 App Components \u00b7 03 \u2013 Start an App
"},{"location":"02_components/","title":"App Components","text":"

What ships in every standard app, and how the pieces relate. This is the blueprint's component model \u2014 templates/app/ is a runnable instance of it.

"},{"location":"02_components/#component-model","title":"\ud83d\uddc2\ufe0f Component model","text":"

The blueprint has two orthogonal views: runtime flow (who calls whom) and composition-root wiring (who constructs whom). Keeping them separate makes the layering visible instead of hiding it behind a hub.

"},{"location":"02_components/#runtime-flow","title":"\ud83d\udd00 Runtime flow","text":"

Who calls whom at request and job time:

%%{init: {\"flowchart\": {\"nodeSpacing\": 50, \"rankSpacing\": 80}}}%%\nflowchart TB\n    subgraph REQ[\"Request path \u2014 API process\"]\n        direction LR\n        CL([\"Client<br/>operationId\"]) --> RT[\"interfaces/&lt;resource&gt;/routes.py\"]\n        RT --> SVC[\"&lt;resource&gt;_svc\"]\n        SVC --> REPO[\"&lt;resource&gt;_repo\"]\n    end\n\n    subgraph WRK[\"Background path \u2014 worker process\"]\n        direction LR\n        W[\"worker.py\"] --> JSVC[\"job_svc\"]\n        W --> PIPE[\"pipelines/&lt;family&gt;\"]\n        PIPE --> ISVC[\"item_svc\"]\n        JSVC --> JREPO[\"job_repo\"]\n        ISVC --> IREPO[\"item_repo\"]\n    end\n\n    subgraph INFRA[\"infra/ \u2014 adapters\"]\n        MONGO[(\"MongoDB / mongo_ops\")]\n    end\n\n    REPO --> MONGO\n    JREPO --> MONGO\n    IREPO --> MONGO

Legend \u2014 solid arrows are runtime calls. Nothing is self-constructed.

"},{"location":"02_components/#composition-root-wiring","title":"\ud83e\uddf5 Composition-root wiring","text":"

Who constructs what at startup:

%%{init: {\"flowchart\": {\"nodeSpacing\": 50, \"rankSpacing\": 80}}}%%\nflowchart TB\n    INIT[\"init.py \u2014 composition root\"]\n    SETUP[\"infra/db/setup.py\"]\n    FACT[\"domain/*/ports/*<br/>factory seams\"]\n    REPOS[\"repos<br/>infra/db/repos/mongo.py\"]\n    SVCES[\"services<br/>CrudsServiceAdaptor\"]\n    STATE[\"app.state.db_resources\"]\n    HEXA[\"hexa.build\"]\n    RT[\"routes.py\"]\n    WK[\"worker.py\"]\n\n    INIT --> SETUP\n    INIT --> FACT\n    FACT --> REPOS\n    FACT --> SVCES\n    REPOS --> SVCES\n    HEXA -.-> SVCES\n    INIT --> STATE\n    STATE --> RT\n    INIT --> WK

Legend \u2014 init.py is the only place that imports concrete adapters. The ports/ factory seams bind infra; the API reads resources from app.state.db_resources, the worker calls init() directly.

"},{"location":"02_components/#component-roles","title":"\ud83d\udce6 Component roles","text":""},{"location":"02_components/#1-interfaces-the-edge","title":"1. interfaces/ \u2014 the edge","text":"

Thin handlers bound to openapi.yaml operationIds. They parse the request, call a service, and shape the response. No business rules, no I/O.

  • interfaces/openapi.py re-exports every route module so the OpenAPI-first app can resolve handlers.
  • Routes may mount the cache decorator on read endpoints.
"},{"location":"02_components/#2-domain-the-core","title":"2. domain/ \u2014 the core","text":"

Models, ports, and services (use cases). No framework imports. The ports/ package is the one seam allowed to reach into infra/: each port module declares the document shape and a factory that binds the adapter.

  • <aggregate>/models.py \u2014 dataclasses, enums, document shapes.
  • <aggregate>/ports/db.py \u2014 document model + create_<aggregate>_repo().
  • <aggregate>/ports/service.py \u2014 service + get_<aggregate>_service(repo).
  • Services compose ports and enforce the business rules; the port factories bind the implementations, and the composition root calls them.
"},{"location":"02_components/#3-infra-the-adapters","title":"3. infra/ \u2014 the adapters","text":"

Concrete implementations of the domain ports plus cross-cutting infrastructure:

  • db/ \u2014 mongo-ops repositories and the connection lifecycle.
  • adapters/ \u2014 cache store, progress bus, storages, fetchers (library-backed).
  • Anything else the domain needs, implemented against its ports.
"},{"location":"02_components/#4-pipelines-data-driven-families-optional","title":"4. pipelines/ \u2014 data-driven families (optional)","text":"

Extraction and enrichment families, each a deterministic step chain (abc.py / impl.py / pipeline.yaml / resources/). Roots are registered in the pattern registry and driven either by a worker job or a CLI.

"},{"location":"02_components/#5-workerpy-the-job-worker-optional","title":"5. worker.py \u2014 the job worker (optional)","text":"

A separate process that polls durable job collections, runs pipeline roots, and publishes progress to the progress bus. It shares the same composition root as the API.

"},{"location":"02_components/#6-initpy-the-composition-root","title":"6. init.py \u2014 the composition root","text":"

The only place anything is constructed: leaf repositories \u2192 dependent repositories \u2192 services \u2192 adapters. Exposes get_svc overloads and starts / stops resources on the app lifespan.

"},{"location":"02_components/#how-the-request-flows","title":"\ud83d\udd17 How the request flows","text":"
sequenceDiagram\n    participant C as Client\n    participant R as route (interfaces)\n    participant S as service (port factory / adapter)\n    participant P as repo (infra)\n    participant DB as MongoDB\n\n    C->>R: POST /items (operationId)\n    R->>S: svc.create(payload)\n    S->>P: repo.insert(doc)\n    P->>DB: insert\n    DB-->>P: ack\n    P-->>S: doc\n    S-->>R: result\n    R-->>C: 200 JSON
"},{"location":"02_components/#related","title":"Related","text":"
  • 01 \u2013 Overview \u00b7 03 \u2013 Start an App \u00b7 04 \u2013 Testing & Quality
"},{"location":"03_start_an_app/","title":"\ud83d\ude80 Start an App","text":"

This is the entry point for building a new application from the blueprint. The goal is one deterministic pass: you supply only the two axes, and the agent does the rest by reading the standards MCP, importing Tier A libraries, and copying Tier B template components.

Doc model: this page is the human entry point. The deterministic, machine-facing checklist lives in the reference page Build Recipe, served as docs://modules/build_recipe.

"},{"location":"03_start_an_app/#what-the-agent-needs-from-you","title":"\ud83e\uddfe What the agent needs from you","text":"

Gather these before starting \u2014 the start_app MCP prompt asks for them:

  1. App name + one-line purpose.
  2. Axis 1 \u2014 resources. Each resource, its fields, and relationships. Paste openapi.yaml if you already have it.
  3. Axis 2 \u2014 pipelines. Only if an input needs a multi-step transformation: the families and their input formats (or \"none\").
  4. Auth needed now? Default no. Auth is deferred (py-jwt primitives only), and an authless app is just a spec with no security keys \u2014 see Spec-First Routing \u2192 Authless apps.
  5. Integrations. Mongo, ingestion formats, email, LLM provider.

If you can state axes 1 and 2, the rest is mechanical.

"},{"location":"03_start_an_app/#how-to-start","title":"\u25b6\ufe0f How to start","text":"

From an MCP client connected to the standards server:

  1. Invoke the intake prompt (or start_app with no arguments) to get the intake questions.
  2. Answer them, then invoke build (build(app_name=..., resources=..., pipelines=..., auth=...)), or use start_app to intake-and-build in one call.
  3. The prompt hands off to docs://modules/build_recipe; the agent scaffolds with get_app_template() and pulls exact files with get_app_component(kind, resource=..., family=...), authoring only the app-specific parts.
  4. To validate the standard without touching a real app, invoke trial (trial(app_name=..., build_path=...)) to build into a scratch directory, prove it builds, and report findings.

Manual alternative \u2014 copy the skeleton and follow the reference recipe:

cp -r <docs>/standards/src/templates/app apps/<your-app>\n
"},{"location":"03_start_an_app/#reference","title":"\ud83d\udcda Reference","text":"
  • Build Recipe \u2014 the deterministic checklist
  • Genericity Matrix \u2014 Tier A / B / C
  • Library Registry \u2014 the Tier A catalog
  • App Components \u2014 the component model
"},{"location":"03_start_an_app/#related","title":"Related","text":"
  • 01 \u2013 Overview \u00b7 02 \u2013 App Components \u00b7 04 \u2013 Testing & Quality
"},{"location":"05_mcp_setup/","title":"\ud83d\udd0c MCP Setup","text":"

Every repository ships its documentation as a Model Context Protocol (MCP) server, and the standards registry server ties them together. The docs portal runs each one as a FastMCP streamable-http app bound to 0.0.0.0:<port>, exposing the endpoint at /mcp (see docs/main.py and docs/config.yml).

Connect your agent to the standards server first: it answers find_library, list_repos, and the start_app prompt, so the agent reaches for an internal library instead of reimplementing one (see the Library Registry).

"},{"location":"05_mcp_setup/#run-the-servers-locally","title":"\u25b6\ufe0f Run the servers locally","text":"

From the docs checkout:

.venv\\Scripts\\python.exe main.py                      # every server\n.venv\\Scripts\\python.exe main.py --servers standards   # just the registry\n

:8000 is the health endpoint (GET /healthz), not an MCP server.

"},{"location":"05_mcp_setup/#servers","title":"\ud83e\udded Servers","text":"Slug MCP server Port localhost mcp.aetoskia.com standards standards 8009 http://localhost:8009/mcp https://mcp.aetoskia.com/standards/mcp doc-forge docforge 8001 http://localhost:8001/mcp https://mcp.aetoskia.com/doc-forge/mcp mail-intake mail_intake 8002 http://localhost:8002/mcp https://mcp.aetoskia.com/mail-intake/mcp omniread omniread 8003 http://localhost:8003/mcp https://mcp.aetoskia.com/omniread/mcp openapi-first openapi_first 8004 http://localhost:8004/mcp https://mcp.aetoskia.com/openapi-first/mcp py-jwt jwtlib 8005 http://localhost:8005/mcp https://mcp.aetoskia.com/py-jwt/mcp dagpipe dagpipe 8006 http://localhost:8006/mcp https://mcp.aetoskia.com/dagpipe/mcp mongo-ops mongo_ops 8007 http://localhost:8007/mcp https://mcp.aetoskia.com/mongo-ops/mcp hexa hexa 8008 http://localhost:8008/mcp https://mcp.aetoskia.com/hexa/mcp doc-weaver doc-weaver 8010 http://localhost:8010/mcp https://mcp.aetoskia.com/doc-weaver/mcp react-auth react-auth 8011 http://localhost:8011/mcp https://mcp.aetoskia.com/react-auth/mcp react-openapi react-openapi 8012 http://localhost:8012/mcp https://mcp.aetoskia.com/react-openapi/mcp

The hosted endpoints are served over HTTPS at https://mcp.aetoskia.com/<slug>/mcp. The tabs below are linked (content.tabs.link): switching one switches all of them. Every snippet registers all twelve servers, so a single paste is enough.

"},{"location":"05_mcp_setup/#claude-code","title":"\ud83e\udd16 Claude Code","text":"

Project-scoped .mcp.json at the repo root. The type field is required \u2014 an entry with a url but no type is read as a stdio server and skipped.

localhostmcp.aetoskia.com
{\n  \"mcpServers\": {\n    \"standards\": { \"type\": \"http\", \"url\": \"http://localhost:8009/mcp\" },\n    \"doc-forge\": { \"type\": \"http\", \"url\": \"http://localhost:8001/mcp\" },\n    \"mail-intake\": { \"type\": \"http\", \"url\": \"http://localhost:8002/mcp\" },\n    \"omniread\": { \"type\": \"http\", \"url\": \"http://localhost:8003/mcp\" },\n    \"openapi-first\": { \"type\": \"http\", \"url\": \"http://localhost:8004/mcp\" },\n    \"py-jwt\": { \"type\": \"http\", \"url\": \"http://localhost:8005/mcp\" },\n    \"dagpipe\": { \"type\": \"http\", \"url\": \"http://localhost:8006/mcp\" },\n    \"mongo-ops\": { \"type\": \"http\", \"url\": \"http://localhost:8007/mcp\" },\n    \"hexa\": { \"type\": \"http\", \"url\": \"http://localhost:8008/mcp\" },\n    \"doc-weaver\": { \"type\": \"http\", \"url\": \"http://localhost:8010/mcp\" },\n    \"react-auth\": { \"type\": \"http\", \"url\": \"http://localhost:8011/mcp\" },\n    \"react-openapi\": { \"type\": \"http\", \"url\": \"http://localhost:8012/mcp\" }\n  }\n}\n
{\n  \"mcpServers\": {\n    \"standards\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/standards/mcp\" },\n    \"doc-forge\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n    \"mail-intake\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n    \"omniread\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n    \"openapi-first\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n    \"py-jwt\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n    \"dagpipe\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n    \"mongo-ops\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n    \"hexa\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n    \"doc-weaver\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n    \"react-auth\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n    \"react-openapi\": { \"type\": \"http\", \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\" }\n  }\n}\n

Or add them with the CLI: claude mcp add --transport http standards http://localhost:8009/mcp.

"},{"location":"05_mcp_setup/#codex","title":"\ud83e\udd16 Codex","text":"

~/.codex/config.toml (or a project-scoped .codex/config.toml).

localhostmcp.aetoskia.com
[mcp_servers.standards]\nurl = \"http://localhost:8009/mcp\"\n\n[mcp_servers.doc-forge]\nurl = \"http://localhost:8001/mcp\"\n\n[mcp_servers.mail-intake]\nurl = \"http://localhost:8002/mcp\"\n\n[mcp_servers.omniread]\nurl = \"http://localhost:8003/mcp\"\n\n[mcp_servers.openapi-first]\nurl = \"http://localhost:8004/mcp\"\n\n[mcp_servers.py-jwt]\nurl = \"http://localhost:8005/mcp\"\n\n[mcp_servers.dagpipe]\nurl = \"http://localhost:8006/mcp\"\n\n[mcp_servers.mongo-ops]\nurl = \"http://localhost:8007/mcp\"\n\n[mcp_servers.hexa]\nurl = \"http://localhost:8008/mcp\"\n\n[mcp_servers.doc-weaver]\nurl = \"http://localhost:8010/mcp\"\n\n[mcp_servers.react-auth]\nurl = \"http://localhost:8011/mcp\"\n\n[mcp_servers.react-openapi]\nurl = \"http://localhost:8012/mcp\"\n
[mcp_servers.standards]\nurl = \"https://mcp.aetoskia.com/standards/mcp\"\n\n[mcp_servers.doc-forge]\nurl = \"https://mcp.aetoskia.com/doc-forge/mcp\"\n\n[mcp_servers.mail-intake]\nurl = \"https://mcp.aetoskia.com/mail-intake/mcp\"\n\n[mcp_servers.omniread]\nurl = \"https://mcp.aetoskia.com/omniread/mcp\"\n\n[mcp_servers.openapi-first]\nurl = \"https://mcp.aetoskia.com/openapi-first/mcp\"\n\n[mcp_servers.py-jwt]\nurl = \"https://mcp.aetoskia.com/py-jwt/mcp\"\n\n[mcp_servers.dagpipe]\nurl = \"https://mcp.aetoskia.com/dagpipe/mcp\"\n\n[mcp_servers.mongo-ops]\nurl = \"https://mcp.aetoskia.com/mongo-ops/mcp\"\n\n[mcp_servers.hexa]\nurl = \"https://mcp.aetoskia.com/hexa/mcp\"\n\n[mcp_servers.doc-weaver]\nurl = \"https://mcp.aetoskia.com/doc-weaver/mcp\"\n\n[mcp_servers.react-auth]\nurl = \"https://mcp.aetoskia.com/react-auth/mcp\"\n\n[mcp_servers.react-openapi]\nurl = \"https://mcp.aetoskia.com/react-openapi/mcp\"\n

Or add them with the CLI: codex mcp add standards --url http://localhost:8009/mcp.

"},{"location":"05_mcp_setup/#antigravity","title":"\ud83e\udd16 Antigravity","text":"

~/.gemini/antigravity/mcp_config.json (IDE) or ~/.gemini/config/mcp_config.json (CLI). Antigravity uses serverUrl, not url, for HTTP endpoints.

localhostmcp.aetoskia.com
{\n  \"mcpServers\": {\n    \"standards\": { \"serverUrl\": \"http://localhost:8009/mcp\" },\n    \"doc-forge\": { \"serverUrl\": \"http://localhost:8001/mcp\" },\n    \"mail-intake\": { \"serverUrl\": \"http://localhost:8002/mcp\" },\n    \"omniread\": { \"serverUrl\": \"http://localhost:8003/mcp\" },\n    \"openapi-first\": { \"serverUrl\": \"http://localhost:8004/mcp\" },\n    \"py-jwt\": { \"serverUrl\": \"http://localhost:8005/mcp\" },\n    \"dagpipe\": { \"serverUrl\": \"http://localhost:8006/mcp\" },\n    \"mongo-ops\": { \"serverUrl\": \"http://localhost:8007/mcp\" },\n    \"hexa\": { \"serverUrl\": \"http://localhost:8008/mcp\" },\n    \"doc-weaver\": { \"serverUrl\": \"http://localhost:8010/mcp\" },\n    \"react-auth\": { \"serverUrl\": \"http://localhost:8011/mcp\" },\n    \"react-openapi\": { \"serverUrl\": \"http://localhost:8012/mcp\" }\n  }\n}\n
{\n  \"mcpServers\": {\n    \"standards\": { \"serverUrl\": \"https://mcp.aetoskia.com/standards/mcp\" },\n    \"doc-forge\": { \"serverUrl\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n    \"mail-intake\": { \"serverUrl\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n    \"omniread\": { \"serverUrl\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n    \"openapi-first\": { \"serverUrl\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n    \"py-jwt\": { \"serverUrl\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n    \"dagpipe\": { \"serverUrl\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n    \"mongo-ops\": { \"serverUrl\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n    \"hexa\": { \"serverUrl\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n    \"doc-weaver\": { \"serverUrl\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n    \"react-auth\": { \"serverUrl\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n    \"react-openapi\": { \"serverUrl\": \"https://mcp.aetoskia.com/react-openapi/mcp\" }\n  }\n}\n
"},{"location":"05_mcp_setup/#opencode","title":"\ud83e\udd16 OpenCode","text":"

opencode.json (project) or ~/.config/opencode/opencode.json (global).

localhostmcp.aetoskia.com
{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"standards\": { \"type\": \"remote\", \"url\": \"http://localhost:8009/mcp\", \"enabled\": true },\n    \"doc-forge\": { \"type\": \"remote\", \"url\": \"http://localhost:8001/mcp\", \"enabled\": true },\n    \"mail-intake\": { \"type\": \"remote\", \"url\": \"http://localhost:8002/mcp\", \"enabled\": true },\n    \"omniread\": { \"type\": \"remote\", \"url\": \"http://localhost:8003/mcp\", \"enabled\": true },\n    \"openapi-first\": { \"type\": \"remote\", \"url\": \"http://localhost:8004/mcp\", \"enabled\": true },\n    \"py-jwt\": { \"type\": \"remote\", \"url\": \"http://localhost:8005/mcp\", \"enabled\": true },\n    \"dagpipe\": { \"type\": \"remote\", \"url\": \"http://localhost:8006/mcp\", \"enabled\": true },\n    \"mongo-ops\": { \"type\": \"remote\", \"url\": \"http://localhost:8007/mcp\", \"enabled\": true },\n    \"hexa\": { \"type\": \"remote\", \"url\": \"http://localhost:8008/mcp\", \"enabled\": true },\n    \"doc-weaver\": { \"type\": \"remote\", \"url\": \"http://localhost:8010/mcp\", \"enabled\": true },\n    \"react-auth\": { \"type\": \"remote\", \"url\": \"http://localhost:8011/mcp\", \"enabled\": true },\n    \"react-openapi\": { \"type\": \"remote\", \"url\": \"http://localhost:8012/mcp\", \"enabled\": true }\n  }\n}\n
{\n  \"$schema\": \"https://opencode.ai/config.json\",\n  \"mcp\": {\n    \"standards\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/standards/mcp\", \"enabled\": true },\n    \"doc-forge\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\", \"enabled\": true },\n    \"mail-intake\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\", \"enabled\": true },\n    \"omniread\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/omniread/mcp\", \"enabled\": true },\n    \"openapi-first\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\", \"enabled\": true },\n    \"py-jwt\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\", \"enabled\": true },\n    \"dagpipe\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\", \"enabled\": true },\n    \"mongo-ops\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\", \"enabled\": true },\n    \"hexa\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/hexa/mcp\", \"enabled\": true },\n    \"doc-weaver\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\", \"enabled\": true },\n    \"react-auth\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\", \"enabled\": true },\n    \"react-openapi\": { \"type\": \"remote\", \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\", \"enabled\": true }\n  }\n}\n

Or add them with the CLI: opencode mcp add standards --url http://localhost:8009/mcp --global.

"},{"location":"05_mcp_setup/#pycharm-junie-ai-assistant","title":"\ud83e\udd16 PyCharm (Junie / AI Assistant)","text":"

~/.junie/mcp/mcp.json (user scope) or .junie/mcp/mcp.json (project scope). The same config is reachable from Settings | Tools | MCP Server \u2192 Manual Client Configuration \u2192 Copy HTTP Stream Config.

localhostmcp.aetoskia.com
{\n  \"mcpServers\": {\n    \"standards\": { \"url\": \"http://localhost:8009/mcp\" },\n    \"doc-forge\": { \"url\": \"http://localhost:8001/mcp\" },\n    \"mail-intake\": { \"url\": \"http://localhost:8002/mcp\" },\n    \"omniread\": { \"url\": \"http://localhost:8003/mcp\" },\n    \"openapi-first\": { \"url\": \"http://localhost:8004/mcp\" },\n    \"py-jwt\": { \"url\": \"http://localhost:8005/mcp\" },\n    \"dagpipe\": { \"url\": \"http://localhost:8006/mcp\" },\n    \"mongo-ops\": { \"url\": \"http://localhost:8007/mcp\" },\n    \"hexa\": { \"url\": \"http://localhost:8008/mcp\" },\n    \"doc-weaver\": { \"url\": \"http://localhost:8010/mcp\" },\n    \"react-auth\": { \"url\": \"http://localhost:8011/mcp\" },\n    \"react-openapi\": { \"url\": \"http://localhost:8012/mcp\" }\n  }\n}\n
{\n  \"mcpServers\": {\n    \"standards\": { \"url\": \"https://mcp.aetoskia.com/standards/mcp\" },\n    \"doc-forge\": { \"url\": \"https://mcp.aetoskia.com/doc-forge/mcp\" },\n    \"mail-intake\": { \"url\": \"https://mcp.aetoskia.com/mail-intake/mcp\" },\n    \"omniread\": { \"url\": \"https://mcp.aetoskia.com/omniread/mcp\" },\n    \"openapi-first\": { \"url\": \"https://mcp.aetoskia.com/openapi-first/mcp\" },\n    \"py-jwt\": { \"url\": \"https://mcp.aetoskia.com/py-jwt/mcp\" },\n    \"dagpipe\": { \"url\": \"https://mcp.aetoskia.com/dagpipe/mcp\" },\n    \"mongo-ops\": { \"url\": \"https://mcp.aetoskia.com/mongo-ops/mcp\" },\n    \"hexa\": { \"url\": \"https://mcp.aetoskia.com/hexa/mcp\" },\n    \"doc-weaver\": { \"url\": \"https://mcp.aetoskia.com/doc-weaver/mcp\" },\n    \"react-auth\": { \"url\": \"https://mcp.aetoskia.com/react-auth/mcp\" },\n    \"react-openapi\": { \"url\": \"https://mcp.aetoskia.com/react-openapi/mcp\" }\n  }\n}\n
"},{"location":"05_mcp_setup/#verify","title":"\u2705 Verify","text":"
  • Health check: curl http://localhost:8000/healthz \u2192 ok.
  • Claude Code: claude mcp list \u2192 each server \u2026 \u2713 Connected.
  • Codex: codex mcp list \u2192 each server \u2026 http.
  • OpenCode: opencode mcp list \u2192 each server \u2026 connected.
  • In-session: run /mcp to list the connected servers and their tools.
"},{"location":"05_mcp_setup/#reference","title":"\ud83d\udcda Reference","text":"
  • Library Registry \u2014 the catalog each server mirrors, and where find_library resolves
  • Start an App \u2014 connect standards, then invoke start_app
  • App Components \u2014 the component model
"},{"location":"05_mcp_setup/#related","title":"Related","text":"
  • Start an App \u00b7 Testing & Quality \u00b7 Library Registry
"},{"location":"04_development/01_testing/","title":"Testing & Quality Gates","text":"

Two suites run under pytest with asyncio auto mode: integration (the HTTP edge against fakes) and unit (pure domain and pipeline logic). Finish a blueprint app only when every gate below passes.

"},{"location":"04_development/01_testing/#layout","title":"\ud83d\uddc2\ufe0f Layout","text":"
tests/\n    integration/     # TestClient(app) + mocked resources\n    unit/            # models, converters, pipeline stages/roots\n    conftest.py      # fixtures\n
"},{"location":"04_development/01_testing/#integration-tests","title":"\ud83d\ude80 Integration tests","text":"
  • Build the app with TestClient.
  • Replace app.state.db_resources with fake repositories/services so no database is required.
  • Patch the auth introspection call (httpx.AsyncClient.post) to return a canned identity.
  • Assert status codes and bodies for list/get/create/update/delete, plus 400, 404, 204, and the streaming endpoint's fallback.
client = TestClient(app)\napp.state.db_resources = {\"item_svc\": FakeItemService(), ...}\n\ndef test_create_item():\n    r = client.post(\"/items\", json={\"name\": \"x\"})\n    assert r.status_code == 200\n
"},{"location":"04_development/01_testing/#unit-tests","title":"\ud83e\uddea Unit tests","text":"
  • Domain models and converters: pure, no I/O.
  • Pipeline stages: feed a fixture state, assert the transformed state.
  • Assembled pipeline roots: fixture parity \u2014 replay a stored fixture input and compare against a golden output file.
"},{"location":"04_development/01_testing/#config-consistency-tests","title":"\ud83d\udd10 Config-consistency tests","text":"

For rule-driven pipelines, add a test that cross-references rules against the declared pattern registry: every flag emitted must be defined; every defined flag must be reachable. This catches drift without running the pipeline.

"},{"location":"04_development/01_testing/#quality-gates","title":"\u2705 Quality gates","text":"

A definition of done for any standard app:

  • python -c \"import main\" succeeds.
  • pytest passes.
  • The app serves the spec's operations; the worker drains its queue.
  • No domain module imports a web framework.
  • No infrastructure was reimplemented that a library already provides.
"},{"location":"04_development/01_testing/#conventions","title":"\ud83d\udca1 Conventions","text":"
  • asyncio_mode = \"auto\"; no manual event loops.
  • Fixtures are checked into the repo (inputs + golden outputs).
  • Tests skip (not fail) when a required fixture is absent.
  • Do not mock the domain; mock only the infrastructure edge.
"},{"location":"04_development/01_testing/#related","title":"Related","text":"
  • 02 \u2013 App Components \u00b7 03 \u2013 Start an App \u00b7 Overview
"},{"location":"04_development/02_releasing/","title":"Releasing & Versioning","text":"

How to cut a release of any Aetos repository. The rule lives in the reference page Versioning & Changelog; this is the runbook you follow.

Every repository is one of two Drone shapes \u2014 a PyPI package or a Docker deployment (Drone Pipelines). Both release the same way: the version bump and changelog promotion go in the merge request, and the tag is created on the merged commit.

"},{"location":"04_development/02_releasing/#before-you-start","title":"\ud83e\uddfe Before you start","text":"
  • You have an open merge request holding the change, and main is green (the Drone quality gate passed on the last run).
  • You know whether this is a breaking, feature, or fix release.
  • The version file exists:
  • package \u2192 version in pyproject.toml
  • service \u2192 VERSION at the repo root
"},{"location":"04_development/02_releasing/#pick-the-next-version","title":"\ud83d\udea6 Pick the next version","text":"

The version file and the tag must be identical. For 0.y.z, 0.y is the major line (see the reference page); once at 1.0.0, normal SemVer applies.

Change 0.y.z \u2192 1.0.0+ \u2192 Breaking 0.(y+1).0 (x+1).0.0 Feature 0.y.(z+1) x.(y+1).0 Fix 0.y.(z+1) x.y.(z+1)"},{"location":"04_development/02_releasing/#release-in-the-mr","title":"\ud83c\udf3f Release in the MR","text":"

The version is known while the change is still a merge request, so the bump rides along with it. Do all edits in the MR:

  • Reconcile the changelog first. [Unreleased] is a draft, not the source of truth: diff the change against the last tag (git log <last-tag>..HEAD, git diff --stat <last-tag>..HEAD) and add an entry for every user-facing change that is missing. Always show the proposed additions to the user and wait for approval before promoting \u2014 ask rather than guess when an entry is ambiguous.

  • Promote the changelog in CHANGELOG.md: move the (now reconciled) [Unreleased] content under a new ## [x.y.z] - YYYY-MM-DD heading, leave a fresh empty [Unreleased] on top, and add the compare links \u2014 naming the version/tag, never a commit id:

[Unreleased]: https://git.aetoskia.com/aetos/<repo>/compare/x.y.z...HEAD\n[x.y.z]: https://git.aetoskia.com/aetos/<repo>/compare/x.y.(z-1)...x.y.z\n
  • Bump the version file to the intended release version: version = \"x.y.z\" in pyproject.toml (packages) or the VERSION file (services).
"},{"location":"04_development/02_releasing/#tag-the-merged-commit","title":"\ud83c\udff7\ufe0f Tag the merged commit","text":"
  1. Merge or squash the MR into main.
  2. Create the tag on the resulting commit: git tag x.y.z (lightweight).
  3. Push the tag (git push origin x.y.z) \u2014 Drone builds the release.
"},{"location":"04_development/02_releasing/#agent-assisted-tagging","title":"\ud83e\udd16 Agent-assisted tagging","text":"

The agent does not author or merge the MR and never tags before the merge. After you confirm the MR is merged/squashed and tell it to proceed, the agent:

  1. Waits for that explicit go-ahead.
  2. Finds the commit that introduced the bump:
  3. package: git log -S 'version = \"x.y.z\"' -n 1 --format='%H %s' -- pyproject.toml
  4. service: git log -S 'x.y.z' -n 1 --format='%H %s' -- VERSION
  5. Verifies that commit's version file equals x.y.z, then tags only that commit: git tag x.y.z <sha>.
  6. Does not push \u2014 it asks you to run git push origin x.y.z.
"},{"location":"04_development/02_releasing/#what-drone-does","title":"\ud83e\udd16 What Drone does","text":"
  • Type A (package): asserts tag == pyproject version, then skips if that version already exists on the index, runs the quality gate, builds, and uploads the wheel + sdist.
  • Type B (service): asserts tag == VERSION, resolves the tag, skips if the image already exists, runs the quality gate, builds, pushes, and restarts the container.

If the guard fails, nothing is published \u2014 fix the version file, amend the commit, and move the tag only if it was never pushed.

"},{"location":"04_development/02_releasing/#backfill-recovery","title":"\ud83d\udedf Backfill / recovery","text":"

If an older tag never published (a past version-file mismatch, an index outage):

  • Package: run the backfill-pypi-from-tags pipeline (custom event). It checks out every tag, verifies tag == pyproject version at that commit, and uploads the ones missing from the index. Already-fixed history is never rewritten.
  • Service: rebuild the image for the missing tag with a fresh commit and a new patch version; do not move a published tag.
"},{"location":"04_development/02_releasing/#if-a-release-is-wrong","title":"\ud83d\udd01 If a release is wrong","text":"
  • Never reuse or force-move a pushed tag.
  • Fix forward: bump to the next patch, promote the changelog, tag again.
"},{"location":"04_development/02_releasing/#related","title":"Related","text":"
  • Testing & Quality Gates \u00b7 Versioning & Changelog \u00b7 Drone Pipelines
"}]} \ No newline at end of file diff --git a/standards/wiki/sitemap.xml.gz b/standards/wiki/sitemap.xml.gz index 43b6693ea67df02dd9f5455bc82850339c9ac646..7140084f63cdc7ac094f9b92e2c304376b6ad4a8 100644 GIT binary patch delta 13 Ucmb=gXP58h;An`wI+48s03EOdf&c&j delta 13 Ucmb=gXP58h;9%gnGLgLk02vnpumAu6 diff --git a/vet/lib/.nojekyll b/vet/lib/.nojekyll deleted file mode 100644 index e2ac661..0000000 --- a/vet/lib/.nojekyll +++ /dev/null @@ -1 +0,0 @@ -TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. \ No newline at end of file diff --git a/vet/lib/assets/hierarchy.js b/vet/lib/assets/hierarchy.js deleted file mode 100644 index 88636f0..0000000 --- a/vet/lib/assets/hierarchy.js +++ /dev/null @@ -1 +0,0 @@ -window.hierarchyData = "eJyrVirKzy8pVrKKjtVRKkpNy0lNLsnMzwMKVNfWAgCbHgqm" \ No newline at end of file diff --git a/vet/lib/assets/highlight.css b/vet/lib/assets/highlight.css deleted file mode 100644 index b4202ee..0000000 --- a/vet/lib/assets/highlight.css +++ /dev/null @@ -1,92 +0,0 @@ -:root { - --light-hl-0: #800000; - --dark-hl-0: #808080; - --light-hl-1: #267F99; - --dark-hl-1: #4EC9B0; - --light-hl-2: #000000; - --dark-hl-2: #D4D4D4; - --light-hl-3: #E50000; - --dark-hl-3: #9CDCFE; - --light-hl-4: #A31515; - --dark-hl-4: #CE9178; - --light-hl-5: #0000FF; - --dark-hl-5: #569CD6; - --light-hl-6: #0070C1; - --dark-hl-6: #4FC1FF; - --light-hl-7: #795E26; - --dark-hl-7: #DCDCAA; - --light-hl-8: #001080; - --dark-hl-8: #9CDCFE; - --light-hl-9: #008000; - --dark-hl-9: #6A9955; - --light-code-background: #FFFFFF; - --dark-code-background: #1E1E1E; -} - -@media (prefers-color-scheme: light) { :root { - --hl-0: var(--light-hl-0); - --hl-1: var(--light-hl-1); - --hl-2: var(--light-hl-2); - --hl-3: var(--light-hl-3); - --hl-4: var(--light-hl-4); - --hl-5: var(--light-hl-5); - --hl-6: var(--light-hl-6); - --hl-7: var(--light-hl-7); - --hl-8: var(--light-hl-8); - --hl-9: var(--light-hl-9); - --code-background: var(--light-code-background); -} } - -@media (prefers-color-scheme: dark) { :root { - --hl-0: var(--dark-hl-0); - --hl-1: var(--dark-hl-1); - --hl-2: var(--dark-hl-2); - --hl-3: var(--dark-hl-3); - --hl-4: var(--dark-hl-4); - --hl-5: var(--dark-hl-5); - --hl-6: var(--dark-hl-6); - --hl-7: var(--dark-hl-7); - --hl-8: var(--dark-hl-8); - --hl-9: var(--dark-hl-9); - --code-background: var(--dark-code-background); -} } - -:root[data-theme='light'] { - --hl-0: var(--light-hl-0); - --hl-1: var(--light-hl-1); - --hl-2: var(--light-hl-2); - --hl-3: var(--light-hl-3); - --hl-4: var(--light-hl-4); - --hl-5: var(--light-hl-5); - --hl-6: var(--light-hl-6); - --hl-7: var(--light-hl-7); - --hl-8: var(--light-hl-8); - --hl-9: var(--light-hl-9); - --code-background: var(--light-code-background); -} - -:root[data-theme='dark'] { - --hl-0: var(--dark-hl-0); - --hl-1: var(--dark-hl-1); - --hl-2: var(--dark-hl-2); - --hl-3: var(--dark-hl-3); - --hl-4: var(--dark-hl-4); - --hl-5: var(--dark-hl-5); - --hl-6: var(--dark-hl-6); - --hl-7: var(--dark-hl-7); - --hl-8: var(--dark-hl-8); - --hl-9: var(--dark-hl-9); - --code-background: var(--dark-code-background); -} - -.hl-0 { color: var(--hl-0); } -.hl-1 { color: var(--hl-1); } -.hl-2 { color: var(--hl-2); } -.hl-3 { color: var(--hl-3); } -.hl-4 { color: var(--hl-4); } -.hl-5 { color: var(--hl-5); } -.hl-6 { color: var(--hl-6); } -.hl-7 { color: var(--hl-7); } -.hl-8 { color: var(--hl-8); } -.hl-9 { color: var(--hl-9); } -pre, code { background: var(--code-background); } diff --git a/vet/lib/assets/icons.js b/vet/lib/assets/icons.js deleted file mode 100644 index 58882d7..0000000 --- a/vet/lib/assets/icons.js +++ /dev/null @@ -1,18 +0,0 @@ -(function() { - addIcons(); - function addIcons() { - if (document.readyState === "loading") return document.addEventListener("DOMContentLoaded", addIcons); - const svg = document.body.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg")); - svg.innerHTML = `MMNEPVFCICPMFPCPTTAAATR`; - svg.style.display = "none"; - if (location.protocol === "file:") updateUseElements(); - } - - function updateUseElements() { - document.querySelectorAll("use").forEach(el => { - if (el.getAttribute("href").includes("#icon-")) { - el.setAttribute("href", el.getAttribute("href").replace(/.*#/, "#")); - } - }); - } -})() \ No newline at end of file diff --git a/vet/lib/assets/icons.svg b/vet/lib/assets/icons.svg deleted file mode 100644 index 50ad579..0000000 --- a/vet/lib/assets/icons.svg +++ /dev/null @@ -1 +0,0 @@ -MMNEPVFCICPMFPCPTTAAATR \ No newline at end of file diff --git a/vet/lib/assets/main.js b/vet/lib/assets/main.js deleted file mode 100644 index 2363f64..0000000 --- a/vet/lib/assets/main.js +++ /dev/null @@ -1,60 +0,0 @@ -"use strict"; -window.translations={"copy":"Copy","copied":"Copied!","normally_hidden":"This member is normally hidden due to your filter settings.","hierarchy_expand":"Expand","hierarchy_collapse":"Collapse","folder":"Folder","kind_1":"Project","kind_2":"Module","kind_4":"Namespace","kind_8":"Enumeration","kind_16":"Enumeration Member","kind_32":"Variable","kind_64":"Function","kind_128":"Class","kind_256":"Interface","kind_512":"Constructor","kind_1024":"Property","kind_2048":"Method","kind_4096":"Call Signature","kind_8192":"Index Signature","kind_16384":"Constructor Signature","kind_32768":"Parameter","kind_65536":"Type Literal","kind_131072":"Type Parameter","kind_262144":"Accessor","kind_524288":"Get Signature","kind_1048576":"Set Signature","kind_2097152":"Type Alias","kind_4194304":"Reference","kind_8388608":"Document"}; -"use strict";(()=>{var De=Object.create;var le=Object.defineProperty;var Fe=Object.getOwnPropertyDescriptor;var Ne=Object.getOwnPropertyNames;var Ve=Object.getPrototypeOf,Be=Object.prototype.hasOwnProperty;var qe=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var je=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Ne(e))!Be.call(t,i)&&i!==n&&le(t,i,{get:()=>e[i],enumerable:!(r=Fe(e,i))||r.enumerable});return t};var $e=(t,e,n)=>(n=t!=null?De(Ve(t)):{},je(e||!t||!t.__esModule?le(n,"default",{value:t,enumerable:!0}):n,t));var pe=qe((de,he)=>{(function(){var t=function(e){var n=new t.Builder;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),n.searchPipeline.add(t.stemmer),e.call(n,n),n.build()};t.version="2.3.9";t.utils={},t.utils.warn=function(e){return function(n){e.console&&console.warn&&console.warn(n)}}(this),t.utils.asString=function(e){return e==null?"":e.toString()},t.utils.clone=function(e){if(e==null)return e;for(var n=Object.create(null),r=Object.keys(e),i=0;i0){var d=t.utils.clone(n)||{};d.position=[a,c],d.index=s.length,s.push(new t.Token(r.slice(a,o),d))}a=o+1}}return s},t.tokenizer.separator=/[\s\-]+/;t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions=Object.create(null),t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn(`Function is not registered with pipeline. This may cause problems when serialising the index. -`,e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(r){var i=t.Pipeline.registeredFunctions[r];if(i)n.add(i);else throw new Error("Cannot load unregistered function: "+r)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(n){t.Pipeline.warnIfFunctionNotRegistered(n),this._stack.push(n)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");r=r+1,this._stack.splice(r,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var r=this._stack.indexOf(e);if(r==-1)throw new Error("Cannot find existingFn");this._stack.splice(r,0,n)},t.Pipeline.prototype.remove=function(e){var n=this._stack.indexOf(e);n!=-1&&this._stack.splice(n,1)},t.Pipeline.prototype.run=function(e){for(var n=this._stack.length,r=0;r1&&(oe&&(r=s),o!=e);)i=r-n,s=n+Math.floor(i/2),o=this.elements[s*2];if(o==e||o>e)return s*2;if(ol?d+=2:a==l&&(n+=r[c+1]*i[d+1],c+=2,d+=2);return n},t.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},t.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),n=1,r=0;n0){var o=s.str.charAt(0),a;o in s.node.edges?a=s.node.edges[o]:(a=new t.TokenSet,s.node.edges[o]=a),s.str.length==1&&(a.final=!0),i.push({node:a,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(s.editsRemaining!=0){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new t.TokenSet;s.node.edges["*"]=l}if(s.str.length==0&&(l.final=!0),i.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&i.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),s.str.length==1&&(s.node.final=!0),s.str.length>=1){if("*"in s.node.edges)var c=s.node.edges["*"];else{var c=new t.TokenSet;s.node.edges["*"]=c}s.str.length==1&&(c.final=!0),i.push({node:c,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var d=s.str.charAt(0),m=s.str.charAt(1),p;m in s.node.edges?p=s.node.edges[m]:(p=new t.TokenSet,s.node.edges[m]=p),s.str.length==1&&(p.final=!0),i.push({node:p,editsRemaining:s.editsRemaining-1,str:d+s.str.slice(2)})}}}return r},t.TokenSet.fromString=function(e){for(var n=new t.TokenSet,r=n,i=0,s=e.length;i=e;n--){var r=this.uncheckedNodes[n],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r.char]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}};t.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},t.Index.prototype.search=function(e){return this.query(function(n){var r=new t.QueryParser(e,n);r.parse()})},t.Index.prototype.query=function(e){for(var n=new t.Query(this.fields),r=Object.create(null),i=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),l=0;l1?this._b=1:this._b=e},t.Builder.prototype.k1=function(e){this._k1=e},t.Builder.prototype.add=function(e,n){var r=e[this._ref],i=Object.keys(this._fields);this._documents[r]=n||{},this.documentCount+=1;for(var s=0;s=this.length)return t.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},t.QueryLexer.prototype.width=function(){return this.pos-this.start},t.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},t.QueryLexer.prototype.backup=function(){this.pos-=1},t.QueryLexer.prototype.acceptDigitRun=function(){var e,n;do e=this.next(),n=e.charCodeAt(0);while(n>47&&n<58);e!=t.QueryLexer.EOS&&this.backup()},t.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(t.QueryLexer.TERM)),e.ignore(),e.more())return t.QueryLexer.lexText},t.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.EDIT_DISTANCE),t.QueryLexer.lexText},t.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(t.QueryLexer.BOOST),t.QueryLexer.lexText},t.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(t.QueryLexer.TERM)},t.QueryLexer.termSeparator=t.tokenizer.separator,t.QueryLexer.lexText=function(e){for(;;){var n=e.next();if(n==t.QueryLexer.EOS)return t.QueryLexer.lexEOS;if(n.charCodeAt(0)==92){e.escapeCharacter();continue}if(n==":")return t.QueryLexer.lexField;if(n=="~")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexEditDistance;if(n=="^")return e.backup(),e.width()>0&&e.emit(t.QueryLexer.TERM),t.QueryLexer.lexBoost;if(n=="+"&&e.width()===1||n=="-"&&e.width()===1)return e.emit(t.QueryLexer.PRESENCE),t.QueryLexer.lexText;if(n.match(t.QueryLexer.termSeparator))return t.QueryLexer.lexTerm}},t.QueryParser=function(e,n){this.lexer=new t.QueryLexer(e),this.query=n,this.currentClause={},this.lexemeIdx=0},t.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=t.QueryParser.parseClause;e;)e=e(this);return this.query},t.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},t.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},t.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},t.QueryParser.parseClause=function(e){var n=e.peekLexeme();if(n!=null)switch(n.type){case t.QueryLexer.PRESENCE:return t.QueryParser.parsePresence;case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expected either a field or a term, found "+n.type;throw n.str.length>=1&&(r+=" with value '"+n.str+"'"),new t.QueryParseError(r,n.start,n.end)}},t.QueryParser.parsePresence=function(e){var n=e.consumeLexeme();if(n!=null){switch(n.str){case"-":e.currentClause.presence=t.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=t.Query.presence.REQUIRED;break;default:var r="unrecognised presence operator'"+n.str+"'";throw new t.QueryParseError(r,n.start,n.end)}var i=e.peekLexeme();if(i==null){var r="expecting term or field, found nothing";throw new t.QueryParseError(r,n.start,n.end)}switch(i.type){case t.QueryLexer.FIELD:return t.QueryParser.parseField;case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var r="expecting term or field, found '"+i.type+"'";throw new t.QueryParseError(r,i.start,i.end)}}},t.QueryParser.parseField=function(e){var n=e.consumeLexeme();if(n!=null){if(e.query.allFields.indexOf(n.str)==-1){var r=e.query.allFields.map(function(o){return"'"+o+"'"}).join(", "),i="unrecognised field '"+n.str+"', possible fields: "+r;throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.fields=[n.str];var s=e.peekLexeme();if(s==null){var i="expecting term, found nothing";throw new t.QueryParseError(i,n.start,n.end)}switch(s.type){case t.QueryLexer.TERM:return t.QueryParser.parseTerm;default:var i="expecting term, found '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseTerm=function(e){var n=e.consumeLexeme();if(n!=null){e.currentClause.term=n.str.toLowerCase(),n.str.indexOf("*")!=-1&&(e.currentClause.usePipeline=!1);var r=e.peekLexeme();if(r==null){e.nextClause();return}switch(r.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+r.type+"'";throw new t.QueryParseError(i,r.start,r.end)}}},t.QueryParser.parseEditDistance=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="edit distance must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.editDistance=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},t.QueryParser.parseBoost=function(e){var n=e.consumeLexeme();if(n!=null){var r=parseInt(n.str,10);if(isNaN(r)){var i="boost must be numeric";throw new t.QueryParseError(i,n.start,n.end)}e.currentClause.boost=r;var s=e.peekLexeme();if(s==null){e.nextClause();return}switch(s.type){case t.QueryLexer.TERM:return e.nextClause(),t.QueryParser.parseTerm;case t.QueryLexer.FIELD:return e.nextClause(),t.QueryParser.parseField;case t.QueryLexer.EDIT_DISTANCE:return t.QueryParser.parseEditDistance;case t.QueryLexer.BOOST:return t.QueryParser.parseBoost;case t.QueryLexer.PRESENCE:return e.nextClause(),t.QueryParser.parsePresence;default:var i="Unexpected lexeme type '"+s.type+"'";throw new t.QueryParseError(i,s.start,s.end)}}},function(e,n){typeof define=="function"&&define.amd?define(n):typeof de=="object"?he.exports=n():e.lunr=n()}(this,function(){return t})})()});window.translations||={copy:"Copy",copied:"Copied!",normally_hidden:"This member is normally hidden due to your filter settings.",hierarchy_expand:"Expand",hierarchy_collapse:"Collapse",folder:"Folder",kind_1:"Project",kind_2:"Module",kind_4:"Namespace",kind_8:"Enumeration",kind_16:"Enumeration Member",kind_32:"Variable",kind_64:"Function",kind_128:"Class",kind_256:"Interface",kind_512:"Constructor",kind_1024:"Property",kind_2048:"Method",kind_4096:"Call Signature",kind_8192:"Index Signature",kind_16384:"Constructor Signature",kind_32768:"Parameter",kind_65536:"Type Literal",kind_131072:"Type Parameter",kind_262144:"Accessor",kind_524288:"Get Signature",kind_1048576:"Set Signature",kind_2097152:"Type Alias",kind_4194304:"Reference",kind_8388608:"Document"};var ce=[];function G(t,e){ce.push({selector:e,constructor:t})}var J=class{alwaysVisibleMember=null;constructor(){this.createComponents(document.body),this.ensureFocusedElementVisible(),this.listenForCodeCopies(),window.addEventListener("hashchange",()=>this.ensureFocusedElementVisible()),document.body.style.display||(this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}createComponents(e){ce.forEach(n=>{e.querySelectorAll(n.selector).forEach(r=>{r.dataset.hasInstance||(new n.constructor({el:r,app:this}),r.dataset.hasInstance=String(!0))})})}filterChanged(){this.ensureFocusedElementVisible()}showPage(){document.body.style.display&&(document.body.style.removeProperty("display"),this.ensureFocusedElementVisible(),this.updateIndexVisibility(),this.scrollToHash())}scrollToHash(){if(location.hash){let e=document.getElementById(location.hash.substring(1));if(!e)return;e.scrollIntoView({behavior:"instant",block:"start"})}}ensureActivePageVisible(){let e=document.querySelector(".tsd-navigation .current"),n=e?.parentElement;for(;n&&!n.classList.contains(".tsd-navigation");)n instanceof HTMLDetailsElement&&(n.open=!0),n=n.parentElement;if(e&&!ze(e)){let r=e.getBoundingClientRect().top-document.documentElement.clientHeight/4;document.querySelector(".site-menu").scrollTop=r,document.querySelector(".col-sidebar").scrollTop=r}}updateIndexVisibility(){let e=document.querySelector(".tsd-index-content"),n=e?.open;e&&(e.open=!0),document.querySelectorAll(".tsd-index-section").forEach(r=>{r.style.display="block";let i=Array.from(r.querySelectorAll(".tsd-index-link")).every(s=>s.offsetParent==null);r.style.display=i?"none":"block"}),e&&(e.open=n)}ensureFocusedElementVisible(){if(this.alwaysVisibleMember&&(this.alwaysVisibleMember.classList.remove("always-visible"),this.alwaysVisibleMember.firstElementChild.remove(),this.alwaysVisibleMember=null),!location.hash)return;let e=document.getElementById(location.hash.substring(1));if(!e)return;let n=e.parentElement;for(;n&&n.tagName!=="SECTION";)n=n.parentElement;if(!n)return;let r=n.offsetParent==null,i=n;for(;i!==document.body;)i instanceof HTMLDetailsElement&&(i.open=!0),i=i.parentElement;if(n.offsetParent==null){this.alwaysVisibleMember=n,n.classList.add("always-visible");let s=document.createElement("p");s.classList.add("warning"),s.textContent=window.translations.normally_hidden,n.prepend(s)}r&&e.scrollIntoView()}listenForCodeCopies(){document.querySelectorAll("pre > button").forEach(e=>{let n;e.addEventListener("click",()=>{e.previousElementSibling instanceof HTMLElement&&navigator.clipboard.writeText(e.previousElementSibling.innerText.trim()),e.textContent=window.translations.copied,e.classList.add("visible"),clearTimeout(n),n=setTimeout(()=>{e.classList.remove("visible"),n=setTimeout(()=>{e.textContent=window.translations.copy},100)},1e3)})})}};function ze(t){let e=t.getBoundingClientRect(),n=Math.max(document.documentElement.clientHeight,window.innerHeight);return!(e.bottom<0||e.top-n>=0)}var ue=(t,e=100)=>{let n;return()=>{clearTimeout(n),n=setTimeout(()=>t(),e)}};var ge=$e(pe(),1);async function A(t){let e=Uint8Array.from(atob(t),s=>s.charCodeAt(0)),r=new Blob([e]).stream().pipeThrough(new DecompressionStream("deflate")),i=await new Response(r).text();return JSON.parse(i)}async function fe(t,e){if(!window.searchData)return;let n=await A(window.searchData);t.data=n,t.index=ge.Index.load(n.index),e.classList.remove("loading"),e.classList.add("ready")}function ve(){let t=document.getElementById("tsd-search");if(!t)return;let e={base:document.documentElement.dataset.base+"/"},n=document.getElementById("tsd-search-script");t.classList.add("loading"),n&&(n.addEventListener("error",()=>{t.classList.remove("loading"),t.classList.add("failure")}),n.addEventListener("load",()=>{fe(e,t)}),fe(e,t));let r=document.querySelector("#tsd-search input"),i=document.querySelector("#tsd-search .results");if(!r||!i)throw new Error("The input field or the result list wrapper was not found");i.addEventListener("mouseup",()=>{re(t)}),r.addEventListener("focus",()=>t.classList.add("has-focus")),We(t,i,r,e)}function We(t,e,n,r){n.addEventListener("input",ue(()=>{Ue(t,e,n,r)},200)),n.addEventListener("keydown",i=>{i.key=="Enter"?Je(e,t):i.key=="ArrowUp"?(me(e,n,-1),i.preventDefault()):i.key==="ArrowDown"&&(me(e,n,1),i.preventDefault())}),document.body.addEventListener("keypress",i=>{i.altKey||i.ctrlKey||i.metaKey||!n.matches(":focus")&&i.key==="/"&&(i.preventDefault(),n.focus())}),document.body.addEventListener("keyup",i=>{t.classList.contains("has-focus")&&(i.key==="Escape"||!e.matches(":focus-within")&&!n.matches(":focus"))&&(n.blur(),re(t))})}function re(t){t.classList.remove("has-focus")}function Ue(t,e,n,r){if(!r.index||!r.data)return;e.textContent="";let i=n.value.trim(),s;if(i){let o=i.split(" ").map(a=>a.length?`*${a}*`:"").join(" ");s=r.index.search(o)}else s=[];for(let o=0;oa.score-o.score);for(let o=0,a=Math.min(10,s.length);o`,d=ye(l.name,i);globalThis.DEBUG_SEARCH_WEIGHTS&&(d+=` (score: ${s[o].score.toFixed(2)})`),l.parent&&(d=` - ${ye(l.parent,i)}.${d}`);let m=document.createElement("li");m.classList.value=l.classes??"";let p=document.createElement("a");p.href=r.base+l.url,p.innerHTML=c+d,m.append(p),p.addEventListener("focus",()=>{e.querySelector(".current")?.classList.remove("current"),m.classList.add("current")}),e.appendChild(m)}}function me(t,e,n){let r=t.querySelector(".current");if(!r)r=t.querySelector(n==1?"li:first-child":"li:last-child"),r&&r.classList.add("current");else{let i=r;if(n===1)do i=i.nextElementSibling??void 0;while(i instanceof HTMLElement&&i.offsetParent==null);else do i=i.previousElementSibling??void 0;while(i instanceof HTMLElement&&i.offsetParent==null);i?(r.classList.remove("current"),i.classList.add("current")):n===-1&&(r.classList.remove("current"),e.focus())}}function Je(t,e){let n=t.querySelector(".current");if(n||(n=t.querySelector("li:first-child")),n){let r=n.querySelector("a");r&&(window.location.href=r.href),re(e)}}function ye(t,e){if(e==="")return t;let n=t.toLocaleLowerCase(),r=e.toLocaleLowerCase(),i=[],s=0,o=n.indexOf(r);for(;o!=-1;)i.push(ne(t.substring(s,o)),`${ne(t.substring(o,o+r.length))}`),s=o+r.length,o=n.indexOf(r,s);return i.push(ne(t.substring(s))),i.join("")}var Ge={"&":"&","<":"<",">":">","'":"'",'"':"""};function ne(t){return t.replace(/[&<>"'"]/g,e=>Ge[e])}var I=class{el;app;constructor(e){this.el=e.el,this.app=e.app}};var H="mousedown",Ee="mousemove",B="mouseup",X={x:0,y:0},xe=!1,ie=!1,Xe=!1,D=!1,be=/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);document.documentElement.classList.add(be?"is-mobile":"not-mobile");be&&"ontouchstart"in document.documentElement&&(Xe=!0,H="touchstart",Ee="touchmove",B="touchend");document.addEventListener(H,t=>{ie=!0,D=!1;let e=H=="touchstart"?t.targetTouches[0]:t;X.y=e.pageY||0,X.x=e.pageX||0});document.addEventListener(Ee,t=>{if(ie&&!D){let e=H=="touchstart"?t.targetTouches[0]:t,n=X.x-(e.pageX||0),r=X.y-(e.pageY||0);D=Math.sqrt(n*n+r*r)>10}});document.addEventListener(B,()=>{ie=!1});document.addEventListener("click",t=>{xe&&(t.preventDefault(),t.stopImmediatePropagation(),xe=!1)});var Y=class extends I{active;className;constructor(e){super(e),this.className=this.el.dataset.toggle||"",this.el.addEventListener(B,n=>this.onPointerUp(n)),this.el.addEventListener("click",n=>n.preventDefault()),document.addEventListener(H,n=>this.onDocumentPointerDown(n)),document.addEventListener(B,n=>this.onDocumentPointerUp(n))}setActive(e){if(this.active==e)return;this.active=e,document.documentElement.classList.toggle("has-"+this.className,e),this.el.classList.toggle("active",e);let n=(this.active?"to-has-":"from-has-")+this.className;document.documentElement.classList.add(n),setTimeout(()=>document.documentElement.classList.remove(n),500)}onPointerUp(e){D||(this.setActive(!0),e.preventDefault())}onDocumentPointerDown(e){if(this.active){if(e.target.closest(".col-sidebar, .tsd-filter-group"))return;this.setActive(!1)}}onDocumentPointerUp(e){if(!D&&this.active&&e.target.closest(".col-sidebar")){let n=e.target.closest("a");if(n){let r=window.location.href;r.indexOf("#")!=-1&&(r=r.substring(0,r.indexOf("#"))),n.href.substring(0,r.length)==r&&setTimeout(()=>this.setActive(!1),250)}}}};var se;try{se=localStorage}catch{se={getItem(){return null},setItem(){}}}var C=se;var Le=document.head.appendChild(document.createElement("style"));Le.dataset.for="filters";var Z=class extends I{key;value;constructor(e){super(e),this.key=`filter-${this.el.name}`,this.value=this.el.checked,this.el.addEventListener("change",()=>{this.setLocalStorage(this.el.checked)}),this.setLocalStorage(this.fromLocalStorage()),Le.innerHTML+=`html:not(.${this.key}) .tsd-is-${this.el.name} { display: none; } -`,this.app.updateIndexVisibility()}fromLocalStorage(){let e=C.getItem(this.key);return e?e==="true":this.el.checked}setLocalStorage(e){C.setItem(this.key,e.toString()),this.value=e,this.handleValueChange()}handleValueChange(){this.el.checked=this.value,document.documentElement.classList.toggle(this.key,this.value),this.app.filterChanged(),this.app.updateIndexVisibility()}};var oe=new Map,ae=class{open;accordions=[];key;constructor(e,n){this.key=e,this.open=n}add(e){this.accordions.push(e),e.open=this.open,e.addEventListener("toggle",()=>{this.toggle(e.open)})}toggle(e){for(let n of this.accordions)n.open=e;C.setItem(this.key,e.toString())}},K=class extends I{constructor(e){super(e);let n=this.el.querySelector("summary"),r=n.querySelector("a");r&&r.addEventListener("click",()=>{location.assign(r.href)});let i=`tsd-accordion-${n.dataset.key??n.textContent.trim().replace(/\s+/g,"-").toLowerCase()}`,s;if(oe.has(i))s=oe.get(i);else{let o=C.getItem(i),a=o?o==="true":this.el.open;s=new ae(i,a),oe.set(i,s)}s.add(this.el)}};function Se(t){let e=C.getItem("tsd-theme")||"os";t.value=e,we(e),t.addEventListener("change",()=>{C.setItem("tsd-theme",t.value),we(t.value)})}function we(t){document.documentElement.dataset.theme=t}var ee;function Ce(){let t=document.getElementById("tsd-nav-script");t&&(t.addEventListener("load",Te),Te())}async function Te(){let t=document.getElementById("tsd-nav-container");if(!t||!window.navigationData)return;let e=await A(window.navigationData);ee=document.documentElement.dataset.base,ee.endsWith("/")||(ee+="/"),t.innerHTML="";for(let n of e)Ie(n,t,[]);window.app.createComponents(t),window.app.showPage(),window.app.ensureActivePageVisible()}function Ie(t,e,n){let r=e.appendChild(document.createElement("li"));if(t.children){let i=[...n,t.text],s=r.appendChild(document.createElement("details"));s.className=t.class?`${t.class} tsd-accordion`:"tsd-accordion";let o=s.appendChild(document.createElement("summary"));o.className="tsd-accordion-summary",o.dataset.key=i.join("$"),o.innerHTML='',ke(t,o);let a=s.appendChild(document.createElement("div"));a.className="tsd-accordion-details";let l=a.appendChild(document.createElement("ul"));l.className="tsd-nested-navigation";for(let c of t.children)Ie(c,l,i)}else ke(t,r,t.class)}function ke(t,e,n){if(t.path){let r=e.appendChild(document.createElement("a"));if(r.href=ee+t.path,n&&(r.className=n),location.pathname===r.pathname&&!r.href.includes("#")&&r.classList.add("current"),t.kind){let i=window.translations[`kind_${t.kind}`].replaceAll('"',""");r.innerHTML=``}r.appendChild(document.createElement("span")).textContent=t.text}else{let r=e.appendChild(document.createElement("span")),i=window.translations.folder.replaceAll('"',""");r.innerHTML=``,r.appendChild(document.createElement("span")).textContent=t.text}}var te=document.documentElement.dataset.base;te.endsWith("/")||(te+="/");function Pe(){document.querySelector(".tsd-full-hierarchy")?Ye():document.querySelector(".tsd-hierarchy")&&Ze()}function Ye(){document.addEventListener("click",r=>{let i=r.target;for(;i.parentElement&&i.parentElement.tagName!="LI";)i=i.parentElement;i.dataset.dropdown&&(i.dataset.dropdown=String(i.dataset.dropdown!=="true"))});let t=new Map,e=new Set;for(let r of document.querySelectorAll(".tsd-full-hierarchy [data-refl]")){let i=r.querySelector("ul");t.has(r.dataset.refl)?e.add(r.dataset.refl):i&&t.set(r.dataset.refl,i)}for(let r of e)n(r);function n(r){let i=t.get(r).cloneNode(!0);i.querySelectorAll("[id]").forEach(s=>{s.removeAttribute("id")}),i.querySelectorAll("[data-dropdown]").forEach(s=>{s.dataset.dropdown="false"});for(let s of document.querySelectorAll(`[data-refl="${r}"]`)){let o=tt(),a=s.querySelector("ul");s.insertBefore(o,a),o.dataset.dropdown=String(!!a),a||s.appendChild(i.cloneNode(!0))}}}function Ze(){let t=document.getElementById("tsd-hierarchy-script");t&&(t.addEventListener("load",Qe),Qe())}async function Qe(){let t=document.querySelector(".tsd-panel.tsd-hierarchy:has(h4 a)");if(!t||!window.hierarchyData)return;let e=+t.dataset.refl,n=await A(window.hierarchyData),r=t.querySelector("ul"),i=document.createElement("ul");if(i.classList.add("tsd-hierarchy"),Ke(i,n,e),r.querySelectorAll("li").length==i.querySelectorAll("li").length)return;let s=document.createElement("span");s.classList.add("tsd-hierarchy-toggle"),s.textContent=window.translations.hierarchy_expand,t.querySelector("h4 a")?.insertAdjacentElement("afterend",s),s.insertAdjacentText("beforebegin",", "),s.addEventListener("click",()=>{s.textContent===window.translations.hierarchy_expand?(r.insertAdjacentElement("afterend",i),r.remove(),s.textContent=window.translations.hierarchy_collapse):(i.insertAdjacentElement("afterend",r),i.remove(),s.textContent=window.translations.hierarchy_expand)})}function Ke(t,e,n){let r=e.roots.filter(i=>et(e,i,n));for(let i of r)t.appendChild(_e(e,i,n))}function _e(t,e,n,r=new Set){if(r.has(e))return;r.add(e);let i=t.reflections[e],s=document.createElement("li");if(s.classList.add("tsd-hierarchy-item"),e===n){let o=s.appendChild(document.createElement("span"));o.textContent=i.name,o.classList.add("tsd-hierarchy-target")}else{for(let a of i.uniqueNameParents||[]){let l=t.reflections[a],c=s.appendChild(document.createElement("a"));c.textContent=l.name,c.href=te+l.url,c.className=l.class+" tsd-signature-type",s.append(document.createTextNode("."))}let o=s.appendChild(document.createElement("a"));o.textContent=t.reflections[e].name,o.href=te+i.url,o.className=i.class+" tsd-signature-type"}if(i.children){let o=s.appendChild(document.createElement("ul"));o.classList.add("tsd-hierarchy");for(let a of i.children){let l=_e(t,a,n,r);l&&o.appendChild(l)}}return r.delete(e),s}function et(t,e,n){if(e===n)return!0;let r=new Set,i=[t.reflections[e]];for(;i.length;){let s=i.pop();if(!r.has(s)){r.add(s);for(let o of s.children||[]){if(o===n)return!0;i.push(t.reflections[o])}}}return!1}function tt(){let t=document.createElementNS("http://www.w3.org/2000/svg","svg");return t.setAttribute("width","20"),t.setAttribute("height","20"),t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","none"),t.innerHTML='',t}G(Y,"a[data-toggle]");G(K,".tsd-accordion");G(Z,".tsd-filter-item input[type=checkbox]");var Oe=document.getElementById("tsd-theme");Oe&&Se(Oe);var nt=new J;Object.defineProperty(window,"app",{value:nt});ve();Ce();Pe();})(); -/*! Bundled license information: - -lunr/lunr.js: - (** - * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 - * Copyright (C) 2020 Oliver Nightingale - * @license MIT - *) - (*! - * lunr.utils - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Set - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.tokenizer - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Pipeline - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Vector - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.stemmer - * Copyright (C) 2020 Oliver Nightingale - * Includes code from - http://tartarus.org/~martin/PorterStemmer/js.txt - *) - (*! - * lunr.stopWordFilter - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.trimmer - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.TokenSet - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Index - * Copyright (C) 2020 Oliver Nightingale - *) - (*! - * lunr.Builder - * Copyright (C) 2020 Oliver Nightingale - *) -*/ diff --git a/vet/lib/assets/navigation.js b/vet/lib/assets/navigation.js deleted file mode 100644 index dcfab1e..0000000 --- a/vet/lib/assets/navigation.js +++ /dev/null @@ -1 +0,0 @@ -window.navigationData = "eJytlk1v2zAMhv+Lz8k+urXDchvSDtuhwID2VhSBItO2EFsSZDlbN/S/T/6ILTuSwjg9JuT7kK+oUHn6F2n4o6NVVCoaLSKasTxWwKPVUx/5LoQGZYKS6Mx8LkRc5VC+N4pNG3uX6SI3CTvG42h15cbEkJAq1wMnqTjVTPARqcsaE28+vz6/LnrSDyCxr6E29hYNdSRUQ6IATzsm8ibN1BxMKwVh3N1KHZm0YumEBE4kW1LBE5a6CeMclK1SAl036ZUitZ2BvCeKka2HfaQbV/t0NTJdZkRBvNQZNHNwNfJNyscu7HBmAzaHVJTBtciFuhexBdYvMojtJZMCH75++Xhtz6RPNCfRfOU5uxNlOvXRCS6wl8/Nx9xGWpVaFOxvM8LSM5qYaHLLSpmTF8R0xsiNJcb9zob89bS504cbKO4FB29uAhBvCd2db/ygRLk+JF9uuS/rRgbNMi4rXZ5vtdWhjLapl9vsSrpwQYuc7Fk6WXRYm4MWZXVIv9yuVdqHDS/gSiWEwozZHpS416RLvtxwX9aNdJi17TbIdeClHJW2slEuH6AgXDPaLHDLHTNrvG02XGOsn5S8vrF8jDJRj5i3DuY9S0H7vAUeHLvkESH4+jTKX4oVTLM96nJOFKhxbRUxUcwdnNIbZeBZprXFB1qrcJd8WsAGBOqkyn55z+DXwiAXwPuH7wTYKANkYU4uhVnoVhpgG+kssIkEqEYai9/zxthpw3Q57zgaZYBs9oAwY5bZvBsyyEP3BPQtlCzlj2IH/IytYN+YMcOxF+zNsGcalsD37pVwiKJ+/j8LKZS+B028m7rnDbmhrTxk3dkdnobeHbVsuLXx5/9Q6bPL" \ No newline at end of file diff --git a/vet/lib/assets/search.js b/vet/lib/assets/search.js deleted file mode 100644 index 150c60f..0000000 --- a/vet/lib/assets/search.js +++ /dev/null @@ -1 +0,0 @@ -window.searchData = "eJzNndtu28YWht9FuVUdcs6TuzZN0QC7QNGmvTECg5ZoW4gtCZLs3e4g77455Ehcaw7iiAcjN7Fjav3zc/GbWcMhKX6d7Tb/3c/eXX+dfVmtl7N3ZD5bF0/l7N1sv1u8/WWzOZS72Xz2vHus/vS0WT4/lvu31aabZtPVw+Hpsdq+eCz2+7ISms2+zY9agp3EluVd8fx4OCndPa8Xh9VmjbTshwKa89m22JXrA7bVtoRd/1oWy4jrZtM4rq1WsmtrK+p6U/0a9FxtGMmxUUr3awzF3D4Vq3XQrdlw1i3W2WzLdbFd/bDYrO9W90FF/JGz2hSIb8vF+zrieVeYFJy0X4rdqriNqHth3XlydiG2p/uHKmj5w+GhfCrf/rjdfjK/BHcYfvLm+MnzOc20zHnb3vvN42b322bZ6h/+3Z5VP0V07294R4IH4aRapfRQ/nOIHIMOSzZ4uLPkjhI2lNxzunycAWPxvD9snlb/Kxozy+JQ/Lzabx+Lf7tRwbE3IDa104CQ90gs5cCdaT6qe2Euz2SnT3bvynJ5Wyy+XJzaY2BqXo+fH5zUU8NhxWHpPKWjTy5X6+3zYX9xJpuw1Dw2nx6cRdtoSG1YBm0S+uRvXbys7nGhSs1hG5qaxzZicC5B4zHVYTkFiemT1/3z7q5YlJeTeQxMnnDYzw/O6KnhsOKwbJ7SkZTL+t/38akZ2g3w4dTp6n15+LN8KtaH1aKu9vuUegzb8QQuzA7cwfh0CjWRMq2CFr3gcSxyEbbXpnBVzZqag32BwXESmGeEuR1jDF9vWq3L/TmCMbu3mx08exzi9iQ1mVk0qR5i1QqNabRrXPl9t3paHVYvKWOzE5A6Jt/uiuovCUOwq18H9ukKYKcih4xnwwy9ubkxo04t08+ZFWt0YjbzbByfjc6ERslIRsnURulIRunURtlIRtnURvlIRvnURsVIRsXURuVIRuXURtVIRtXURvVIRvUERkGlvN+BFaYLfJq476lOnvyMUCZrrUmqpOtyUJFMsNmzRro2B5XIBJs9K6Rrc1CBTLDZsz66NgeVxwSbPauj34OmtdmzNro2B5XGBJs9K6Nrc1BhTLE5zrApJx43e5Zv1+ag6p1ic5xsqomz2XOO4docNMUI20QzjLKMXYTtsFkFfl9zjKOhUSYZRmyiWYbjc+A0o9to73mGY3TgRKPbaO+ZhmN04FSj22jvuYZjdOBko9to79mG15cmNtp7vuEYHTjh6Dbae8bhGB045eg22ruYO0YHVvNuo73rpGN0YKEMGgWVclOdrd+XfZw2kd9TrQSORiiWVm2Sauk7HVQuk6z2rJe+1UEFM8lqz4rpWx1UMpOs9qyZvtVBRTPJas+qGepVU1vtWTd9q4MKZ5LVnpXTtzqodCZZ7Vk7fauDimeS1Z7V07c6qHzGrIL6WQX3MVpt+Z4q59HOCGXTSE1SMx2Pgwpmt8me1dIxOahUdpvsWScdk4OKZLfJnhXSMTmoPHab7FkbvX4zqcmeVdExOagkdpvsWQ8dk4OKYbfJnpXQMTmoDHab7FkDHZODCmDQJL6n8udyv7pff9p8Kdfpd1TCU1QsMVpVBDV6Ye4W+3NhPpp0j6xrEcZPU7UfV/cPSQ+sdFqzR/0o2PO4I9nzlC6L3ZcxnVu9SYwDJqotm/tdsX3odSdCGz0ND3eb9eGX4mn1OIY7m1ijeXfU7JleoHyeiod8POO11uSGyYiGyWsYpiMapq9hmI1omL2GYT6iYf4ahsWIhsUrGN4/3x5Wh8dyxMECSr6W/RGHDig5tf3bzfLfETN/lHsN2yNm/Cg3te1FsT3zZHgP463gBNbhs2YPxbbXBaI6cJr5UfOwyx/FcvXca0bfWjtRYAR3R8GeGW1kO5K5NF+C0c+zCR0tofiRmZfVofyhXL+cnMHHY44bz38vAHhK7OPTdrM7/FYeipOe88DQSbL9aPeenUxGsID+E9t708R0twkCO3f6w0U+PgQTe+Gu//3x04ebH3//ePPTj39+uPnrj//0MPDGbLsptqub22Jf3pjwCzPzocvgX59+HcHh8+FhmMXP86rRZfnP7N3X2Uu525tx9N2MXNErXUncrcrHpfmimsZ71cDm6cmIzmfLzeK5/vWz/djf5eJgHkV7d918+m02m19nc8aulOSfP8+vj8H1hvoPR432L3VgVTuv8zmlVzxnKDD3AnMUWFWvaxJqkXiBBAXSWIvUC6QosJp9X9NQi8wLZCiQx1rkXiBHgdVs9JqFWhReoECBsvofn9Pq0GZ6LuwvSEF6ChIpqOp/MtS08gIVCqxQulbzXF9RzeY61LT2FDRGwhCSB2nKfZxyh6caqDwYHEAKM5WTKI0+VTnGKqdwx3MS2vPcRyzHjOWGnDxIWe5jlmPOco4ssKAFn7kcQ5cblHIetOBzl2PwcoksBNHLffZyDF9ukMqD+OU+fzkGMEcE5ipowWcwxxCSGkIdHGB8CAmGkOTQAslCFohPI3FGuHqIC6JMAoMcxpEgHEkQR+LjSDCOxABGgjgSH0eCcSSGKxIcv4hPIcEUEsMVCVJIfAoJppAYnIgIBvvwEQwfMTiRIHzEh49g+IihiKhgsM8cwczRDB2z4OBJffgoho8aimhw+KQ+cxQzRw1FtBoC8ytGnZZ95qhTWQ081bQ/FBworhg1WpdXGgz2UaMYNWrgoSwY7KNGMWrUwEN5MNhHjWLUqIGHimCwjxrFqFEDD5XBYB81ilGjBh6qgsE+ahSjxgwzVIeCmU8Yw4QxwwzLgsE+YQwTxgwzLDiqMZ8whgljNIon8wljzvyNRfFkgSkcJozxKJ7MJ4xhwpiI4sl8whgmjMkonswnjGHCmIriyXzCGCaM6SiezCeMYcJ4FsWT+4RxTBivCQtO77lPGMeEcRJlm/uEcUwYN8ywYMXjPmEcE8ZZtGNwnzDunCUYZliwXPLAiQImjItox+A+YRwTxmW0Y3CfMI4J4yraMbhPGMeEcR3tGNwnjGPCRBbtGMInTGDCRB7tGMInTGDCBIl2DOETJjBhgkY7hvAJE5gwwaJsC58wgQkTPIqn8AkTzrlofTIanJCJwOkoJkzIKJ7CJ0xgwoSK4il8wgQmTOgonsInTGDCZBbFU/qESUyYzKN4Sp8wiQmTJIqn9AmTmDBJo3hKnzCJCZMsiqf0CZOYMMmjeEqfMIkJkyKKp/QJk86Kh2GGBaf8MrDWgQmTKoqn9AmTmDCpo3hKnzCJCVNZFE/lE6YwYSqP4ql8whQmTJEonsonTGHCFI3iqXzCFCZMsSieyidMYcIUj+KpfMIUJkyJKJ7KJ0xhwpSM4ql8wpSznGaYYeEFtcCKGiZMGWZY8KRS+YQpTJg2zLDgQob2CdOYMG2Y4cFzSe0TpjFh2jDDgzN97ROmMWHaMMODM0DtE6YxYdoww4OTOO0TpjFh2jDDg/Mw7ROmMWHaMMODVVL7hGlMmK6XbYNjmPYJ05gwbZjhQcK0T5h2Fm0NMzxImA4s17rrtQYaHkSs2YbDwd9svOFGRBZ8A4u2mbNqmxl0RHjNNwss3GbOym1m6BFB1pptbryzZpsZgER40TYLrNpmzrJtZhgSQeKabW68s2CbGYxEeMU2CyzZZs6abWZIEkHumm1uvLNamxmYhDxdb1Bzoq54JhylwMpt5izdZoYsESEpsGabOSTWFwOq9qm+4pri+NC1A+/igSFLhkkMXj5wSKyvCcjI1YcAie41hPpqgAyTGLp4YP9WX9h7KXeHcvmxucB3fd08cPJ1dmMv+bWX47/OKK3+/TafMdb8rE7p6p/V3Ln+WU1Sqp/f2kuA9V9PVwHNNuODOC1Q0IJVZty2YJWFbn5WM5mUFqjTAgMtWGUmbAtWWWa2hTypBea0wEELVpkds2OVZW5bIEktcNxADhogtgF7OLhtUNgGpUpsALcgQAtWiR3Tb61L27KiSS0IpwUJWrDKzKZfWGVp90mxpBak04ICLVhlbtMvrLK0iCme1gI+Dgx0B56GinI86laBWW/c7r2w3qSFVIm0FhyPoEPxtCOlscdqutp6tMeeW2/CepOWOiWTWrA3vLVtCEC0Ka2pIgSJECiStq/H7/5tVQgAk6R1HnwLFDDEoaG0w2e/CxcgAtJP0yA73d8GrFBoJa0/1U8EPNXfo90K5RkUukxncXy9CJCDBz5x7+pvMD4+kwI4Bf1dpRWf4+tsQJ5ajTSUm4cuWgEO8qPTdsi8H2PZvB9j4XwrPUgUPIBpx+/08hSgAkSaqGPZaH7kaV2vvvMLJE1BJuxgnifScXydxZldh90orRfBJzbAsQEDhE4bH+7Lw7J+xupgH9MCvIGBQqUNFJXa3n4P98J+CzwYeMARJmlHuPk6UGAJHF+Wdijt930BDTA/4mll8QGN5Rzsh07bjwc0jnPgQCc6oEgAAKPTgDGPRQABMAzotHHAPKYABAAbOo0N89gAEABdSqcNZqv6Rr2n+s5R0Dc17JuXKjkdXcLBP3G4bl62cqZ3g1Tlaamyj+gBZsFO6rRhp31fyRlrQJakyR6/FAh4AzCKNBjrb0YACrAopdGIRhm3hBPQv0ha/zozaoHdI2m7d7qTG1AqIKWJ+9jcXQ9EGBRJ3LFtuVjg988B3MEAn6a2W7y9sy9jbGVAp0mDyMg82LcjgkyDRKfL1K8rBLNJUCCSRZq3CAIgAdHJIvb9e2iQu3Sy1d6jD2XgUGnnHnZWkx+nNfYUNrfbiZ38EPs5mn5czH3RCDrpzX26ddonrUAy0ECdaKh95gk4QjP0tEH69MIWgBvokiTx8Ni3FsVHVAImKCSNYveMgYDDTdLqWfM8R7Hd1r9AMe2gkygVeMHd8vj6P1A+4Plo2nQzKN++/w5ow7EubagLah/fBweU4VCcdtyDyvBNaUAdnioMSHn7vjBABgCfpHEPnvTxzwUJHHEvOX71v9v2ySGoCYhLHHXg8/ZguAA9Saf1pMAzKqDWoRPxSwTxIyVAEeKfwv/n+Wy7Ml/AsK5irj9/+/Z/9j82Ag=="; \ No newline at end of file diff --git a/vet/lib/assets/style.css b/vet/lib/assets/style.css deleted file mode 100644 index 2ab8b83..0000000 --- a/vet/lib/assets/style.css +++ /dev/null @@ -1,1611 +0,0 @@ -@layer typedoc { - :root { - /* Light */ - --light-color-background: #f2f4f8; - --light-color-background-secondary: #eff0f1; - --light-color-warning-text: #222; - --light-color-background-warning: #e6e600; - --light-color-accent: #c5c7c9; - --light-color-active-menu-item: var(--light-color-accent); - --light-color-text: #222; - --light-color-text-aside: #6e6e6e; - - --light-color-icon-background: var(--light-color-background); - --light-color-icon-text: var(--light-color-text); - - --light-color-comment-tag-text: var(--light-color-text); - --light-color-comment-tag: var(--light-color-background); - - --light-color-link: #1f70c2; - --light-color-focus-outline: #3584e4; - - --light-color-ts-keyword: #056bd6; - --light-color-ts-project: #b111c9; - --light-color-ts-module: var(--light-color-ts-project); - --light-color-ts-namespace: var(--light-color-ts-project); - --light-color-ts-enum: #7e6f15; - --light-color-ts-enum-member: var(--light-color-ts-enum); - --light-color-ts-variable: #4760ec; - --light-color-ts-function: #572be7; - --light-color-ts-class: #1f70c2; - --light-color-ts-interface: #108024; - --light-color-ts-constructor: var(--light-color-ts-class); - --light-color-ts-property: #9f5f30; - --light-color-ts-method: #be3989; - --light-color-ts-reference: #ff4d82; - --light-color-ts-call-signature: var(--light-color-ts-method); - --light-color-ts-index-signature: var(--light-color-ts-property); - --light-color-ts-constructor-signature: var( - --light-color-ts-constructor - ); - --light-color-ts-parameter: var(--light-color-ts-variable); - /* type literal not included as links will never be generated to it */ - --light-color-ts-type-parameter: #a55c0e; - --light-color-ts-accessor: #c73c3c; - --light-color-ts-get-signature: var(--light-color-ts-accessor); - --light-color-ts-set-signature: var(--light-color-ts-accessor); - --light-color-ts-type-alias: #d51270; - /* reference not included as links will be colored with the kind that it points to */ - --light-color-document: #000000; - - --light-color-alert-note: #0969d9; - --light-color-alert-tip: #1a7f37; - --light-color-alert-important: #8250df; - --light-color-alert-warning: #9a6700; - --light-color-alert-caution: #cf222e; - - --light-external-icon: url("data:image/svg+xml;utf8,"); - --light-color-scheme: light; - - /* Dark */ - --dark-color-background: #2b2e33; - --dark-color-background-secondary: #1e2024; - --dark-color-background-warning: #bebe00; - --dark-color-warning-text: #222; - --dark-color-accent: #9096a2; - --dark-color-active-menu-item: #5d5d6a; - --dark-color-text: #f5f5f5; - --dark-color-text-aside: #dddddd; - - --dark-color-icon-background: var(--dark-color-background-secondary); - --dark-color-icon-text: var(--dark-color-text); - - --dark-color-comment-tag-text: var(--dark-color-text); - --dark-color-comment-tag: var(--dark-color-background); - - --dark-color-link: #00aff4; - --dark-color-focus-outline: #4c97f2; - - --dark-color-ts-keyword: #3399ff; - --dark-color-ts-project: #e358ff; - --dark-color-ts-module: var(--dark-color-ts-project); - --dark-color-ts-namespace: var(--dark-color-ts-project); - --dark-color-ts-enum: #f4d93e; - --dark-color-ts-enum-member: var(--dark-color-ts-enum); - --dark-color-ts-variable: #798dff; - --dark-color-ts-function: #a280ff; - --dark-color-ts-class: #8ac4ff; - --dark-color-ts-interface: #6cff87; - --dark-color-ts-constructor: var(--dark-color-ts-class); - --dark-color-ts-property: #ff984d; - --dark-color-ts-method: #ff4db8; - --dark-color-ts-reference: #ff4d82; - --dark-color-ts-call-signature: var(--dark-color-ts-method); - --dark-color-ts-index-signature: var(--dark-color-ts-property); - --dark-color-ts-constructor-signature: var(--dark-color-ts-constructor); - --dark-color-ts-parameter: var(--dark-color-ts-variable); - /* type literal not included as links will never be generated to it */ - --dark-color-ts-type-parameter: #e07d13; - --dark-color-ts-accessor: #ff6060; - --dark-color-ts-get-signature: var(--dark-color-ts-accessor); - --dark-color-ts-set-signature: var(--dark-color-ts-accessor); - --dark-color-ts-type-alias: #ff6492; - /* reference not included as links will be colored with the kind that it points to */ - --dark-color-document: #ffffff; - - --dark-color-alert-note: #0969d9; - --dark-color-alert-tip: #1a7f37; - --dark-color-alert-important: #8250df; - --dark-color-alert-warning: #9a6700; - --dark-color-alert-caution: #cf222e; - - --dark-external-icon: url("data:image/svg+xml;utf8,"); - --dark-color-scheme: dark; - } - - @media (prefers-color-scheme: light) { - :root { - --color-background: var(--light-color-background); - --color-background-secondary: var( - --light-color-background-secondary - ); - --color-background-warning: var(--light-color-background-warning); - --color-warning-text: var(--light-color-warning-text); - --color-accent: var(--light-color-accent); - --color-active-menu-item: var(--light-color-active-menu-item); - --color-text: var(--light-color-text); - --color-text-aside: var(--light-color-text-aside); - - --color-icon-background: var(--light-color-icon-background); - --color-icon-text: var(--light-color-icon-text); - - --color-comment-tag-text: var(--light-color-text); - --color-comment-tag: var(--light-color-background); - - --color-link: var(--light-color-link); - --color-focus-outline: var(--light-color-focus-outline); - - --color-ts-keyword: var(--light-color-ts-keyword); - --color-ts-project: var(--light-color-ts-project); - --color-ts-module: var(--light-color-ts-module); - --color-ts-namespace: var(--light-color-ts-namespace); - --color-ts-enum: var(--light-color-ts-enum); - --color-ts-enum-member: var(--light-color-ts-enum-member); - --color-ts-variable: var(--light-color-ts-variable); - --color-ts-function: var(--light-color-ts-function); - --color-ts-class: var(--light-color-ts-class); - --color-ts-interface: var(--light-color-ts-interface); - --color-ts-constructor: var(--light-color-ts-constructor); - --color-ts-property: var(--light-color-ts-property); - --color-ts-method: var(--light-color-ts-method); - --color-ts-reference: var(--light-color-ts-reference); - --color-ts-call-signature: var(--light-color-ts-call-signature); - --color-ts-index-signature: var(--light-color-ts-index-signature); - --color-ts-constructor-signature: var( - --light-color-ts-constructor-signature - ); - --color-ts-parameter: var(--light-color-ts-parameter); - --color-ts-type-parameter: var(--light-color-ts-type-parameter); - --color-ts-accessor: var(--light-color-ts-accessor); - --color-ts-get-signature: var(--light-color-ts-get-signature); - --color-ts-set-signature: var(--light-color-ts-set-signature); - --color-ts-type-alias: var(--light-color-ts-type-alias); - --color-document: var(--light-color-document); - - --color-alert-note: var(--light-color-alert-note); - --color-alert-tip: var(--light-color-alert-tip); - --color-alert-important: var(--light-color-alert-important); - --color-alert-warning: var(--light-color-alert-warning); - --color-alert-caution: var(--light-color-alert-caution); - - --external-icon: var(--light-external-icon); - --color-scheme: var(--light-color-scheme); - } - } - - @media (prefers-color-scheme: dark) { - :root { - --color-background: var(--dark-color-background); - --color-background-secondary: var( - --dark-color-background-secondary - ); - --color-background-warning: var(--dark-color-background-warning); - --color-warning-text: var(--dark-color-warning-text); - --color-accent: var(--dark-color-accent); - --color-active-menu-item: var(--dark-color-active-menu-item); - --color-text: var(--dark-color-text); - --color-text-aside: var(--dark-color-text-aside); - - --color-icon-background: var(--dark-color-icon-background); - --color-icon-text: var(--dark-color-icon-text); - - --color-comment-tag-text: var(--dark-color-text); - --color-comment-tag: var(--dark-color-background); - - --color-link: var(--dark-color-link); - --color-focus-outline: var(--dark-color-focus-outline); - - --color-ts-keyword: var(--dark-color-ts-keyword); - --color-ts-project: var(--dark-color-ts-project); - --color-ts-module: var(--dark-color-ts-module); - --color-ts-namespace: var(--dark-color-ts-namespace); - --color-ts-enum: var(--dark-color-ts-enum); - --color-ts-enum-member: var(--dark-color-ts-enum-member); - --color-ts-variable: var(--dark-color-ts-variable); - --color-ts-function: var(--dark-color-ts-function); - --color-ts-class: var(--dark-color-ts-class); - --color-ts-interface: var(--dark-color-ts-interface); - --color-ts-constructor: var(--dark-color-ts-constructor); - --color-ts-property: var(--dark-color-ts-property); - --color-ts-method: var(--dark-color-ts-method); - --color-ts-reference: var(--dark-color-ts-reference); - --color-ts-call-signature: var(--dark-color-ts-call-signature); - --color-ts-index-signature: var(--dark-color-ts-index-signature); - --color-ts-constructor-signature: var( - --dark-color-ts-constructor-signature - ); - --color-ts-parameter: var(--dark-color-ts-parameter); - --color-ts-type-parameter: var(--dark-color-ts-type-parameter); - --color-ts-accessor: var(--dark-color-ts-accessor); - --color-ts-get-signature: var(--dark-color-ts-get-signature); - --color-ts-set-signature: var(--dark-color-ts-set-signature); - --color-ts-type-alias: var(--dark-color-ts-type-alias); - --color-document: var(--dark-color-document); - - --color-alert-note: var(--dark-color-alert-note); - --color-alert-tip: var(--dark-color-alert-tip); - --color-alert-important: var(--dark-color-alert-important); - --color-alert-warning: var(--dark-color-alert-warning); - --color-alert-caution: var(--dark-color-alert-caution); - - --external-icon: var(--dark-external-icon); - --color-scheme: var(--dark-color-scheme); - } - } - - html { - color-scheme: var(--color-scheme); - } - - body { - margin: 0; - } - - :root[data-theme="light"] { - --color-background: var(--light-color-background); - --color-background-secondary: var(--light-color-background-secondary); - --color-background-warning: var(--light-color-background-warning); - --color-warning-text: var(--light-color-warning-text); - --color-icon-background: var(--light-color-icon-background); - --color-accent: var(--light-color-accent); - --color-active-menu-item: var(--light-color-active-menu-item); - --color-text: var(--light-color-text); - --color-text-aside: var(--light-color-text-aside); - --color-icon-text: var(--light-color-icon-text); - - --color-comment-tag-text: var(--light-color-text); - --color-comment-tag: var(--light-color-background); - - --color-link: var(--light-color-link); - --color-focus-outline: var(--light-color-focus-outline); - - --color-ts-keyword: var(--light-color-ts-keyword); - --color-ts-project: var(--light-color-ts-project); - --color-ts-module: var(--light-color-ts-module); - --color-ts-namespace: var(--light-color-ts-namespace); - --color-ts-enum: var(--light-color-ts-enum); - --color-ts-enum-member: var(--light-color-ts-enum-member); - --color-ts-variable: var(--light-color-ts-variable); - --color-ts-function: var(--light-color-ts-function); - --color-ts-class: var(--light-color-ts-class); - --color-ts-interface: var(--light-color-ts-interface); - --color-ts-constructor: var(--light-color-ts-constructor); - --color-ts-property: var(--light-color-ts-property); - --color-ts-method: var(--light-color-ts-method); - --color-ts-reference: var(--light-color-ts-reference); - --color-ts-call-signature: var(--light-color-ts-call-signature); - --color-ts-index-signature: var(--light-color-ts-index-signature); - --color-ts-constructor-signature: var( - --light-color-ts-constructor-signature - ); - --color-ts-parameter: var(--light-color-ts-parameter); - --color-ts-type-parameter: var(--light-color-ts-type-parameter); - --color-ts-accessor: var(--light-color-ts-accessor); - --color-ts-get-signature: var(--light-color-ts-get-signature); - --color-ts-set-signature: var(--light-color-ts-set-signature); - --color-ts-type-alias: var(--light-color-ts-type-alias); - --color-document: var(--light-color-document); - - --color-note: var(--light-color-note); - --color-tip: var(--light-color-tip); - --color-important: var(--light-color-important); - --color-warning: var(--light-color-warning); - --color-caution: var(--light-color-caution); - - --external-icon: var(--light-external-icon); - --color-scheme: var(--light-color-scheme); - } - - :root[data-theme="dark"] { - --color-background: var(--dark-color-background); - --color-background-secondary: var(--dark-color-background-secondary); - --color-background-warning: var(--dark-color-background-warning); - --color-warning-text: var(--dark-color-warning-text); - --color-icon-background: var(--dark-color-icon-background); - --color-accent: var(--dark-color-accent); - --color-active-menu-item: var(--dark-color-active-menu-item); - --color-text: var(--dark-color-text); - --color-text-aside: var(--dark-color-text-aside); - --color-icon-text: var(--dark-color-icon-text); - - --color-comment-tag-text: var(--dark-color-text); - --color-comment-tag: var(--dark-color-background); - - --color-link: var(--dark-color-link); - --color-focus-outline: var(--dark-color-focus-outline); - - --color-ts-keyword: var(--dark-color-ts-keyword); - --color-ts-project: var(--dark-color-ts-project); - --color-ts-module: var(--dark-color-ts-module); - --color-ts-namespace: var(--dark-color-ts-namespace); - --color-ts-enum: var(--dark-color-ts-enum); - --color-ts-enum-member: var(--dark-color-ts-enum-member); - --color-ts-variable: var(--dark-color-ts-variable); - --color-ts-function: var(--dark-color-ts-function); - --color-ts-class: var(--dark-color-ts-class); - --color-ts-interface: var(--dark-color-ts-interface); - --color-ts-constructor: var(--dark-color-ts-constructor); - --color-ts-property: var(--dark-color-ts-property); - --color-ts-method: var(--dark-color-ts-method); - --color-ts-reference: var(--dark-color-ts-reference); - --color-ts-call-signature: var(--dark-color-ts-call-signature); - --color-ts-index-signature: var(--dark-color-ts-index-signature); - --color-ts-constructor-signature: var( - --dark-color-ts-constructor-signature - ); - --color-ts-parameter: var(--dark-color-ts-parameter); - --color-ts-type-parameter: var(--dark-color-ts-type-parameter); - --color-ts-accessor: var(--dark-color-ts-accessor); - --color-ts-get-signature: var(--dark-color-ts-get-signature); - --color-ts-set-signature: var(--dark-color-ts-set-signature); - --color-ts-type-alias: var(--dark-color-ts-type-alias); - --color-document: var(--dark-color-document); - - --color-note: var(--dark-color-note); - --color-tip: var(--dark-color-tip); - --color-important: var(--dark-color-important); - --color-warning: var(--dark-color-warning); - --color-caution: var(--dark-color-caution); - - --external-icon: var(--dark-external-icon); - --color-scheme: var(--dark-color-scheme); - } - - *:focus-visible, - .tsd-accordion-summary:focus-visible svg { - outline: 2px solid var(--color-focus-outline); - } - - .always-visible, - .always-visible .tsd-signatures { - display: inherit !important; - } - - h1, - h2, - h3, - h4, - h5, - h6 { - line-height: 1.2; - } - - h1 { - font-size: 1.875rem; - margin: 0.67rem 0; - } - - h2 { - font-size: 1.5rem; - margin: 0.83rem 0; - } - - h3 { - font-size: 1.25rem; - margin: 1rem 0; - } - - h4 { - font-size: 1.05rem; - margin: 1.33rem 0; - } - - h5 { - font-size: 1rem; - margin: 1.5rem 0; - } - - h6 { - font-size: 0.875rem; - margin: 2.33rem 0; - } - - dl, - menu, - ol, - ul { - margin: 1em 0; - } - - dd { - margin: 0 0 0 34px; - } - - .container { - max-width: 1700px; - padding: 0 2rem; - } - - /* Footer */ - footer { - border-top: 1px solid var(--color-accent); - padding-top: 1rem; - padding-bottom: 1rem; - max-height: 3.5rem; - } - footer > p { - margin: 0 1em; - } - - .container-main { - margin: 0 auto; - /* toolbar, footer, margin */ - min-height: calc(100vh - 41px - 56px - 4rem); - } - - @keyframes fade-in { - from { - opacity: 0; - } - to { - opacity: 1; - } - } - @keyframes fade-out { - from { - opacity: 1; - visibility: visible; - } - to { - opacity: 0; - } - } - @keyframes fade-in-delayed { - 0% { - opacity: 0; - } - 33% { - opacity: 0; - } - 100% { - opacity: 1; - } - } - @keyframes fade-out-delayed { - 0% { - opacity: 1; - visibility: visible; - } - 66% { - opacity: 0; - } - 100% { - opacity: 0; - } - } - @keyframes pop-in-from-right { - from { - transform: translate(100%, 0); - } - to { - transform: translate(0, 0); - } - } - @keyframes pop-out-to-right { - from { - transform: translate(0, 0); - visibility: visible; - } - to { - transform: translate(100%, 0); - } - } - body { - background: var(--color-background); - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans", - Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; - font-size: 16px; - color: var(--color-text); - } - - a { - color: var(--color-link); - text-decoration: none; - } - a:hover { - text-decoration: underline; - } - a.external[target="_blank"] { - background-image: var(--external-icon); - background-position: top 3px right; - background-repeat: no-repeat; - padding-right: 13px; - } - a.tsd-anchor-link { - color: var(--color-text); - } - - code, - pre { - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - padding: 0.2em; - margin: 0; - font-size: 0.875rem; - border-radius: 0.8em; - } - - pre { - position: relative; - white-space: pre-wrap; - word-wrap: break-word; - padding: 10px; - border: 1px solid var(--color-accent); - margin-bottom: 8px; - } - pre code { - padding: 0; - font-size: 100%; - } - pre > button { - position: absolute; - top: 10px; - right: 10px; - opacity: 0; - transition: opacity 0.1s; - box-sizing: border-box; - } - pre:hover > button, - pre > button.visible { - opacity: 1; - } - - blockquote { - margin: 1em 0; - padding-left: 1em; - border-left: 4px solid gray; - } - - .tsd-typography { - line-height: 1.333em; - } - .tsd-typography ul { - list-style: square; - padding: 0 0 0 20px; - margin: 0; - } - .tsd-typography .tsd-index-panel h3, - .tsd-index-panel .tsd-typography h3, - .tsd-typography h4, - .tsd-typography h5, - .tsd-typography h6 { - font-size: 1em; - } - .tsd-typography h5, - .tsd-typography h6 { - font-weight: normal; - } - .tsd-typography p, - .tsd-typography ul, - .tsd-typography ol { - margin: 1em 0; - } - .tsd-typography table { - border-collapse: collapse; - border: none; - } - .tsd-typography td, - .tsd-typography th { - padding: 6px 13px; - border: 1px solid var(--color-accent); - } - .tsd-typography thead, - .tsd-typography tr:nth-child(even) { - background-color: var(--color-background-secondary); - } - - .tsd-alert { - padding: 8px 16px; - margin-bottom: 16px; - border-left: 0.25em solid var(--alert-color); - } - .tsd-alert blockquote > :last-child, - .tsd-alert > :last-child { - margin-bottom: 0; - } - .tsd-alert-title { - color: var(--alert-color); - display: inline-flex; - align-items: center; - } - .tsd-alert-title span { - margin-left: 4px; - } - - .tsd-alert-note { - --alert-color: var(--color-alert-note); - } - .tsd-alert-tip { - --alert-color: var(--color-alert-tip); - } - .tsd-alert-important { - --alert-color: var(--color-alert-important); - } - .tsd-alert-warning { - --alert-color: var(--color-alert-warning); - } - .tsd-alert-caution { - --alert-color: var(--color-alert-caution); - } - - .tsd-breadcrumb { - margin: 0; - padding: 0; - color: var(--color-text-aside); - } - .tsd-breadcrumb a { - color: var(--color-text-aside); - text-decoration: none; - } - .tsd-breadcrumb a:hover { - text-decoration: underline; - } - .tsd-breadcrumb li { - display: inline; - } - .tsd-breadcrumb li:after { - content: " / "; - } - - .tsd-comment-tags { - display: flex; - flex-direction: column; - } - dl.tsd-comment-tag-group { - display: flex; - align-items: center; - overflow: hidden; - margin: 0.5em 0; - } - dl.tsd-comment-tag-group dt { - display: flex; - margin-right: 0.5em; - font-size: 0.875em; - font-weight: normal; - } - dl.tsd-comment-tag-group dd { - margin: 0; - } - code.tsd-tag { - padding: 0.25em 0.4em; - border: 0.1em solid var(--color-accent); - margin-right: 0.25em; - font-size: 70%; - } - h1 code.tsd-tag:first-of-type { - margin-left: 0.25em; - } - - dl.tsd-comment-tag-group dd:before, - dl.tsd-comment-tag-group dd:after { - content: " "; - } - dl.tsd-comment-tag-group dd pre, - dl.tsd-comment-tag-group dd:after { - clear: both; - } - dl.tsd-comment-tag-group p { - margin: 0; - } - - .tsd-panel.tsd-comment .lead { - font-size: 1.1em; - line-height: 1.333em; - margin-bottom: 2em; - } - .tsd-panel.tsd-comment .lead:last-child { - margin-bottom: 0; - } - - .tsd-filter-visibility h4 { - font-size: 1rem; - padding-top: 0.75rem; - padding-bottom: 0.5rem; - margin: 0; - } - .tsd-filter-item:not(:last-child) { - margin-bottom: 0.5rem; - } - .tsd-filter-input { - display: flex; - width: -moz-fit-content; - width: fit-content; - align-items: center; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - cursor: pointer; - } - .tsd-filter-input input[type="checkbox"] { - cursor: pointer; - position: absolute; - width: 1.5em; - height: 1.5em; - opacity: 0; - } - .tsd-filter-input input[type="checkbox"]:disabled { - pointer-events: none; - } - .tsd-filter-input svg { - cursor: pointer; - width: 1.5em; - height: 1.5em; - margin-right: 0.5em; - border-radius: 0.33em; - /* Leaving this at full opacity breaks event listeners on Firefox. - Don't remove unless you know what you're doing. */ - opacity: 0.99; - } - .tsd-filter-input input[type="checkbox"]:focus-visible + svg { - outline: 2px solid var(--color-focus-outline); - } - .tsd-checkbox-background { - fill: var(--color-accent); - } - input[type="checkbox"]:checked ~ svg .tsd-checkbox-checkmark { - stroke: var(--color-text); - } - .tsd-filter-input input:disabled ~ svg > .tsd-checkbox-background { - fill: var(--color-background); - stroke: var(--color-accent); - stroke-width: 0.25rem; - } - .tsd-filter-input input:disabled ~ svg > .tsd-checkbox-checkmark { - stroke: var(--color-accent); - } - - .settings-label { - font-weight: bold; - text-transform: uppercase; - display: inline-block; - } - - .tsd-filter-visibility .settings-label { - margin: 0.75rem 0 0.5rem 0; - } - - .tsd-theme-toggle .settings-label { - margin: 0.75rem 0.75rem 0 0; - } - - .tsd-hierarchy h4 label:hover span { - text-decoration: underline; - } - - .tsd-hierarchy { - list-style: square; - margin: 0; - } - .tsd-hierarchy-target { - font-weight: bold; - } - .tsd-hierarchy-toggle { - color: var(--color-link); - cursor: pointer; - } - - .tsd-full-hierarchy:not(:last-child) { - margin-bottom: 1em; - padding-bottom: 1em; - border-bottom: 1px solid var(--color-accent); - } - .tsd-full-hierarchy, - .tsd-full-hierarchy ul { - list-style: none; - margin: 0; - padding: 0; - } - .tsd-full-hierarchy ul { - padding-left: 1.5rem; - } - .tsd-full-hierarchy a { - padding: 0.25rem 0 !important; - font-size: 1rem; - display: inline-flex; - align-items: center; - color: var(--color-text); - } - .tsd-full-hierarchy svg[data-dropdown] { - cursor: pointer; - } - .tsd-full-hierarchy svg[data-dropdown="false"] { - transform: rotate(-90deg); - } - .tsd-full-hierarchy svg[data-dropdown="false"] ~ ul { - display: none; - } - - .tsd-panel-group.tsd-index-group { - margin-bottom: 0; - } - .tsd-index-panel .tsd-index-list { - list-style: none; - line-height: 1.333em; - margin: 0; - padding: 0.25rem 0 0 0; - overflow: hidden; - display: grid; - grid-template-columns: repeat(3, 1fr); - column-gap: 1rem; - grid-template-rows: auto; - } - @media (max-width: 1024px) { - .tsd-index-panel .tsd-index-list { - grid-template-columns: repeat(2, 1fr); - } - } - @media (max-width: 768px) { - .tsd-index-panel .tsd-index-list { - grid-template-columns: repeat(1, 1fr); - } - } - .tsd-index-panel .tsd-index-list li { - -webkit-page-break-inside: avoid; - -moz-page-break-inside: avoid; - -ms-page-break-inside: avoid; - -o-page-break-inside: avoid; - page-break-inside: avoid; - } - - .tsd-flag { - display: inline-block; - padding: 0.25em 0.4em; - border-radius: 4px; - color: var(--color-comment-tag-text); - background-color: var(--color-comment-tag); - text-indent: 0; - font-size: 75%; - line-height: 1; - font-weight: normal; - } - - .tsd-anchor { - position: relative; - top: -100px; - } - - .tsd-member { - position: relative; - } - .tsd-member .tsd-anchor + h3 { - display: flex; - align-items: center; - margin-top: 0; - margin-bottom: 0; - border-bottom: none; - } - - .tsd-navigation.settings { - margin: 1rem 0; - } - .tsd-navigation > a, - .tsd-navigation .tsd-accordion-summary { - width: calc(100% - 0.25rem); - display: flex; - align-items: center; - } - .tsd-navigation a, - .tsd-navigation summary > span, - .tsd-page-navigation a { - display: flex; - width: calc(100% - 0.25rem); - align-items: center; - padding: 0.25rem; - color: var(--color-text); - text-decoration: none; - box-sizing: border-box; - } - .tsd-navigation a.current, - .tsd-page-navigation a.current { - background: var(--color-active-menu-item); - } - .tsd-navigation a:hover, - .tsd-page-navigation a:hover { - text-decoration: underline; - } - .tsd-navigation ul, - .tsd-page-navigation ul { - margin-top: 0; - margin-bottom: 0; - padding: 0; - list-style: none; - } - .tsd-navigation li, - .tsd-page-navigation li { - padding: 0; - max-width: 100%; - } - .tsd-navigation .tsd-nav-link { - display: none; - } - .tsd-nested-navigation { - margin-left: 3rem; - } - .tsd-nested-navigation > li > details { - margin-left: -1.5rem; - } - .tsd-small-nested-navigation { - margin-left: 1.5rem; - } - .tsd-small-nested-navigation > li > details { - margin-left: -1.5rem; - } - - .tsd-page-navigation-section { - margin-left: 10px; - } - .tsd-page-navigation-section > summary { - padding: 0.25rem; - } - .tsd-page-navigation-section > div { - margin-left: 20px; - } - .tsd-page-navigation ul { - padding-left: 1.75rem; - } - - #tsd-sidebar-links a { - margin-top: 0; - margin-bottom: 0.5rem; - line-height: 1.25rem; - } - #tsd-sidebar-links a:last-of-type { - margin-bottom: 0; - } - - a.tsd-index-link { - padding: 0.25rem 0 !important; - font-size: 1rem; - line-height: 1.25rem; - display: inline-flex; - align-items: center; - color: var(--color-text); - } - .tsd-accordion-summary { - list-style-type: none; /* hide marker on non-safari */ - outline: none; /* broken on safari, so just hide it */ - } - .tsd-accordion-summary::-webkit-details-marker { - display: none; /* hide marker on safari */ - } - .tsd-accordion-summary, - .tsd-accordion-summary a { - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - user-select: none; - - cursor: pointer; - } - .tsd-accordion-summary a { - width: calc(100% - 1.5rem); - } - .tsd-accordion-summary > * { - margin-top: 0; - margin-bottom: 0; - padding-top: 0; - padding-bottom: 0; - } - .tsd-accordion .tsd-accordion-summary > svg { - margin-left: 0.25rem; - vertical-align: text-top; - } - /* - * We need to be careful to target the arrow indicating whether the accordion - * is open, but not any other SVGs included in the details element. - */ - .tsd-accordion:not([open]) > .tsd-accordion-summary > svg:first-child, - .tsd-accordion:not([open]) > .tsd-accordion-summary > h1 > svg:first-child, - .tsd-accordion:not([open]) > .tsd-accordion-summary > h2 > svg:first-child, - .tsd-accordion:not([open]) > .tsd-accordion-summary > h3 > svg:first-child, - .tsd-accordion:not([open]) > .tsd-accordion-summary > h4 > svg:first-child, - .tsd-accordion:not([open]) > .tsd-accordion-summary > h5 > svg:first-child { - transform: rotate(-90deg); - } - .tsd-index-content > :not(:first-child) { - margin-top: 0.75rem; - } - .tsd-index-heading { - margin-top: 1.5rem; - margin-bottom: 0.75rem; - } - - .tsd-no-select { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - } - .tsd-kind-icon { - margin-right: 0.5rem; - width: 1.25rem; - height: 1.25rem; - min-width: 1.25rem; - min-height: 1.25rem; - } - .tsd-signature > .tsd-kind-icon { - margin-right: 0.8rem; - } - - .tsd-panel { - margin-bottom: 2.5rem; - } - .tsd-panel.tsd-member { - margin-bottom: 4rem; - } - .tsd-panel:empty { - display: none; - } - .tsd-panel > h1, - .tsd-panel > h2, - .tsd-panel > h3 { - margin: 1.5rem -1.5rem 0.75rem -1.5rem; - padding: 0 1.5rem 0.75rem 1.5rem; - } - .tsd-panel > h1.tsd-before-signature, - .tsd-panel > h2.tsd-before-signature, - .tsd-panel > h3.tsd-before-signature { - margin-bottom: 0; - border-bottom: none; - } - - .tsd-panel-group { - margin: 2rem 0; - } - .tsd-panel-group.tsd-index-group { - margin: 2rem 0; - } - .tsd-panel-group.tsd-index-group details { - margin: 2rem 0; - } - .tsd-panel-group > .tsd-accordion-summary { - margin-bottom: 1rem; - } - - #tsd-search { - transition: background-color 0.2s; - } - #tsd-search .title { - position: relative; - z-index: 2; - } - #tsd-search .field { - position: absolute; - left: 0; - top: 0; - right: 2.5rem; - height: 100%; - } - #tsd-search .field input { - box-sizing: border-box; - position: relative; - top: -50px; - z-index: 1; - width: 100%; - padding: 0 10px; - opacity: 0; - outline: 0; - border: 0; - background: transparent; - color: var(--color-text); - } - #tsd-search .field label { - position: absolute; - overflow: hidden; - right: -40px; - } - #tsd-search .field input, - #tsd-search .title, - #tsd-toolbar-links a { - transition: opacity 0.2s; - } - #tsd-search .results { - position: absolute; - visibility: hidden; - top: 40px; - width: 100%; - margin: 0; - padding: 0; - list-style: none; - box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); - } - #tsd-search .results li { - background-color: var(--color-background); - line-height: initial; - padding: 4px; - } - #tsd-search .results li:nth-child(even) { - background-color: var(--color-background-secondary); - } - #tsd-search .results li.state { - display: none; - } - #tsd-search .results li.current:not(.no-results), - #tsd-search .results li:hover:not(.no-results) { - background-color: var(--color-accent); - } - #tsd-search .results a { - display: flex; - align-items: center; - padding: 0.25rem; - box-sizing: border-box; - } - #tsd-search .results a:before { - top: 10px; - } - #tsd-search .results span.parent { - color: var(--color-text-aside); - font-weight: normal; - } - #tsd-search.has-focus { - background-color: var(--color-accent); - } - #tsd-search.has-focus .field input { - top: 0; - opacity: 1; - } - #tsd-search.has-focus .title, - #tsd-search.has-focus #tsd-toolbar-links a { - z-index: 0; - opacity: 0; - } - #tsd-search.has-focus .results { - visibility: visible; - } - #tsd-search.loading .results li.state.loading { - display: block; - } - #tsd-search.failure .results li.state.failure { - display: block; - } - - #tsd-toolbar-links { - position: absolute; - top: 0; - right: 2rem; - height: 100%; - display: flex; - align-items: center; - justify-content: flex-end; - } - #tsd-toolbar-links a { - margin-left: 1.5rem; - } - #tsd-toolbar-links a:hover { - text-decoration: underline; - } - - .tsd-signature { - margin: 0 0 1rem 0; - padding: 1rem 0.5rem; - border: 1px solid var(--color-accent); - font-family: Menlo, Monaco, Consolas, "Courier New", monospace; - font-size: 14px; - overflow-x: auto; - } - - .tsd-signature-keyword { - color: var(--color-ts-keyword); - font-weight: normal; - } - - .tsd-signature-symbol { - color: var(--color-text-aside); - font-weight: normal; - } - - .tsd-signature-type { - font-style: italic; - font-weight: normal; - } - - .tsd-signatures { - padding: 0; - margin: 0 0 1em 0; - list-style-type: none; - } - .tsd-signatures .tsd-signature { - margin: 0; - border-color: var(--color-accent); - border-width: 1px 0; - transition: background-color 0.1s; - } - .tsd-signatures .tsd-index-signature:not(:last-child) { - margin-bottom: 1em; - } - .tsd-signatures .tsd-index-signature .tsd-signature { - border-width: 1px; - } - .tsd-description .tsd-signatures .tsd-signature { - border-width: 1px; - } - - ul.tsd-parameter-list, - ul.tsd-type-parameter-list { - list-style: square; - margin: 0; - padding-left: 20px; - } - ul.tsd-parameter-list > li.tsd-parameter-signature, - ul.tsd-type-parameter-list > li.tsd-parameter-signature { - list-style: none; - margin-left: -20px; - } - ul.tsd-parameter-list h5, - ul.tsd-type-parameter-list h5 { - font-size: 16px; - margin: 1em 0 0.5em 0; - } - .tsd-sources { - margin-top: 1rem; - font-size: 0.875em; - } - .tsd-sources a { - color: var(--color-text-aside); - text-decoration: underline; - } - .tsd-sources ul { - list-style: none; - padding: 0; - } - - .tsd-page-toolbar { - position: sticky; - z-index: 1; - top: 0; - left: 0; - width: 100%; - color: var(--color-text); - background: var(--color-background-secondary); - border-bottom: 1px var(--color-accent) solid; - transition: transform 0.3s ease-in-out; - } - .tsd-page-toolbar a { - color: var(--color-text); - text-decoration: none; - } - .tsd-page-toolbar a.title { - font-weight: bold; - } - .tsd-page-toolbar a.title:hover { - text-decoration: underline; - } - .tsd-page-toolbar .tsd-toolbar-contents { - display: flex; - justify-content: space-between; - height: 2.5rem; - margin: 0 auto; - } - .tsd-page-toolbar .table-cell { - position: relative; - white-space: nowrap; - line-height: 40px; - } - .tsd-page-toolbar .table-cell:first-child { - width: 100%; - } - .tsd-page-toolbar .tsd-toolbar-icon { - box-sizing: border-box; - line-height: 0; - padding: 12px 0; - } - - .tsd-widget { - display: inline-block; - overflow: hidden; - opacity: 0.8; - height: 40px; - transition: - opacity 0.1s, - background-color 0.2s; - vertical-align: bottom; - cursor: pointer; - } - .tsd-widget:hover { - opacity: 0.9; - } - .tsd-widget.active { - opacity: 1; - background-color: var(--color-accent); - } - .tsd-widget.no-caption { - width: 40px; - } - .tsd-widget.no-caption:before { - margin: 0; - } - - .tsd-widget.options, - .tsd-widget.menu { - display: none; - } - input[type="checkbox"] + .tsd-widget:before { - background-position: -120px 0; - } - input[type="checkbox"]:checked + .tsd-widget:before { - background-position: -160px 0; - } - - img { - max-width: 100%; - } - - .tsd-member-summary-name { - display: inline-flex; - align-items: center; - padding: 0.25rem; - text-decoration: none; - } - - .tsd-anchor-icon { - display: inline-flex; - align-items: center; - margin-left: 0.5rem; - color: var(--color-text); - } - - .tsd-anchor-icon svg { - width: 1em; - height: 1em; - visibility: hidden; - } - - .tsd-member-summary-name:hover > .tsd-anchor-icon svg, - .tsd-anchor-link:hover > .tsd-anchor-icon svg { - visibility: visible; - } - - .deprecated { - text-decoration: line-through !important; - } - - .warning { - padding: 1rem; - color: var(--color-warning-text); - background: var(--color-background-warning); - } - - .tsd-kind-project { - color: var(--color-ts-project); - } - .tsd-kind-module { - color: var(--color-ts-module); - } - .tsd-kind-namespace { - color: var(--color-ts-namespace); - } - .tsd-kind-enum { - color: var(--color-ts-enum); - } - .tsd-kind-enum-member { - color: var(--color-ts-enum-member); - } - .tsd-kind-variable { - color: var(--color-ts-variable); - } - .tsd-kind-function { - color: var(--color-ts-function); - } - .tsd-kind-class { - color: var(--color-ts-class); - } - .tsd-kind-interface { - color: var(--color-ts-interface); - } - .tsd-kind-constructor { - color: var(--color-ts-constructor); - } - .tsd-kind-property { - color: var(--color-ts-property); - } - .tsd-kind-method { - color: var(--color-ts-method); - } - .tsd-kind-reference { - color: var(--color-ts-reference); - } - .tsd-kind-call-signature { - color: var(--color-ts-call-signature); - } - .tsd-kind-index-signature { - color: var(--color-ts-index-signature); - } - .tsd-kind-constructor-signature { - color: var(--color-ts-constructor-signature); - } - .tsd-kind-parameter { - color: var(--color-ts-parameter); - } - .tsd-kind-type-parameter { - color: var(--color-ts-type-parameter); - } - .tsd-kind-accessor { - color: var(--color-ts-accessor); - } - .tsd-kind-get-signature { - color: var(--color-ts-get-signature); - } - .tsd-kind-set-signature { - color: var(--color-ts-set-signature); - } - .tsd-kind-type-alias { - color: var(--color-ts-type-alias); - } - - /* if we have a kind icon, don't color the text by kind */ - .tsd-kind-icon ~ span { - color: var(--color-text); - } - - * { - scrollbar-width: thin; - scrollbar-color: var(--color-accent) var(--color-icon-background); - } - - *::-webkit-scrollbar { - width: 0.75rem; - } - - *::-webkit-scrollbar-track { - background: var(--color-icon-background); - } - - *::-webkit-scrollbar-thumb { - background-color: var(--color-accent); - border-radius: 999rem; - border: 0.25rem solid var(--color-icon-background); - } - - /* mobile */ - @media (max-width: 769px) { - .tsd-widget.options, - .tsd-widget.menu { - display: inline-block; - } - - .container-main { - display: flex; - } - html .col-content { - float: none; - max-width: 100%; - width: 100%; - } - html .col-sidebar { - position: fixed !important; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - z-index: 1024; - top: 0 !important; - bottom: 0 !important; - left: auto !important; - right: 0 !important; - padding: 1.5rem 1.5rem 0 0; - width: 75vw; - visibility: hidden; - background-color: var(--color-background); - transform: translate(100%, 0); - } - html .col-sidebar > *:last-child { - padding-bottom: 20px; - } - html .overlay { - content: ""; - display: block; - position: fixed; - z-index: 1023; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: rgba(0, 0, 0, 0.75); - visibility: hidden; - } - - .to-has-menu .overlay { - animation: fade-in 0.4s; - } - - .to-has-menu .col-sidebar { - animation: pop-in-from-right 0.4s; - } - - .from-has-menu .overlay { - animation: fade-out 0.4s; - } - - .from-has-menu .col-sidebar { - animation: pop-out-to-right 0.4s; - } - - .has-menu body { - overflow: hidden; - } - .has-menu .overlay { - visibility: visible; - } - .has-menu .col-sidebar { - visibility: visible; - transform: translate(0, 0); - display: flex; - flex-direction: column; - gap: 1.5rem; - max-height: 100vh; - padding: 1rem 2rem; - } - .has-menu .tsd-navigation { - max-height: 100%; - } - #tsd-toolbar-links { - display: none; - } - .tsd-navigation .tsd-nav-link { - display: flex; - } - } - - /* one sidebar */ - @media (min-width: 770px) { - .container-main { - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); - grid-template-areas: "sidebar content"; - margin: 2rem auto; - } - - .col-sidebar { - grid-area: sidebar; - } - .col-content { - grid-area: content; - padding: 0 1rem; - } - } - @media (min-width: 770px) and (max-width: 1399px) { - .col-sidebar { - max-height: calc(100vh - 2rem - 42px); - overflow: auto; - position: sticky; - top: 42px; - padding-top: 1rem; - } - .site-menu { - margin-top: 1rem; - } - } - - /* two sidebars */ - @media (min-width: 1200px) { - .container-main { - grid-template-columns: minmax(0, 1fr) minmax(0, 2.5fr) minmax( - 0, - 20rem - ); - grid-template-areas: "sidebar content toc"; - } - - .col-sidebar { - display: contents; - } - - .page-menu { - grid-area: toc; - padding-left: 1rem; - } - .site-menu { - grid-area: sidebar; - } - - .site-menu { - margin-top: 1rem; - } - - .page-menu, - .site-menu { - max-height: calc(100vh - 2rem - 42px); - overflow: auto; - position: sticky; - top: 42px; - } - } -} diff --git a/vet/lib/functions/src_Footer.default.html b/vet/lib/functions/src_Footer.default.html deleted file mode 100644 index 1e5bfd5..0000000 --- a/vet/lib/functions/src_Footer.default.html +++ /dev/null @@ -1,3 +0,0 @@ -default | vet

Function default

  • Fixed bottom app bar showing the site copyright.

    -

    Returns Element

    The footer AppBar element.

    -
diff --git a/vet/lib/functions/src_Header.default.html b/vet/lib/functions/src_Header.default.html deleted file mode 100644 index 1b9d7bf..0000000 --- a/vet/lib/functions/src_Header.default.html +++ /dev/null @@ -1,5 +0,0 @@ -default | vet

Function default

  • Fixed top app bar with the title/logo and an Admin button.

    -

    Uses useNavigate, so it must be rendered inside a router. Clicking the -title navigates to /; the Admin button navigates to /admin.

    -

    Returns Element

    The header AppBar element.

    -
diff --git a/vet/lib/functions/src_Home.default.html b/vet/lib/functions/src_Home.default.html deleted file mode 100644 index fe57343..0000000 --- a/vet/lib/functions/src_Home.default.html +++ /dev/null @@ -1,5 +0,0 @@ -default | vet

Function default

  • Render the demo landing page: resource grid, live preview, appointment form -and (when present) a live SSE stream.

    -

    Returns Element

    The page container, or a "no resources" notice when the spec -exposes none.

    -
diff --git a/vet/lib/functions/src_shared-theme_AppTheme.default.html b/vet/lib/functions/src_shared-theme_AppTheme.default.html deleted file mode 100644 index c4c7d04..0000000 --- a/vet/lib/functions/src_shared-theme_AppTheme.default.html +++ /dev/null @@ -1,11 +0,0 @@ -default | vet
  • Provide the MUI theme, color-mode context and CSS variables to children.

    -

    Builds the theme from getDesignTokens(mode) + getSemanticColors(mode) + -the component customizations, and re-creates it whenever the mode changes. -Also sets --bg-page, --bg-card, --bg-elevated, --border-default, ---border-subtle, --text-primary, --text-secondary and --text-muted -on a wrapper Box.

    -

    Props: children and defaultMode (see AppThemeProps).

    -

    Parameters

    • __namedParameters: AppThemeProps

    Returns Element

    <AppTheme defaultMode="dark">
    <CssBaseline />
    <App />
    </AppTheme> -
    - -
diff --git a/vet/lib/functions/src_shared-theme_themeConfig.getSemanticColors.html b/vet/lib/functions/src_shared-theme_themeConfig.getSemanticColors.html deleted file mode 100644 index d7ab76a..0000000 --- a/vet/lib/functions/src_shared-theme_themeConfig.getSemanticColors.html +++ /dev/null @@ -1,9 +0,0 @@ -getSemanticColors | vet
  • Resolve the semantic color groups for a color mode.

    -

    Dark mode uses fixed HSL values; light mode derives borders/text from the -gray ramp (with alpha).

    -

    Parameters

    Returns SemanticColors

    The SemanticColors for that mode.

    -
    const colors = getSemanticColors("dark");
    colors.surface.page; // "hsl(0, 0%, 9%)" -
    - -
diff --git a/vet/lib/functions/src_shared-theme_themePrimitives.getDesignTokens.html b/vet/lib/functions/src_shared-theme_themePrimitives.getDesignTokens.html deleted file mode 100644 index 082a6e8..0000000 --- a/vet/lib/functions/src_shared-theme_themePrimitives.getDesignTokens.html +++ /dev/null @@ -1,8 +0,0 @@ -getDesignTokens | vet

Build the MUI design tokens (palette, typography, shape, shadows) for a mode.

-

Light and dark palettes share the ramps but override specific slots in dark -mode. Also sets shadows[1] (the "baseShadow") per mode. The returned object -is spread into createTheme by AppTheme.

-
  • Parameters

    • mode: PaletteMode

      "light" or "dark".

      -

    Returns {
        palette: {
            action: { hover: string; selected: string };
            background: { default: string; paper: string };
            divider: string;
            error: { dark: string; light: string; main: string };
            flows: {
                inflows: { primary: string; surface: string; text: string };
                outflows: { primary: string; surface: string; text: string };
            };
            grey: {
                "100": string;
                "200": string;
                "300": string;
                "400": string;
                "50": string;
                "500": string;
                "600": string;
                "700": string;
                "750": string;
                "800": string;
                "850": string;
                "900": string;
            };
            info: { contrastText: string; dark: string; light: string; main: string };
            mode: PaletteMode;
            primary: {
                contrastText: string;
                dark: string;
                light: string;
                main: string;
            };
            success: { dark: string; light: string; main: string };
            text: { primary: string; secondary: string; warning: string };
            warning: { dark: string; light: string; main: string };
        };
        shadows: Shadows;
        shape: { borderRadius: number };
        typography: {
            body1: { fontSize: string };
            body2: { fontSize: string; fontWeight: number };
            caption: { fontSize: string; fontWeight: number };
            fontFamily: string;
            h1: {
                fontSize: string;
                fontWeight: number;
                letterSpacing: number;
                lineHeight: number;
            };
            h2: { fontSize: string; fontWeight: number; lineHeight: number };
            h3: { fontSize: string; lineHeight: number };
            h4: { fontSize: string; fontWeight: number; lineHeight: number };
            h5: { fontSize: string; fontWeight: number };
            h6: { fontSize: string; fontWeight: number };
            subtitle1: { fontSize: string };
            subtitle2: { fontSize: string; fontWeight: number };
        };
    }

    A MUI ThemeOptions-shaped object (palette, typography, shape, -shadows).

    -
diff --git a/vet/lib/index.html b/vet/lib/index.html deleted file mode 100644 index a3dfa48..0000000 --- a/vet/lib/index.html +++ /dev/null @@ -1 +0,0 @@ -vet
diff --git a/vet/lib/interfaces/src_shared-theme_themeConfig.SemanticColors.html b/vet/lib/interfaces/src_shared-theme_themeConfig.SemanticColors.html deleted file mode 100644 index 2e77379..0000000 --- a/vet/lib/interfaces/src_shared-theme_themeConfig.SemanticColors.html +++ /dev/null @@ -1,17 +0,0 @@ -SemanticColors | vet

Mode-aware semantic color groups attached to the MUI theme as -theme.semantic and exposed as CSS custom properties by AppTheme.

-
interface SemanticColors {
    border: { default: string; subtle: string };
    surface: { card: string; elevated: string; page: string };
    text: { muted: string; primary: string; secondary: string };
}

Properties

Properties

border: { default: string; subtle: string }

Border colors.

-

Type declaration

  • default: string

    Default border (--border-default).

    -
  • subtle: string

    Subtle border (--border-subtle).

    -
surface: { card: string; elevated: string; page: string }

Background surface colors.

-

Type declaration

  • card: string

    Card background (--bg-card).

    -
  • elevated: string

    Elevated surface, e.g. popovers (--bg-elevated).

    -
  • page: string

    Page background (--bg-page).

    -
text: { muted: string; primary: string; secondary: string }

Text colors.

-

Type declaration

  • muted: string

    Muted text (--text-muted).

    -
  • primary: string

    Primary text (--text-primary).

    -
  • secondary: string

    Secondary text (--text-secondary).

    -
diff --git a/vet/lib/interfaces/src_vite-env.ImportMeta.html b/vet/lib/interfaces/src_vite-env.ImportMeta.html deleted file mode 100644 index 9a2ab58..0000000 --- a/vet/lib/interfaces/src_vite-env.ImportMeta.html +++ /dev/null @@ -1,12 +0,0 @@ -ImportMeta | vet

Interface ImportMeta

The type of import.meta.

-

If you need to declare that a given property exists on import.meta, -this type may be augmented via interface merging.

-
interface ImportMeta {
    dirname: string;
    env: ImportMetaEnv;
    filename: string;
    glob: ImportGlobFunction;
    hot?: ViteHotContext;
    main: boolean;
    url: string;
    resolve(specifier: string): string;
    resolve(specifier: string, parent?: string | URL): string;
}

Properties

Methods

Properties

dirname: string
filename: string
glob: ImportGlobFunction
hot?: ViteHotContext
main: boolean
url: string

Methods

  • Parameters

    • specifier: string

    Returns string

  • Parameters

    • specifier: string
    • Optionalparent: string | URL

    Returns string

diff --git a/vet/lib/interfaces/src_vite-env.ImportMetaEnv.html b/vet/lib/interfaces/src_vite-env.ImportMetaEnv.html deleted file mode 100644 index 204a9b6..0000000 --- a/vet/lib/interfaces/src_vite-env.ImportMetaEnv.html +++ /dev/null @@ -1,8 +0,0 @@ -ImportMetaEnv | vet

Interface ImportMetaEnv

interface ImportMetaEnv {
    BASE_URL: string;
    DEV: boolean;
    MODE: string;
    PROD: boolean;
    SSR: boolean;
    VITE_API_BASE_URL: string;
    VITE_AUTH_BASE_URL: string;
    [key: string]: any;
}

Indexable

  • [key: string]: any

Properties

BASE_URL: string
DEV: boolean
MODE: string
PROD: boolean
SSR: boolean
VITE_API_BASE_URL: string
VITE_AUTH_BASE_URL: string
diff --git a/vet/lib/modules/src_Footer.html b/vet/lib/modules/src_Footer.html deleted file mode 100644 index 065da89..0000000 --- a/vet/lib/modules/src_Footer.html +++ /dev/null @@ -1,6 +0,0 @@ -src/Footer | vet

Module src/Footer

Site footer for the Veterinary Clinic demo app.

-

A fixed bottom AppBar (pinned above the drawer via -zIndex.drawer + 1) with a blurred translucent background and a top -divider, rendering the Copyright line. Rendered once by main.jsx below -the routed content.

-

Functions

default
diff --git a/vet/lib/modules/src_Header.html b/vet/lib/modules/src_Header.html deleted file mode 100644 index 8acb1b5..0000000 --- a/vet/lib/modules/src_Header.html +++ /dev/null @@ -1,6 +0,0 @@ -src/Header | vet

Module src/Header

Top navigation bar for the Veterinary Clinic demo app.

-

A fixed AppBar with blurred translucent background and bottom divider, -showing the app title/logo and an Admin button. Rendered once by main.jsx -above the routed content; the title navigates to / and the Admin button to -/admin.

-

Functions

default
diff --git a/vet/lib/modules/src_Home.html b/vet/lib/modules/src_Home.html deleted file mode 100644 index d4a0449..0000000 --- a/vet/lib/modules/src_Home.html +++ /dev/null @@ -1,13 +0,0 @@ -src/Home | vet

Module src/Home

Landing page for the Veterinary Clinic demo app.

-

Exercises the react-openapi building blocks end-to-end:

-
    -
  • ResourceCard - a grid of every top-level resource with a live record -count (or SSE connection status for streaming resources).
  • -
  • LiveTable - preview of the first 5 records of the first non-streaming -resource.
  • -
  • ApptForm - a hand-crafted appointment form using FormFieldRenderer, -useResource().create() and auto-loaded FK options.
  • -
  • An optional live SseStreamView with a pet selector for a streaming -resource.
  • -
-

Functions

default
diff --git a/vet/lib/modules/src_main.html b/vet/lib/modules/src_main.html deleted file mode 100644 index 673bcae..0000000 --- a/vet/lib/modules/src_main.html +++ /dev/null @@ -1,6 +0,0 @@ -src/main | vet

Module src/main

Application entry point.

-

Creates the React root from #root and mounts the app: AppProvider -(fed by specConfiguration) wraps a BrowserRouter → AppTheme → -Header → routed content (Home at /, Admin at /admin/*) → -Footer.

-
diff --git a/vet/lib/modules/src_openapi-config.html b/vet/lib/modules/src_openapi-config.html deleted file mode 100644 index 5513fd9..0000000 --- a/vet/lib/modules/src_openapi-config.html +++ /dev/null @@ -1,5 +0,0 @@ -src/openapi-config | vet

Module src/openapi-config

Runtime OpenAPI configuration for the Veterinary Clinic demo.

-

Reads the API base URL from import.meta.env.VITE_API_BASE_URL and points -react-openapi at ${base}/openapi.json, sets the app title, and enables -client-side filtering for the appointments resource.

-

Variables

specConfiguration
diff --git a/vet/lib/modules/src_shared-theme_AppTheme.html b/vet/lib/modules/src_shared-theme_AppTheme.html deleted file mode 100644 index 12f20e3..0000000 --- a/vet/lib/modules/src_shared-theme_AppTheme.html +++ /dev/null @@ -1,9 +0,0 @@ -src/shared-theme/AppTheme | vet

Module src/shared-theme/AppTheme

App theme provider and color-mode context.

-

Wraps the MUI ThemeProvider with the design tokens (getDesignTokens), -semantic colors (getSemanticColors) and component customizations -(inputsCustomizations, dataDisplayCustomizations, -feedbackCustomizations, navigationCustomizations, -surfacesCustomizations). Exposes a light/dark ColorModeContext and -publishes the semantic colors as CSS custom properties (--bg-page, ---bg-card, --text-primary, ...) for the app subtree.

-

Type Aliases

ColorMode

Variables

ColorModeContext

Functions

default
diff --git a/vet/lib/modules/src_shared-theme_customizations_dataDisplay.html b/vet/lib/modules/src_shared-theme_customizations_dataDisplay.html deleted file mode 100644 index e956c1f..0000000 --- a/vet/lib/modules/src_shared-theme_customizations_dataDisplay.html +++ /dev/null @@ -1,4 +0,0 @@ -src/shared-theme/customizations/dataDisplay | vet

Module src/shared-theme/customizations/dataDisplay

MUI style overrides for data-display components.

-

Exports dataDisplayCustomizations, a Components<Theme> map applied by -AppTheme, covering lists, chips, table pagination and icons.

-

Variables

dataDisplayCustomizations
diff --git a/vet/lib/modules/src_shared-theme_customizations_feedback.html b/vet/lib/modules/src_shared-theme_customizations_feedback.html deleted file mode 100644 index 3d6f321..0000000 --- a/vet/lib/modules/src_shared-theme_customizations_feedback.html +++ /dev/null @@ -1,4 +0,0 @@ -src/shared-theme/customizations/feedback | vet

Module src/shared-theme/customizations/feedback

MUI style overrides for feedback components.

-

Exports feedbackCustomizations, a Components<Theme> map applied by -AppTheme, covering alerts, dialogs and linear progress.

-

Variables

feedbackCustomizations
diff --git a/vet/lib/modules/src_shared-theme_customizations_inputs.html b/vet/lib/modules/src_shared-theme_customizations_inputs.html deleted file mode 100644 index fef5594..0000000 --- a/vet/lib/modules/src_shared-theme_customizations_inputs.html +++ /dev/null @@ -1,5 +0,0 @@ -src/shared-theme/customizations/inputs | vet

Module src/shared-theme/customizations/inputs

MUI style overrides for form inputs and buttons.

-

Exports inputsCustomizations, a Components<Theme> map applied by -AppTheme, covering buttons, icon buttons, toggles, checkbox, outlined -inputs and form labels with light/dark variants.

-

Variables

inputsCustomizations
diff --git a/vet/lib/modules/src_shared-theme_customizations_navigation.html b/vet/lib/modules/src_shared-theme_customizations_navigation.html deleted file mode 100644 index e68a75c..0000000 --- a/vet/lib/modules/src_shared-theme_customizations_navigation.html +++ /dev/null @@ -1,5 +0,0 @@ -src/shared-theme/customizations/navigation | vet

Module src/shared-theme/customizations/navigation

MUI style overrides for navigation components.

-

Exports navigationCustomizations, a Components<Theme> map applied by -AppTheme, covering menus, selects, links, drawers, pagination, tabs and -steppers.

-

Variables

navigationCustomizations
diff --git a/vet/lib/modules/src_shared-theme_customizations_surfaces.html b/vet/lib/modules/src_shared-theme_customizations_surfaces.html deleted file mode 100644 index 46827ec..0000000 --- a/vet/lib/modules/src_shared-theme_customizations_surfaces.html +++ /dev/null @@ -1,4 +0,0 @@ -src/shared-theme/customizations/surfaces | vet

Module src/shared-theme/customizations/surfaces

MUI style overrides for surface components.

-

Exports surfacesCustomizations, a Components<Theme> map applied by -AppTheme, covering accordions, paper, cards and card sections.

-

Variables

surfacesCustomizations
diff --git a/vet/lib/modules/src_shared-theme_themeConfig.html b/vet/lib/modules/src_shared-theme_themeConfig.html deleted file mode 100644 index 179a21d..0000000 --- a/vet/lib/modules/src_shared-theme_themeConfig.html +++ /dev/null @@ -1,5 +0,0 @@ -src/shared-theme/themeConfig | vet

Module src/shared-theme/themeConfig

Semantic (mode-aware) color tokens.

-

Adds a semantic slice to the MUI theme (augmenting @mui/material/styles) -with surface/border/text colors, resolved per light/dark mode by -getSemanticColors. AppTheme publishes these as CSS custom properties.

-

Interfaces

SemanticColors

Type Aliases

SemanticColorMode

Functions

getSemanticColors
diff --git a/vet/lib/modules/src_shared-theme_themePrimitives.html b/vet/lib/modules/src_shared-theme_themePrimitives.html deleted file mode 100644 index ca7cb69..0000000 --- a/vet/lib/modules/src_shared-theme_themePrimitives.html +++ /dev/null @@ -1,6 +0,0 @@ -src/shared-theme/themePrimitives | vet

Module src/shared-theme/themePrimitives

Base design tokens and palettes for the Veterinary Clinic theme.

-

Defines the raw color ramps (brand, gray, green, orange, red), the -light/dark design tokens (getDesignTokens), and the colorSchemes, -typography, shape and shadows primitives. Also augments MUI's theme -types with the ColorRange, flows and baseShadow extensions.

-

Variables

brand
colorSchemes
gray
green
orange
red
shadows
shape
typography

Functions

getDesignTokens
diff --git a/vet/lib/modules/src_vite-env.html b/vet/lib/modules/src_vite-env.html deleted file mode 100644 index 269573b..0000000 --- a/vet/lib/modules/src_vite-env.html +++ /dev/null @@ -1 +0,0 @@ -src/vite-env | vet

Module src/vite-env

Interfaces

ImportMeta
ImportMetaEnv
diff --git a/vet/lib/types/src_shared-theme_AppTheme.ColorMode.html b/vet/lib/types/src_shared-theme_AppTheme.ColorMode.html deleted file mode 100644 index 09da8ba..0000000 --- a/vet/lib/types/src_shared-theme_AppTheme.ColorMode.html +++ /dev/null @@ -1,2 +0,0 @@ -ColorMode | vet
ColorMode: "light" | "dark"

Color mode of the app theme.

-
diff --git a/vet/lib/types/src_shared-theme_themeConfig.SemanticColorMode.html b/vet/lib/types/src_shared-theme_themeConfig.SemanticColorMode.html deleted file mode 100644 index 2070797..0000000 --- a/vet/lib/types/src_shared-theme_themeConfig.SemanticColorMode.html +++ /dev/null @@ -1,2 +0,0 @@ -SemanticColorMode | vet
SemanticColorMode: "light" | "dark"

Color mode supported by the semantic tokens.

-
diff --git a/vet/lib/variables/src_openapi-config.specConfiguration.html b/vet/lib/variables/src_openapi-config.specConfiguration.html deleted file mode 100644 index efa1686..0000000 --- a/vet/lib/variables/src_openapi-config.specConfiguration.html +++ /dev/null @@ -1,8 +0,0 @@ -specConfiguration | vet

Variable specConfigurationConst

specConfiguration: SpecConfiguration = ...

The SpecConfiguration passed to AppProvider.

-
    -
  • specUrl / baseApiUrl - derived from VITE_API_BASE_URL.
  • -
  • title - "Veterinary Clinic".
  • -
  • resourceConfig.appointments.filterOptions.mode - "client".
  • -
-

getToken is intentionally left commented out; this demo has no auth.

-
diff --git a/vet/lib/variables/src_shared-theme_AppTheme.ColorModeContext.html b/vet/lib/variables/src_shared-theme_AppTheme.ColorModeContext.html deleted file mode 100644 index 3f5d17e..0000000 --- a/vet/lib/variables/src_shared-theme_AppTheme.ColorModeContext.html +++ /dev/null @@ -1,2 +0,0 @@ -ColorModeContext | vet

Variable ColorModeContextConst

ColorModeContext: Context<ColorModeContextValue> = ...

Context giving the current color mode and its setters.

-
diff --git a/vet/lib/variables/src_shared-theme_customizations_dataDisplay.dataDisplayCustomizations.html b/vet/lib/variables/src_shared-theme_customizations_dataDisplay.dataDisplayCustomizations.html deleted file mode 100644 index 46c6607..0000000 --- a/vet/lib/variables/src_shared-theme_customizations_dataDisplay.dataDisplayCustomizations.html +++ /dev/null @@ -1,2 +0,0 @@ -dataDisplayCustomizations | vet
dataDisplayCustomizations: Components<Theme> = ...

Component overrides for lists, chips, table pagination and icons.

-
diff --git a/vet/lib/variables/src_shared-theme_customizations_feedback.feedbackCustomizations.html b/vet/lib/variables/src_shared-theme_customizations_feedback.feedbackCustomizations.html deleted file mode 100644 index e44a6fa..0000000 --- a/vet/lib/variables/src_shared-theme_customizations_feedback.feedbackCustomizations.html +++ /dev/null @@ -1,2 +0,0 @@ -feedbackCustomizations | vet
feedbackCustomizations: Components<Theme> = ...

Component overrides for alerts, dialogs and linear progress.

-
diff --git a/vet/lib/variables/src_shared-theme_customizations_inputs.inputsCustomizations.html b/vet/lib/variables/src_shared-theme_customizations_inputs.inputsCustomizations.html deleted file mode 100644 index e721073..0000000 --- a/vet/lib/variables/src_shared-theme_customizations_inputs.inputsCustomizations.html +++ /dev/null @@ -1,2 +0,0 @@ -inputsCustomizations | vet
inputsCustomizations: Components<Theme> = ...

Component overrides for buttons, toggles, inputs and labels.

-
diff --git a/vet/lib/variables/src_shared-theme_customizations_navigation.navigationCustomizations.html b/vet/lib/variables/src_shared-theme_customizations_navigation.navigationCustomizations.html deleted file mode 100644 index def87ba..0000000 --- a/vet/lib/variables/src_shared-theme_customizations_navigation.navigationCustomizations.html +++ /dev/null @@ -1,2 +0,0 @@ -navigationCustomizations | vet
navigationCustomizations: Components<Theme> = ...

Component overrides for menus, selects, links, drawers, pagination and tabs.

-
diff --git a/vet/lib/variables/src_shared-theme_customizations_surfaces.surfacesCustomizations.html b/vet/lib/variables/src_shared-theme_customizations_surfaces.surfacesCustomizations.html deleted file mode 100644 index 5c0f5ac..0000000 --- a/vet/lib/variables/src_shared-theme_customizations_surfaces.surfacesCustomizations.html +++ /dev/null @@ -1,2 +0,0 @@ -surfacesCustomizations | vet
surfacesCustomizations: Components<Theme> = ...

Component overrides for accordions, paper and cards.

-
diff --git a/vet/lib/variables/src_shared-theme_themePrimitives.brand.html b/vet/lib/variables/src_shared-theme_themePrimitives.brand.html deleted file mode 100644 index d187b13..0000000 --- a/vet/lib/variables/src_shared-theme_themePrimitives.brand.html +++ /dev/null @@ -1,2 +0,0 @@ -brand | vet
brand: {
    "100": string;
    "200": string;
    "300": string;
    "400": string;
    "50": string;
    "500": string;
    "600": string;
    "700": string;
    "800": string;
    "900": string;
} = ...

Brand blue color ramp (50-900).

-

Type declaration

  • 100: string
  • 200: string
  • 300: string
  • 400: string
  • 50: string
  • 500: string
  • 600: string
  • 700: string
  • 800: string
  • 900: string
diff --git a/vet/lib/variables/src_shared-theme_themePrimitives.colorSchemes.html b/vet/lib/variables/src_shared-theme_themePrimitives.colorSchemes.html deleted file mode 100644 index adfbada..0000000 --- a/vet/lib/variables/src_shared-theme_themePrimitives.colorSchemes.html +++ /dev/null @@ -1,2 +0,0 @@ -colorSchemes | vet
colorSchemes: {
    dark: {
        palette: {
            action: { hover: string; selected: string };
            background: { default: string; paper: string };
            baseShadow: string;
            divider: string;
            error: { dark: string; light: string; main: string };
            flows: {
                inflows: { primary: string; surface: string; text: string };
                outflows: { primary: string; surface: string; text: string };
            };
            grey: {
                "100": string;
                "200": string;
                "300": string;
                "400": string;
                "50": string;
                "500": string;
                "600": string;
                "700": string;
                "750": string;
                "800": string;
                "850": string;
                "900": string;
            };
            info: { contrastText: string; dark: string; light: string; main: string };
            primary: {
                contrastText: string;
                dark: string;
                light: string;
                main: string;
            };
            success: { dark: string; light: string; main: string };
            text: { primary: string; secondary: string };
            warning: { dark: string; light: string; main: string };
        };
    };
    light: {
        palette: {
            action: { hover: string; selected: string };
            background: { default: string; paper: string };
            baseShadow: string;
            divider: string;
            error: { dark: string; light: string; main: string };
            flows: {
                inflows: { primary: string; surface: string; text: string };
                outflows: { primary: string; surface: string; text: string };
            };
            grey: {
                "100": string;
                "200": string;
                "300": string;
                "400": string;
                "50": string;
                "500": string;
                "600": string;
                "700": string;
                "750": string;
                "800": string;
                "850": string;
                "900": string;
            };
            info: { contrastText: string; dark: string; light: string; main: string };
            primary: {
                contrastText: string;
                dark: string;
                light: string;
                main: string;
            };
            success: { dark: string; light: string; main: string };
            text: { primary: string; secondary: string; warning: string };
            warning: { dark: string; light: string; main: string };
        };
    };
} = ...

Explicit light/dark colorSchemes palette definitions.

-

Type declaration

  • dark: {
        palette: {
            action: { hover: string; selected: string };
            background: { default: string; paper: string };
            baseShadow: string;
            divider: string;
            error: { dark: string; light: string; main: string };
            flows: {
                inflows: { primary: string; surface: string; text: string };
                outflows: { primary: string; surface: string; text: string };
            };
            grey: {
                "100": string;
                "200": string;
                "300": string;
                "400": string;
                "50": string;
                "500": string;
                "600": string;
                "700": string;
                "750": string;
                "800": string;
                "850": string;
                "900": string;
            };
            info: { contrastText: string; dark: string; light: string; main: string };
            primary: {
                contrastText: string;
                dark: string;
                light: string;
                main: string;
            };
            success: { dark: string; light: string; main: string };
            text: { primary: string; secondary: string };
            warning: { dark: string; light: string; main: string };
        };
    }
  • light: {
        palette: {
            action: { hover: string; selected: string };
            background: { default: string; paper: string };
            baseShadow: string;
            divider: string;
            error: { dark: string; light: string; main: string };
            flows: {
                inflows: { primary: string; surface: string; text: string };
                outflows: { primary: string; surface: string; text: string };
            };
            grey: {
                "100": string;
                "200": string;
                "300": string;
                "400": string;
                "50": string;
                "500": string;
                "600": string;
                "700": string;
                "750": string;
                "800": string;
                "850": string;
                "900": string;
            };
            info: { contrastText: string; dark: string; light: string; main: string };
            primary: {
                contrastText: string;
                dark: string;
                light: string;
                main: string;
            };
            success: { dark: string; light: string; main: string };
            text: { primary: string; secondary: string; warning: string };
            warning: { dark: string; light: string; main: string };
        };
    }
diff --git a/vet/lib/variables/src_shared-theme_themePrimitives.gray.html b/vet/lib/variables/src_shared-theme_themePrimitives.gray.html deleted file mode 100644 index 96907ea..0000000 --- a/vet/lib/variables/src_shared-theme_themePrimitives.gray.html +++ /dev/null @@ -1,2 +0,0 @@ -gray | vet
gray: {
    "100": string;
    "200": string;
    "300": string;
    "400": string;
    "50": string;
    "500": string;
    "600": string;
    "700": string;
    "750": string;
    "800": string;
    "850": string;
    "900": string;
} = ...

Neutral gray color ramp (50-900, plus 750/850).

-

Type declaration

  • 100: string
  • 200: string
  • 300: string
  • 400: string
  • 50: string
  • 500: string
  • 600: string
  • 700: string
  • 750: string
  • 800: string
  • 850: string
  • 900: string
diff --git a/vet/lib/variables/src_shared-theme_themePrimitives.green.html b/vet/lib/variables/src_shared-theme_themePrimitives.green.html deleted file mode 100644 index 873dbee..0000000 --- a/vet/lib/variables/src_shared-theme_themePrimitives.green.html +++ /dev/null @@ -1,2 +0,0 @@ -green | vet
green: {
    "100": string;
    "200": string;
    "300": string;
    "400": string;
    "50": string;
    "500": string;
    "600": string;
    "700": string;
    "800": string;
    "900": string;
} = ...

Green (success) color ramp (50-900).

-

Type declaration

  • 100: string
  • 200: string
  • 300: string
  • 400: string
  • 50: string
  • 500: string
  • 600: string
  • 700: string
  • 800: string
  • 900: string
diff --git a/vet/lib/variables/src_shared-theme_themePrimitives.orange.html b/vet/lib/variables/src_shared-theme_themePrimitives.orange.html deleted file mode 100644 index 2b1d29f..0000000 --- a/vet/lib/variables/src_shared-theme_themePrimitives.orange.html +++ /dev/null @@ -1,2 +0,0 @@ -orange | vet
orange: {
    "100": string;
    "200": string;
    "300": string;
    "400": string;
    "50": string;
    "500": string;
    "600": string;
    "700": string;
    "800": string;
    "900": string;
} = ...

Orange (warning) color ramp (50-900).

-

Type declaration

  • 100: string
  • 200: string
  • 300: string
  • 400: string
  • 50: string
  • 500: string
  • 600: string
  • 700: string
  • 800: string
  • 900: string
diff --git a/vet/lib/variables/src_shared-theme_themePrimitives.red.html b/vet/lib/variables/src_shared-theme_themePrimitives.red.html deleted file mode 100644 index b8a1565..0000000 --- a/vet/lib/variables/src_shared-theme_themePrimitives.red.html +++ /dev/null @@ -1,2 +0,0 @@ -red | vet
red: {
    "100": string;
    "200": string;
    "300": string;
    "400": string;
    "50": string;
    "500": string;
    "600": string;
    "700": string;
    "800": string;
    "900": string;
} = ...

Red (error) color ramp (50-900).

-

Type declaration

  • 100: string
  • 200: string
  • 300: string
  • 400: string
  • 50: string
  • 500: string
  • 600: string
  • 700: string
  • 800: string
  • 900: string
diff --git a/vet/lib/variables/src_shared-theme_themePrimitives.shadows.html b/vet/lib/variables/src_shared-theme_themePrimitives.shadows.html deleted file mode 100644 index 559ace1..0000000 --- a/vet/lib/variables/src_shared-theme_themePrimitives.shadows.html +++ /dev/null @@ -1,2 +0,0 @@ -shadows | vet
shadows: Shadows = defaultShadows

Shadow scale (index 0 none, index 1 the template baseShadow).

-
diff --git a/vet/lib/variables/src_shared-theme_themePrimitives.shape.html b/vet/lib/variables/src_shared-theme_themePrimitives.shape.html deleted file mode 100644 index 1a00986..0000000 --- a/vet/lib/variables/src_shared-theme_themePrimitives.shape.html +++ /dev/null @@ -1,2 +0,0 @@ -shape | vet
shape: { borderRadius: number } = ...

Shape tokens (global border radius).

-

Type declaration

  • borderRadius: number
diff --git a/vet/lib/variables/src_shared-theme_themePrimitives.typography.html b/vet/lib/variables/src_shared-theme_themePrimitives.typography.html deleted file mode 100644 index 137f567..0000000 --- a/vet/lib/variables/src_shared-theme_themePrimitives.typography.html +++ /dev/null @@ -1,2 +0,0 @@ -typography | vet
typography: {
    body1: { fontSize: string };
    body2: { fontSize: string; fontWeight: number };
    caption: { fontSize: string; fontWeight: number };
    fontFamily: string;
    h1: {
        fontSize: string;
        fontWeight: number;
        letterSpacing: number;
        lineHeight: number;
    };
    h2: { fontSize: string; fontWeight: number; lineHeight: number };
    h3: { fontSize: string; lineHeight: number };
    h4: { fontSize: string; fontWeight: number; lineHeight: number };
    h5: { fontSize: string; fontWeight: number };
    h6: { fontSize: string; fontWeight: number };
    subtitle1: { fontSize: string };
    subtitle2: { fontSize: string; fontWeight: number };
} = ...

Typography scale (Inter) used by the theme.

-

Type declaration

  • body1: { fontSize: string }
  • body2: { fontSize: string; fontWeight: number }
  • caption: { fontSize: string; fontWeight: number }
  • fontFamily: string
  • h1: {
        fontSize: string;
        fontWeight: number;
        letterSpacing: number;
        lineHeight: number;
    }
  • h2: { fontSize: string; fontWeight: number; lineHeight: number }
  • h3: { fontSize: string; lineHeight: number }
  • h4: { fontSize: string; fontWeight: number; lineHeight: number }
  • h5: { fontSize: string; fontWeight: number }
  • h6: { fontSize: string; fontWeight: number }
  • subtitle1: { fontSize: string }
  • subtitle2: { fontSize: string; fontWeight: number }
diff --git a/vet/mcp/index.json b/vet/mcp/index.json deleted file mode 100644 index 1defb38..0000000 --- a/vet/mcp/index.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "project": "vet", - "type": "docforge-model", - "modules_count": 14, - "source": "doc-weaver" -} diff --git a/vet/mcp/modules/Footer.json b/vet/mcp/modules/Footer.json deleted file mode 100644 index e10b04c..0000000 --- a/vet/mcp/modules/Footer.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "module": "Footer", - "content": { - "path": "Footer", - "docstring": "Site footer for the Veterinary Clinic demo app.\r\n\r\nA fixed bottom `AppBar` (pinned above the drawer via\r\n`zIndex.drawer + 1`) with a blurred translucent background and a top\r\ndivider, rendering the `Copyright` line. Rendered once by `main.jsx` below\r\nthe routed content.", - "objects": { - "Footer": { - "name": "Footer", - "kind": "component", - "path": "Footer.Footer", - "signature": "default(): React.JSX.Element", - "docstring": "Fixed bottom app bar showing the site copyright.\n\n**Returns:**\n\nThe footer `AppBar` element." - } - } - } -} diff --git a/vet/mcp/modules/Header.json b/vet/mcp/modules/Header.json deleted file mode 100644 index bd8a50b..0000000 --- a/vet/mcp/modules/Header.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "module": "Header", - "content": { - "path": "Header", - "docstring": "Top navigation bar for the Veterinary Clinic demo app.\r\n\r\nA fixed `AppBar` with blurred translucent background and bottom divider,\r\nshowing the app title/logo and an Admin button. Rendered once by `main.jsx`\r\nabove the routed content; the title navigates to `/` and the Admin button to\r\n`/admin`.", - "objects": { - "Header": { - "name": "Header", - "kind": "component", - "path": "Header.Header", - "signature": "default(): React.JSX.Element", - "docstring": "Fixed top app bar with the title/logo and an Admin button.\r\n\r\nUses `useNavigate`, so it must be rendered inside a router. Clicking the\r\ntitle navigates to `/`; the Admin button navigates to `/admin`.\n\n**Returns:**\n\nThe header `AppBar` element." - } - } - } -} diff --git a/vet/mcp/modules/Home.json b/vet/mcp/modules/Home.json deleted file mode 100644 index 1a1c60f..0000000 --- a/vet/mcp/modules/Home.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "module": "Home", - "content": { - "path": "Home", - "docstring": "Landing page for the Veterinary Clinic demo app.\r\n\r\nExercises the `react-openapi` building blocks end-to-end:\r\n- `ResourceCard` - a grid of every top-level resource with a live record\r\n count (or SSE connection status for streaming resources).\r\n- `LiveTable` - preview of the first 5 records of the first non-streaming\r\n resource.\r\n- `ApptForm` - a hand-crafted appointment form using `FormFieldRenderer`,\r\n `useResource().create()` and auto-loaded FK options.\r\n- An optional live `SseStreamView` with a pet selector for a streaming\r\n resource.", - "objects": { - "Home": { - "name": "Home", - "kind": "component", - "path": "Home.Home", - "signature": "default(): React.JSX.Element", - "docstring": "Render the demo landing page: resource grid, live preview, appointment form\r\nand (when present) a live SSE stream.\n\n**Returns:**\n\nThe page container, or a \"no resources\" notice when the spec\r\nexposes none." - } - } - } -} diff --git a/vet/mcp/modules/main.json b/vet/mcp/modules/main.json deleted file mode 100644 index d6672bb..0000000 --- a/vet/mcp/modules/main.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "module": "main", - "content": { - "path": "main", - "docstring": "Application entry point.\r\n\r\nCreates the React root from `#root` and mounts the app: `AppProvider`\r\n(fed by `specConfiguration`) wraps a `BrowserRouter` → `AppTheme` →\r\n`Header` → routed content (`Home` at `/`, `Admin` at `/admin/*`) →\r\n`Footer`.", - "objects": {} - } -} diff --git a/vet/mcp/modules/openapi-config.json b/vet/mcp/modules/openapi-config.json deleted file mode 100644 index c82d424..0000000 --- a/vet/mcp/modules/openapi-config.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "module": "openapi-config", - "content": { - "path": "openapi-config", - "docstring": "Runtime OpenAPI configuration for the Veterinary Clinic demo.\r\n\r\nReads the API base URL from `import.meta.env.VITE_API_BASE_URL` and points\r\n`react-openapi` at `${base}/openapi.json`, sets the app title, and enables\r\nclient-side filtering for the `appointments` resource.", - "objects": { - "specConfiguration": { - "name": "specConfiguration", - "kind": "variable", - "path": "openapi-config.specConfiguration", - "signature": "specConfiguration: SpecConfiguration", - "docstring": "The `SpecConfiguration` passed to `AppProvider`.\r\n\r\n- `specUrl` / `baseApiUrl` - derived from `VITE_API_BASE_URL`.\r\n- `title` - \"Veterinary Clinic\".\r\n- `resourceConfig.appointments.filterOptions.mode` - `\"client\"`.\r\n\r\n`getToken` is intentionally left commented out; this demo has no auth." - } - } - } -} diff --git a/vet/mcp/modules/shared-theme.AppTheme.json b/vet/mcp/modules/shared-theme.AppTheme.json deleted file mode 100644 index 6977a0e..0000000 --- a/vet/mcp/modules/shared-theme.AppTheme.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "module": "shared-theme.AppTheme", - "content": { - "path": "shared-theme.AppTheme", - "docstring": "App theme provider and color-mode context.\r\n\r\nWraps the MUI `ThemeProvider` with the design tokens (`getDesignTokens`),\r\nsemantic colors (`getSemanticColors`) and component customizations\r\n(`inputsCustomizations`, `dataDisplayCustomizations`,\r\n`feedbackCustomizations`, `navigationCustomizations`,\r\n`surfacesCustomizations`). Exposes a light/dark `ColorModeContext` and\r\npublishes the semantic colors as CSS custom properties (`--bg-page`,\r\n`--bg-card`, `--text-primary`, ...) for the app subtree.", - "objects": { - "ColorMode": { - "name": "ColorMode", - "kind": "type-alias", - "path": "shared-theme.AppTheme.ColorMode", - "signature": "ColorMode: \"light\" | \"dark\"", - "docstring": "Color mode of the app theme." - }, - "ColorModeContext": { - "name": "ColorModeContext", - "kind": "component", - "path": "shared-theme.AppTheme.ColorModeContext", - "signature": "ColorModeContext: React.Context", - "docstring": "Context giving the current color mode and its setters." - }, - "AppTheme": { - "name": "AppTheme", - "kind": "component", - "path": "shared-theme.AppTheme.AppTheme", - "signature": "default(__namedParameters: AppThemeProps): React.JSX.Element", - "docstring": "Provide the MUI theme, color-mode context and CSS variables to `children`.\r\n\r\nBuilds the theme from `getDesignTokens(mode)` + `getSemanticColors(mode)` +\r\nthe component customizations, and re-creates it whenever the mode changes.\r\nAlso sets `--bg-page`, `--bg-card`, `--bg-elevated`, `--border-default`,\r\n`--border-subtle`, `--text-primary`, `--text-secondary` and `--text-muted`\r\non a wrapper `Box`.\r\n\r\nProps: `children` and `defaultMode` (see `AppThemeProps`).\n\n**Example:**\n\n```tsx\r\n\r\n \r\n \r\n\r\n```" - } - } - } -} diff --git a/vet/mcp/modules/shared-theme.customizations.dataDisplay.json b/vet/mcp/modules/shared-theme.customizations.dataDisplay.json deleted file mode 100644 index 3201b5a..0000000 --- a/vet/mcp/modules/shared-theme.customizations.dataDisplay.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "module": "shared-theme.customizations.dataDisplay", - "content": { - "path": "shared-theme.customizations.dataDisplay", - "docstring": "MUI style overrides for data-display components.\n\nExports `dataDisplayCustomizations`, a `Components` map applied by\n`AppTheme`, covering lists, chips, table pagination and icons.", - "objects": { - "dataDisplayCustomizations": { - "name": "dataDisplayCustomizations", - "kind": "variable", - "path": "shared-theme.customizations.dataDisplay.dataDisplayCustomizations", - "signature": "dataDisplayCustomizations: Components", - "docstring": "Component overrides for lists, chips, table pagination and icons." - } - } - } -} diff --git a/vet/mcp/modules/shared-theme.customizations.feedback.json b/vet/mcp/modules/shared-theme.customizations.feedback.json deleted file mode 100644 index 72be1b1..0000000 --- a/vet/mcp/modules/shared-theme.customizations.feedback.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "module": "shared-theme.customizations.feedback", - "content": { - "path": "shared-theme.customizations.feedback", - "docstring": "MUI style overrides for feedback components.\r\n\r\nExports `feedbackCustomizations`, a `Components` map applied by\r\n`AppTheme`, covering alerts, dialogs and linear progress.", - "objects": { - "feedbackCustomizations": { - "name": "feedbackCustomizations", - "kind": "variable", - "path": "shared-theme.customizations.feedback.feedbackCustomizations", - "signature": "feedbackCustomizations: Components", - "docstring": "Component overrides for alerts, dialogs and linear progress." - } - } - } -} diff --git a/vet/mcp/modules/shared-theme.customizations.inputs.json b/vet/mcp/modules/shared-theme.customizations.inputs.json deleted file mode 100644 index c767f05..0000000 --- a/vet/mcp/modules/shared-theme.customizations.inputs.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "module": "shared-theme.customizations.inputs", - "content": { - "path": "shared-theme.customizations.inputs", - "docstring": "MUI style overrides for form inputs and buttons.\r\n\r\nExports `inputsCustomizations`, a `Components` map applied by\r\n`AppTheme`, covering buttons, icon buttons, toggles, checkbox, outlined\r\ninputs and form labels with light/dark variants.", - "objects": { - "inputsCustomizations": { - "name": "inputsCustomizations", - "kind": "variable", - "path": "shared-theme.customizations.inputs.inputsCustomizations", - "signature": "inputsCustomizations: Components", - "docstring": "Component overrides for buttons, toggles, inputs and labels." - } - } - } -} diff --git a/vet/mcp/modules/shared-theme.customizations.navigation.json b/vet/mcp/modules/shared-theme.customizations.navigation.json deleted file mode 100644 index 5fe48e2..0000000 --- a/vet/mcp/modules/shared-theme.customizations.navigation.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "module": "shared-theme.customizations.navigation", - "content": { - "path": "shared-theme.customizations.navigation", - "docstring": "MUI style overrides for navigation components.\r\n\r\nExports `navigationCustomizations`, a `Components` map applied by\r\n`AppTheme`, covering menus, selects, links, drawers, pagination, tabs and\r\nsteppers.", - "objects": { - "navigationCustomizations": { - "name": "navigationCustomizations", - "kind": "variable", - "path": "shared-theme.customizations.navigation.navigationCustomizations", - "signature": "navigationCustomizations: Components", - "docstring": "Component overrides for menus, selects, links, drawers, pagination and tabs." - } - } - } -} diff --git a/vet/mcp/modules/shared-theme.customizations.surfaces.json b/vet/mcp/modules/shared-theme.customizations.surfaces.json deleted file mode 100644 index fd0d2d7..0000000 --- a/vet/mcp/modules/shared-theme.customizations.surfaces.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "module": "shared-theme.customizations.surfaces", - "content": { - "path": "shared-theme.customizations.surfaces", - "docstring": "MUI style overrides for surface components.\r\n\r\nExports `surfacesCustomizations`, a `Components` map applied by\r\n`AppTheme`, covering accordions, paper, cards and card sections.", - "objects": { - "surfacesCustomizations": { - "name": "surfacesCustomizations", - "kind": "variable", - "path": "shared-theme.customizations.surfaces.surfacesCustomizations", - "signature": "surfacesCustomizations: Components", - "docstring": "Component overrides for accordions, paper and cards." - } - } - } -} diff --git a/vet/mcp/modules/shared-theme.themeConfig.json b/vet/mcp/modules/shared-theme.themeConfig.json deleted file mode 100644 index dbfdf3d..0000000 --- a/vet/mcp/modules/shared-theme.themeConfig.json +++ /dev/null @@ -1,53 +0,0 @@ -{ - "module": "shared-theme.themeConfig", - "content": { - "path": "shared-theme.themeConfig", - "docstring": "Semantic (mode-aware) color tokens.\r\n\r\nAdds a `semantic` slice to the MUI theme (augmenting `@mui/material/styles`)\r\nwith surface/border/text colors, resolved per light/dark mode by\r\n`getSemanticColors`. `AppTheme` publishes these as CSS custom properties.", - "objects": { - "SemanticColors": { - "name": "SemanticColors", - "kind": "interface", - "path": "shared-theme.themeConfig.SemanticColors", - "signature": "SemanticColors", - "docstring": "Mode-aware semantic color groups attached to the MUI theme as\r\n`theme.semantic` and exposed as CSS custom properties by `AppTheme`.", - "members": { - "border": { - "name": "border", - "kind": "property", - "path": "shared-theme.themeConfig.SemanticColors.border", - "signature": "border: { default: string; subtle: string }", - "docstring": "Border colors." - }, - "surface": { - "name": "surface", - "kind": "property", - "path": "shared-theme.themeConfig.SemanticColors.surface", - "signature": "surface: { card: string; elevated: string; page: string }", - "docstring": "Background surface colors." - }, - "text": { - "name": "text", - "kind": "property", - "path": "shared-theme.themeConfig.SemanticColors.text", - "signature": "text: { muted: string; primary: string; secondary: string }", - "docstring": "Text colors." - } - } - }, - "SemanticColorMode": { - "name": "SemanticColorMode", - "kind": "type-alias", - "path": "shared-theme.themeConfig.SemanticColorMode", - "signature": "SemanticColorMode: \"light\" | \"dark\"", - "docstring": "Color mode supported by the semantic tokens." - }, - "getSemanticColors": { - "name": "getSemanticColors", - "kind": "function", - "path": "shared-theme.themeConfig.getSemanticColors", - "signature": "getSemanticColors(mode: SemanticColorMode): SemanticColors", - "docstring": "Resolve the semantic color groups for a color mode.\r\n\r\nDark mode uses fixed HSL values; light mode derives borders/text from the\r\n`gray` ramp (with `alpha`).\n\n**Parameters:**\n\n- `mode` — `\"light\"` or `\"dark\"`.\n\n**Returns:**\n\nThe `SemanticColors` for that mode.\n\n**Example:**\n\n```ts\r\nconst colors = getSemanticColors(\"dark\");\r\ncolors.surface.page; // \"hsl(0, 0%, 9%)\"\r\n```" - } - } - } -} diff --git a/vet/mcp/modules/shared-theme.themePrimitives.json b/vet/mcp/modules/shared-theme.themePrimitives.json deleted file mode 100644 index 50dfcf2..0000000 --- a/vet/mcp/modules/shared-theme.themePrimitives.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "module": "shared-theme.themePrimitives", - "content": { - "path": "shared-theme.themePrimitives", - "docstring": "Base design tokens and palettes for the Veterinary Clinic theme.\r\n\r\nDefines the raw color ramps (`brand`, `gray`, `green`, `orange`, `red`), the\r\nlight/dark design tokens (`getDesignTokens`), and the `colorSchemes`,\r\n`typography`, `shape` and `shadows` primitives. Also augments MUI's theme\r\ntypes with the `ColorRange`, `flows` and `baseShadow` extensions.", - "objects": { - "brand": { - "name": "brand", - "kind": "variable", - "path": "shared-theme.themePrimitives.brand", - "signature": "brand: { 100: string; 200: string; 300: string; 400: string; 50: string; 500: string; 600: string; 700: string; 800: string; 900: string }", - "docstring": "Brand blue color ramp (50-900)." - }, - "colorSchemes": { - "name": "colorSchemes", - "kind": "variable", - "path": "shared-theme.themePrimitives.colorSchemes", - "signature": "colorSchemes: { dark: { palette: { action: { hover: string; selected: string }; background: { default: string; paper: string }; baseShadow: string; divider: string; error: { dark: string; light: string; main: string }; flows: { inflows: { primary: string; surface: string; text: string }; outflows: { primary: string; surface: string; text: string } }; grey: { 100: string; 200: string; 300: string; 400: string; 50: string; 500: string; 600: string; 700: string; 750: string; 800: string; 850: string; 900: string }; info: { contrastText: string; dark: string; light: string; main: string }; primary: { contrastText: string; dark: string; light: string; main: string }; success: { dark: string; light: string; main: string }; text: { primary: string; secondary: string }; warning: { dark: string; light: string; main: string } } }; light: { palette: { action: { hover: string; selected: string }; background: { default: string; paper: string }; baseShadow: string; divider: string; error: { dark: string; light: string; main: string }; flows: { inflows: { primary: string; surface: string; text: string }; outflows: { primary: string; surface: string; text: string } }; grey: { 100: string; 200: string; 300: string; 400: string; 50: string; 500: string; 600: string; 700: string; 750: string; 800: string; 850: string; 900: string }; info: { contrastText: string; dark: string; light: string; main: string }; primary: { contrastText: string; dark: string; light: string; main: string }; success: { dark: string; light: string; main: string }; text: { primary: string; secondary: string; warning: string }; warning: { dark: string; light: string; main: string } } } }", - "docstring": "Explicit light/dark `colorSchemes` palette definitions." - }, - "gray": { - "name": "gray", - "kind": "variable", - "path": "shared-theme.themePrimitives.gray", - "signature": "gray: { 100: string; 200: string; 300: string; 400: string; 50: string; 500: string; 600: string; 700: string; 750: string; 800: string; 850: string; 900: string }", - "docstring": "Neutral gray color ramp (50-900, plus 750/850)." - }, - "green": { - "name": "green", - "kind": "variable", - "path": "shared-theme.themePrimitives.green", - "signature": "green: { 100: string; 200: string; 300: string; 400: string; 50: string; 500: string; 600: string; 700: string; 800: string; 900: string }", - "docstring": "Green (success) color ramp (50-900)." - }, - "orange": { - "name": "orange", - "kind": "variable", - "path": "shared-theme.themePrimitives.orange", - "signature": "orange: { 100: string; 200: string; 300: string; 400: string; 50: string; 500: string; 600: string; 700: string; 800: string; 900: string }", - "docstring": "Orange (warning) color ramp (50-900)." - }, - "red": { - "name": "red", - "kind": "variable", - "path": "shared-theme.themePrimitives.red", - "signature": "red: { 100: string; 200: string; 300: string; 400: string; 50: string; 500: string; 600: string; 700: string; 800: string; 900: string }", - "docstring": "Red (error) color ramp (50-900)." - }, - "shadows": { - "name": "shadows", - "kind": "variable", - "path": "shared-theme.themePrimitives.shadows", - "signature": "shadows: Shadows", - "docstring": "Shadow scale (index 0 `none`, index 1 the template `baseShadow`)." - }, - "shape": { - "name": "shape", - "kind": "variable", - "path": "shared-theme.themePrimitives.shape", - "signature": "shape: { borderRadius: number }", - "docstring": "Shape tokens (global border radius)." - }, - "typography": { - "name": "typography", - "kind": "variable", - "path": "shared-theme.themePrimitives.typography", - "signature": "typography: { body1: { fontSize: string }; body2: { fontSize: string; fontWeight: number }; caption: { fontSize: string; fontWeight: number }; fontFamily: string; h1: { fontSize: string; fontWeight: number; letterSpacing: number; lineHeight: number }; h2: { fontSize: string; fontWeight: number; lineHeight: number }; h3: { fontSize: string; lineHeight: number }; h4: { fontSize: string; fontWeight: number; lineHeight: number }; h5: { fontSize: string; fontWeight: number }; h6: { fontSize: string; fontWeight: number }; subtitle1: { fontSize: string }; subtitle2: { fontSize: string; fontWeight: number } }", - "docstring": "Typography scale (Inter) used by the theme." - }, - "getDesignTokens": { - "name": "getDesignTokens", - "kind": "function", - "path": "shared-theme.themePrimitives.getDesignTokens", - "signature": "getDesignTokens(mode: PaletteMode): { palette: { action: { hover: string; selected: string }; background: { default: string; paper: string }; divider: string; error: { dark: string; light: string; main: string }; flows: { inflows: { primary: string; surface: string; text: string }; outflows: { primary: string; surface: string; text: string } }; grey: { 100: string; 200: string; 300: string; 400: string; 50: string; 500: string; 600: string; 700: string; 750: string; 800: string; 850: string; 900: string }; info: { contrastText: string; dark: string; light: string; main: string }; mode: PaletteMode; primary: { contrastText: string; dark: string; light: string; main: string }; success: { dark: string; light: string; main: string }; text: { primary: string; secondary: string; warning: string }; warning: { dark: string; light: string; main: string } }; shadows: Shadows; shape: { borderRadius: number }; typography: { body1: { fontSize: string }; body2: { fontSize: string; fontWeight: number }; caption: { fontSize: string; fontWeight: number }; fontFamily: string; h1: { fontSize: string; fontWeight: number; letterSpacing: number; lineHeight: number }; h2: { fontSize: string; fontWeight: number; lineHeight: number }; h3: { fontSize: string; lineHeight: number }; h4: { fontSize: string; fontWeight: number; lineHeight: number }; h5: { fontSize: string; fontWeight: number }; h6: { fontSize: string; fontWeight: number }; subtitle1: { fontSize: string }; subtitle2: { fontSize: string; fontWeight: number } } }", - "docstring": "Build the MUI design tokens (palette, typography, shape, shadows) for a mode.\r\n\r\nLight and dark palettes share the ramps but override specific slots in dark\r\nmode. Also sets `shadows[1]` (the \"baseShadow\") per mode. The returned object\r\nis spread into `createTheme` by `AppTheme`.\n\n**Parameters:**\n\n- `mode` — `\"light\"` or `\"dark\"`.\n\n**Returns:**\n\nA MUI `ThemeOptions`-shaped object (palette, typography, shape,\r\nshadows)." - } - } - } -} diff --git a/vet/mcp/modules/src_vite-env.json b/vet/mcp/modules/src_vite-env.json deleted file mode 100644 index 9ccd9f7..0000000 --- a/vet/mcp/modules/src_vite-env.json +++ /dev/null @@ -1,132 +0,0 @@ -{ - "module": "src_vite-env", - "content": { - "path": "src_vite-env", - "docstring": "", - "objects": { - "ImportMeta": { - "name": "ImportMeta", - "kind": "interface", - "path": "src_vite-env.ImportMeta", - "signature": "ImportMeta", - "docstring": "The type of `import.meta`.\n\nIf you need to declare that a given property exists on `import.meta`,\nthis type may be augmented via interface merging.", - "members": { - "dirname": { - "name": "dirname", - "kind": "property", - "path": "src_vite-env.ImportMeta.dirname", - "signature": "dirname: string", - "docstring": "" - }, - "env": { - "name": "env", - "kind": "property", - "path": "src_vite-env.ImportMeta.env", - "signature": "env: ImportMetaEnv", - "docstring": "" - }, - "filename": { - "name": "filename", - "kind": "property", - "path": "src_vite-env.ImportMeta.filename", - "signature": "filename: string", - "docstring": "" - }, - "glob": { - "name": "glob", - "kind": "property", - "path": "src_vite-env.ImportMeta.glob", - "signature": "glob: ImportGlobFunction", - "docstring": "" - }, - "hot": { - "name": "hot", - "kind": "property", - "path": "src_vite-env.ImportMeta.hot", - "signature": "hot: ViteHotContext", - "docstring": "" - }, - "main": { - "name": "main", - "kind": "property", - "path": "src_vite-env.ImportMeta.main", - "signature": "main: boolean", - "docstring": "" - }, - "url": { - "name": "url", - "kind": "property", - "path": "src_vite-env.ImportMeta.url", - "signature": "url: string", - "docstring": "" - }, - "resolve": { - "name": "resolve", - "kind": "method", - "path": "src_vite-env.ImportMeta.resolve", - "signature": "resolve(specifier: string): string | resolve(specifier: string, parent?: string | \"node:url\".URL): string", - "docstring": "" - } - } - }, - "ImportMetaEnv": { - "name": "ImportMetaEnv", - "kind": "interface", - "path": "src_vite-env.ImportMetaEnv", - "signature": "ImportMetaEnv", - "docstring": "", - "members": { - "BASE_URL": { - "name": "BASE_URL", - "kind": "property", - "path": "src_vite-env.ImportMetaEnv.BASE_URL", - "signature": "BASE_URL: string", - "docstring": "" - }, - "DEV": { - "name": "DEV", - "kind": "property", - "path": "src_vite-env.ImportMetaEnv.DEV", - "signature": "DEV: boolean", - "docstring": "" - }, - "MODE": { - "name": "MODE", - "kind": "property", - "path": "src_vite-env.ImportMetaEnv.MODE", - "signature": "MODE: string", - "docstring": "" - }, - "PROD": { - "name": "PROD", - "kind": "property", - "path": "src_vite-env.ImportMetaEnv.PROD", - "signature": "PROD: boolean", - "docstring": "" - }, - "SSR": { - "name": "SSR", - "kind": "property", - "path": "src_vite-env.ImportMetaEnv.SSR", - "signature": "SSR: boolean", - "docstring": "" - }, - "VITE_API_BASE_URL": { - "name": "VITE_API_BASE_URL", - "kind": "property", - "path": "src_vite-env.ImportMetaEnv.VITE_API_BASE_URL", - "signature": "VITE_API_BASE_URL: string", - "docstring": "" - }, - "VITE_AUTH_BASE_URL": { - "name": "VITE_AUTH_BASE_URL", - "kind": "property", - "path": "src_vite-env.ImportMetaEnv.VITE_AUTH_BASE_URL", - "signature": "VITE_AUTH_BASE_URL: string", - "docstring": "" - } - } - } - } - } -} diff --git a/vet/mcp/nav.json b/vet/mcp/nav.json deleted file mode 100644 index e3ab1aa..0000000 --- a/vet/mcp/nav.json +++ /dev/null @@ -1,58 +0,0 @@ -[ - { - "module": "Footer", - "resource": "docs://modules/Footer" - }, - { - "module": "Header", - "resource": "docs://modules/Header" - }, - { - "module": "Home", - "resource": "docs://modules/Home" - }, - { - "module": "main", - "resource": "docs://modules/main" - }, - { - "module": "openapi-config", - "resource": "docs://modules/openapi-config" - }, - { - "module": "shared-theme.AppTheme", - "resource": "docs://modules/shared-theme.AppTheme" - }, - { - "module": "shared-theme.customizations.dataDisplay", - "resource": "docs://modules/shared-theme.customizations.dataDisplay" - }, - { - "module": "shared-theme.customizations.feedback", - "resource": "docs://modules/shared-theme.customizations.feedback" - }, - { - "module": "shared-theme.customizations.inputs", - "resource": "docs://modules/shared-theme.customizations.inputs" - }, - { - "module": "shared-theme.customizations.navigation", - "resource": "docs://modules/shared-theme.customizations.navigation" - }, - { - "module": "shared-theme.customizations.surfaces", - "resource": "docs://modules/shared-theme.customizations.surfaces" - }, - { - "module": "shared-theme.themeConfig", - "resource": "docs://modules/shared-theme.themeConfig" - }, - { - "module": "shared-theme.themePrimitives", - "resource": "docs://modules/shared-theme.themePrimitives" - }, - { - "module": "src_vite-env", - "resource": "docs://modules/src_vite-env" - } -]