From a94f35800a6d6af52c46c71d8991c79e4a054e58 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Wed, 27 May 2026 18:20:51 +0200 Subject: [PATCH 01/61] feat(docs-site): redirect ktx.sh/slack to Slack community invite (#224) Add a host-scoped redirect for /slack on ktx.sh before the existing catch-all so the path resolves to the community invite link instead of docs.kaelio.com/ktx/slack. --- docs-site/next.config.mjs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs-site/next.config.mjs b/docs-site/next.config.mjs index 30a96741..b82803be 100644 --- a/docs-site/next.config.mjs +++ b/docs-site/next.config.mjs @@ -34,6 +34,14 @@ const config = { permanent: true, basePath: false, }, + { + source: "/slack", + has: [{ type: "host", value: "ktx.sh" }], + destination: + "https://join.slack.com/t/ktxcommunity/shared_invite/zt-3y9b44m1x-LVyNNJD5nwaZHq4XS29LMQ", + permanent: false, + basePath: false, + }, { source: "/:path*", has: [{ type: "host", value: "ktx.sh" }], From 6837ab253d6173d3270a8fdc08cff066d1137d1b Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Thu, 28 May 2026 02:09:53 +0200 Subject: [PATCH 02/61] fix(cli): align ingest step counter with SDK num_turns (#225) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Claude Code runtime counted every SDKAssistantMessage with parent_tool_use_id === null as a step, but the SDK emits extra messages within a single num_turns round-trip — `stop_reason: 'pause_turn'` continuations and errored partials it retries internally. The local counter then outran maxTurns and the ingest HUD rendered confusing ratios like `step 69/40`. Filter both cases in collectResult so stepIndex tracks num_turns and stays bounded by the work-unit stepBudget. --- .../src/context/llm/claude-code-runtime.ts | 18 +++++- .../context/llm/claude-code-runtime.test.ts | 58 +++++++++++++++++++ uv.lock | 4 +- 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/packages/cli/src/context/llm/claude-code-runtime.ts b/packages/cli/src/context/llm/claude-code-runtime.ts index 0eb3eadb..22055c28 100644 --- a/packages/cli/src/context/llm/claude-code-runtime.ts +++ b/packages/cli/src/context/llm/claude-code-runtime.ts @@ -58,6 +58,22 @@ function isResult(message: SDKMessage): message is SDKResultMessage { return message.type === 'result'; } +// Skip emissions the SDK does not count toward `num_turns`: `pause_turn` continuations and +// errored partials (e.g. `max_output_tokens`) it retries internally. Without this, the +// runtime's step counter outruns `maxTurns` and the HUD renders e.g. `step 69/40`. +function countsAsAssistantTurn(message: SDKMessage): boolean { + if (message.type !== 'assistant' || message.parent_tool_use_id !== null) { + return false; + } + if (message.error !== undefined) { + return false; + } + if (message.message.stop_reason === 'pause_turn') { + return false; + } + return true; +} + function resultError(result: SDKResultMessage): Error | undefined { if (result.subtype === 'success') { return undefined; @@ -190,7 +206,7 @@ async function collectResult(params: { let result: SDKResultMessage | undefined; for await (const message of params.query({ prompt: params.prompt, options: params.options })) { assertInitIsolation(message, params.allowedToolIds, params.expectedMcpServerNames); - if (message.type === 'assistant' && message.parent_tool_use_id === null) { + if (countsAsAssistantTurn(message)) { await params.onAssistantTurn?.(); } if (isResult(message)) { diff --git a/packages/cli/test/context/llm/claude-code-runtime.test.ts b/packages/cli/test/context/llm/claude-code-runtime.test.ts index 205c74e0..706d5d55 100644 --- a/packages/cli/test/context/llm/claude-code-runtime.test.ts +++ b/packages/cli/test/context/llm/claude-code-runtime.test.ts @@ -415,6 +415,64 @@ describe('ClaudeCodeKtxLlmRuntime', () => { ); }); + it('counts only assistant turns the SDK counts toward num_turns', async () => { + const assistantMessage = ( + overrides: Partial> & { uuid: string }, + ): SDKMessage => + ({ + type: 'assistant', + message: { role: 'assistant', content: [], stop_reason: 'end_turn' }, + parent_tool_use_id: null, + session_id: 'session-id', + ...overrides, + }) as unknown as SDKMessage; + + const query = vi.fn((_input: any) => + stream([ + initMessage(), + assistantMessage({ + uuid: '00000000-0000-4000-8000-0000000000a1', + error: 'max_output_tokens', + }), + assistantMessage({ + uuid: '00000000-0000-4000-8000-0000000000a2', + message: { role: 'assistant', content: [], stop_reason: 'pause_turn' } as never, + }), + assistantMessage({ uuid: '00000000-0000-4000-8000-0000000000a3' }), + { + type: 'assistant', + message: { role: 'assistant', content: [], stop_reason: 'end_turn' }, + parent_tool_use_id: 'tool-use-1', + uuid: '00000000-0000-4000-8000-0000000000a4', + session_id: 'session-id', + } as unknown as SDKMessage, + resultMessage({ subtype: 'success', terminal_reason: 'completed' }), + ]), + ); + const runtime = new ClaudeCodeKtxLlmRuntime({ + projectDir: '/tmp/project', + modelSlots: { default: 'sonnet' }, + query, + env: {}, + }); + const onStepFinish = vi.fn(); + + await expect( + runtime.runAgentLoop({ + modelRole: 'default', + systemPrompt: 'system', + userPrompt: 'user', + toolSet: {}, + stepBudget: 40, + telemetryTags: { operationName: 'test' }, + onStepFinish, + }), + ).resolves.toEqual({ stopReason: 'natural' }); + + expect(onStepFinish).toHaveBeenCalledTimes(1); + expect(onStepFinish).toHaveBeenCalledWith({ stepIndex: 1, stepBudget: 40 }); + }); + it('logs and ignores onStepFinish callback errors', async () => { const query = vi.fn((_input: any) => stream([ diff --git a/uv.lock b/uv.lock index 7c2c368f..25a8fab6 100644 --- a/uv.lock +++ b/uv.lock @@ -458,7 +458,7 @@ wheels = [ [[package]] name = "ktx-daemon" -version = "0.5.0" +version = "0.6.0" source = { editable = "python/ktx-daemon" } dependencies = [ { name = "fastapi" }, @@ -515,7 +515,7 @@ dev = [ [[package]] name = "ktx-sl" -version = "0.5.0" +version = "0.6.0" source = { editable = "python/ktx-sl" } dependencies = [ { name = "pydantic" }, From 27842e14a91233818715d792f798032a70b0cfe4 Mon Sep 17 00:00:00 2001 From: Luca Martial <48870843+luca-martial@users.noreply.github.com> Date: Thu, 28 May 2026 05:58:08 -0400 Subject: [PATCH 03/61] docs: add context layer terminology (#226) --- AGENTS.md | 20 ++++++++++++++++++++ docs/terminology.md | 38 +++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index 64ec2d4a..b5eccd67 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -323,6 +323,26 @@ use `PascalCase` without the suffix. source-code identifier, package/API name, or other literal value that must match the implementation. +### Product Category Naming + +- **MUST**: Use **context layer** as the primary public category for **ktx**. + Preferred phrase: `context layer for data agents`. +- **MUST**: Use **context engine** only as the secondary mechanism term for the + active system that builds, reconciles, validates, searches, and serves the + context layer. +- **MUST**: Keep **semantic layer** as the narrower term for executable metric + definitions, semantic sources, joins, measures, and SQL compilation. +- **MUST NOT**: Replace every `semantic layer` occurrence with `context layer`; + the semantic layer is one pillar inside the broader context layer. + +Preferred pattern: + +```md +**ktx** is an open-source context layer for data agents. Its context engine +ingests warehouse metadata, BI definitions, query history, docs, and approved +metrics, then turns them into reviewable files agents can search and execute. +``` + ### Terminology For canonical vocabulary used across docs, code, comments, CLI strings, and diff --git a/docs/terminology.md b/docs/terminology.md index 00be75e6..9da59456 100644 --- a/docs/terminology.md +++ b/docs/terminology.md @@ -21,6 +21,41 @@ in prose when ambiguity is possible. Always qualify: Bare `source` is allowed only inside a section that has already established its referent (e.g., body of a `Semantic sources` page, or `sourceName` as a CLI arg). +## Context Layer and Context Engine + +Use **context layer** as the primary category term for what **ktx** provides to +data agents. + +Use **context engine** as the secondary mechanism term for how **ktx** builds, +maintains, validates, and serves that layer. + +| Concept | Use | Do not use | +|---|---|---| +| The whole **ktx** product category | **context layer** / **context layer for data agents** | knowledge layer, agent memory | +| The active system that builds and maintains context | **context engine** | context layer when describing ingest/reconciliation internals | +| The durable reviewed surface agents use | **context layer** | context engine | +| The compiler pillar for executable metrics and joins | **semantic layer** | context layer when specifically discussing SQL compilation | +| Prose/business knowledge files | **wiki** / **wiki pages** | wiki context | + +### Usage rules + +- Use **context layer** in taglines, page titles, meta descriptions, docs + introductions, comparison pages, and first-paragraph definitions. +- Use **context engine** when describing active behavior: ingesting evidence, + reconciling changes, validating references, maintaining files, search, CLI, + and MCP serving. +- Keep **semantic layer** for the narrower YAML/compiler surface: semantic + sources, measures, joins, dimensions, filters, SQL compilation, and semantic + queries. +- Do not use **context engine** as the primary replacement for the whole + product. It sounds like runtime infrastructure; **context layer** better + describes the durable YAML and Markdown surface users review in git. +- Do not use **context layer** when the sentence is specifically about the + compiler. Example: write "the semantic layer compiles semantic queries to + SQL," not "the context layer compiles semantic queries to SQL." +- Default lowercase in prose: `context layer`, `context engine`, `semantic + layer`. Title case only in page titles, headings, nav labels, and UI labels. + ## Canonical vocabulary | Concept | Use | Do not use | @@ -31,7 +66,8 @@ referent (e.g., body of a `Semantic sources` page, or `sourceName` as a CLI arg) | The connected database | **primary source** / **database connection** | data source | | Analytics-tooling integration | **context source** / **context-source connection** | BI source, BI model, metadata source, source tool | | YAML file describing a table | **semantic source** | semantic-layer source, model file, bare "source file" | -| The whole **ktx** surface | **context layer** (lowercase in prose) | "Context Layer" in prose | +| The whole **ktx** surface | **context layer** / **context layer for data agents** (lowercase in prose) | "Context Layer" in prose, knowledge layer, agent memory | +| The active system that builds and maintains context | **context engine** (lowercase in prose) | context layer when describing ingest/reconciliation internals | | The compiler pillar | **semantic layer** (lowercase in prose) | "Semantic Layer" in prose | | The query payload | **semantic query** (lowercase in prose) | "Semantic Query" | | The MCP layer | **MCP server** (the server), **MCP tools** (the functions) | "ktx MCP" as a standalone noun | From 39f94f39ffce81ad7b5a635fb3327897533aea75 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Thu, 28 May 2026 12:28:10 +0200 Subject: [PATCH 04/61] docs: add ktx skills.sh setup skill (#227) --- README.md | 5 +- .../app/llms.mdx/docs/[[...slug]]/route.ts | 18 +- docs-site/content/agents-setup.md | 201 ------------------ .../docs/ai-resources/prompt-recipes.mdx | 3 +- .../docs/getting-started/quickstart.mdx | 21 +- docs-site/lib/agent-setup-markdown.ts | 12 -- docs-site/lib/llm-docs.ts | 3 +- skills.sh.json | 11 + skills/ktx/SKILL.md | 142 +++++++++++++ skills/ktx/agents/openai.yaml | 7 + 10 files changed, 177 insertions(+), 246 deletions(-) delete mode 100644 docs-site/content/agents-setup.md delete mode 100644 docs-site/lib/agent-setup-markdown.ts create mode 100644 skills.sh.json create mode 100644 skills/ktx/SKILL.md create mode 100644 skills/ktx/agents/openai.yaml diff --git a/README.md b/README.md index 2e034677..23b2fa0a 100644 --- a/README.md +++ b/README.md @@ -119,9 +119,8 @@ Agent integration ready: yes (codex:project) > your project directory: > > ```text -> Follow instructions from -> https://docs.kaelio.com/ktx/docs/agents-setup.md -> to install and configure ktx +> Run npx skills add Kaelio/ktx --skill ktx and use the ktx skill to install +> and configure ktx in this project. > ``` > [!IMPORTANT] diff --git a/docs-site/app/llms.mdx/docs/[[...slug]]/route.ts b/docs-site/app/llms.mdx/docs/[[...slug]]/route.ts index 87dcbd42..1372d556 100644 --- a/docs-site/app/llms.mdx/docs/[[...slug]]/route.ts +++ b/docs-site/app/llms.mdx/docs/[[...slug]]/route.ts @@ -3,11 +3,6 @@ import { getLlmDocsPages, getPageMarkdown, } from "@/lib/llm-docs"; -import { - agentSetupSlug, - isAgentSetupSlug, - readAgentSetupMarkdown, -} from "@/lib/agent-setup-markdown"; export const dynamic = "force-static"; @@ -16,14 +11,6 @@ export async function GET( props: { params: Promise<{ slug?: string[] }> }, ) { const params = await props.params; - if (isAgentSetupSlug(params.slug)) { - return new Response(await readAgentSetupMarkdown(), { - headers: { - "Content-Type": "text/markdown; charset=utf-8", - }, - }); - } - const page = getLlmDocsPage(params.slug); if (!page) { return new Response("Documentation page not found.\n", { @@ -42,8 +29,5 @@ export async function GET( } export function generateStaticParams() { - return [ - ...getLlmDocsPages().map((page) => ({ slug: page.slug })), - { slug: [...agentSetupSlug] }, - ]; + return getLlmDocsPages().map((page) => ({ slug: page.slug })); } diff --git a/docs-site/content/agents-setup.md b/docs-site/content/agents-setup.md deleted file mode 100644 index 4933ff10..00000000 --- a/docs-site/content/agents-setup.md +++ /dev/null @@ -1,201 +0,0 @@ -# Goal - -Set up **ktx** from scratch end-to-end as a fully autonomous, agent-driven replacement for the interactive `ktx setup` wizard. Detect the environment, install missing prerequisites, ask the user only for information you genuinely need (which connections to add, credentials), write a valid configuration, verify it works, and run a fast ingest. Keep the user updated throughout. - -# Operating principles - -- **Be autonomous.** Detect, decide, and act. Only ask the user when you need information that only they can provide: project location, which databases/sources to connect, credentials, and similar choices. -- **Stream short status updates.** Before each major phase ("Checking prerequisites…", "Installing uv…", "Configuring warehouse connection…", "Running fast ingest…") print a one-line update. Not chatty - just enough that the user can see what's happening. -- **Verify against docs, never guess.** CLI flags, config keys, and command names must come from the docs or from `ktx --help`. If something looks wrong or missing, say so explicitly. -- **Print every command you run and its exit code.** Terse, not silent. -- **Fail loudly with cause + fix.** When a command fails: capture the exact error, identify the cause, change something, retry. Never retry an unchanged command. Exceptions for *known soft-failures* are listed in Phase 4 - handle those without retrying. -- **No LLM-based ingestion in this flow.** Only `--fast` ingest. The user can run `--deep` later. -- **Platform-agnostic.** Detect the host OS first and pick the right install commands / path syntax. Anything path- or shell-specific must branch on OS. - -# Authoritative docs - -**ktx** docs are served at `https://docs.kaelio.com/ktx/`. **Start by fetching `https://docs.kaelio.com/ktx/llms.txt`** to discover the docs map. Scan it for a "troubleshooting" entry - if one exists, read it **before** running install/setup so you can apply known fixes preemptively rather than after failing. If no troubleshooting page is listed (current state of the docs), proceed. Then fetch any other `.md` pages you need (setup, ingest, status, connection types). **Never invent CLI flags or config keys** - verify against the docs or `ktx --help` / `ktx --help`. - -> **Note on the `ktx status` JSON example in the docs.** The docs page for `ktx status` shows an example shaped like `{"title": "...", "checks": [...]}`. That example is outdated. The real CLI output uses a top-level `verdict` field plus a `connections[]` array - see Phase 5 for the canonical success criteria. Trust the shape in this prompt over the docs example. - -# Workflow - -## Phase 1 - Detect environment - -Determine the host OS (e.g. via `uname -s`, `process.platform`, or `$env:OS`). Use the right install commands per OS for the rest of this flow. - -| Tool | macOS / Linux | Windows (PowerShell) | -|------|---------------|----------------------| -| `uv` | `curl -LsSf https://astral.sh/uv/install.sh \| sh` then re-source shell env | `irm https://astral.sh/uv/install.ps1 \| iex` | -| Node.js | use system / fnm / nvm - **do not** auto-install | use system / nvm-windows - **do not** auto-install | -| **ktx** CLI | `npm install -g …` (see Phase 2) | `npm install -g …` (see Phase 2) | - -If Node.js is missing, **stop and ask the user** to install it (https://nodejs.org/). Do not attempt to auto-install Node. - -## Phase 2 - Verify and install prerequisites - -Check each tool in order; install only if missing. - -1. **Node.js** - run `node --version`. Require >= 22. If missing or older, stop and instruct the user. -2. **`uv`** - run `uv --version`. If missing, run the OS-appropriate install command, then re-source the shell environment (`export PATH="$HOME/.local/bin:$PATH"` on Linux/macOS) so `uv` is on `PATH`. -3. **ktx CLI** - - - Install ktx with `npm install -g @kaelio/ktx` - - Verify with `ktx --version`. - -Print one status line per tool ("✓ uv 0.11.15 found", "Installing uv…", "✓ ktx 0.x.y installed"). - -## Phase 3 - Gather user choices - -Ask the user (grouped if your harness supports it; otherwise sequentially): - -1. **Project directory.** Default: current working directory. Confirm before continuing. -2. **LLM provider.** Default: `claude-code` with model `sonnet` (the user is already inside Claude Code; no extra API key needed). Offer `anthropic` (paste API key, stored as `env:` or `file:` ref) and `vertex` (GCP project + location) as alternatives. Skip if defaults are accepted. -3. **Embeddings backend.** Default: `sentence-transformers` (local, no API key, managed Python runtime). Offer `openai` only if the user has a key. -4. **Database connections.** Ask how many to add, then loop. For each, collect: - - Connection name (e.g. `warehouse`, `analytics`). - - Driver: one of `sqlite`, `postgres`, `mysql`, `sqlserver`, `bigquery`, `snowflake`. - - Connection URL/DSN (or service-account file for BigQuery). Accept `env:VAR_NAME` or `file:/abs/path` to avoid pasting raw secrets. - - **Heads-up for the user**: even if they paste a literal URL, **ktx** will silently relocate it into `/.ktx/secrets/-url` and rewrite `ktx.yaml` to `url: file:…` - this is correct, secure behavior and not a bug. - - Schemas / datasets to include (postgres / sqlserver / snowflake / bigquery only). - - Optional `enabled_tables` allowlist if the user wants to scope ingest to specific tables. -5. **Context sources** (dbt, Metabase, Looker, LookML, MetricFlow, Notion). Default: none. Ask only if the user mentions them. - -## Phase 4 - Configure the project - -Drive the existing wizard non-interactively (verify exact flag names with `ktx setup --help` and the docs - the automation flags are hidden from help but accepted): - -``` -ktx setup \ - --project-dir \ - --no-input --yes \ - --llm-backend --llm-model \ - [--anthropic-api-key-env ANTHROPIC_API_KEY | --anthropic-api-key-file ] \ - [--vertex-project

--vertex-location ] \ - --embedding-backend \ - [--embedding-api-key-env OPENAI_API_KEY] \ - --skip-sources \ - --database --database-connection-id --database-url \ - [--database-schema …] -``` - -Notes on the flags above: -- **Project creation is automatic with `--no-input --yes`.** When - `ktx.yaml` exists, setup resumes it. When it doesn't exist, setup creates it - at `--project-dir`. -- **`--database-connection-id` is dual-purpose.** With `--database` or - `--database-url`, it names the new connection. Without those flags, it - selects an existing connection id. -- **Configure one new database connection per setup command.** If the user - wants multiple new connections, run setup again for each connection. -- **You don't need `--skip-agents` in this flow.** The agent integration step - is opt-in: setup leaves it alone unless you pass `--agents --target - `. -- **`--skip-sources`** is correct and is the documented way to leave context sources unconfigured. - -### Known soft-failure: `ktx setup` exits 1 after a successful fast build - -When you select a configuration that only does fast ingest, `ktx setup`'s final readiness verification fails with: - -``` -ktx context build did not pass agent-readiness verification. - : deep database context has not completed. -``` - -This is **expected** and **does not mean setup failed**. Treat the exit code as a soft-failure **only if all of the following hold**: - -- The build log shows the fast ingest reached `[100%] Scan completed` for every configured connection. -- `ktx connection test ` (run next) exits 0 for every connection. -- `ktx status --json --no-input` reports `verdict: "ready"`. - -If those three conditions hold, proceed to Phase 5 without retrying setup, and **do not** switch to `--deep` to "fix" the readiness gate - deep ingest is explicitly out of scope. Mention this in the final report under "Docs / CLI gaps" so the user is aware. - -If any of those three conditions do not hold, this is a real failure - capture the error, fetch the relevant docs page, fix the cause, retry. - -After `ktx setup` writes `ktx.yaml`, edit it directly for anything flags don't cover: -- Per-connection `enabled_tables` allowlist (snake_case, under `connections..enabled_tables`). -- Any advanced settings the user requested. - -Use a YAML-aware editor (e.g. `uv run python -c "import yaml; …"`) - do not hand-edit blindly. - -## Phase 5 - Verify - -`ktx setup` already runs a fast ingest of every database connection it configures, so you do not need to re-ingest by default. For each configured connection: - -``` -ktx connection test # must exit 0 -``` - -Only re-run ingest if setup's build log did **not** reach 100% for that connection: - -``` -ktx ingest --fast --no-input -``` - -**Mutex warning on `ktx ingest`**: passing both `--yes` and `--no-input` fails with `Choose only one runtime install mode: --yes or --no-input`. Setup already installed the managed Python runtime, so pass **only `--no-input`** to `ktx ingest`. (`--yes` is only needed when an ingest invocation has to install the runtime itself, which is not the case here.) - -Then run the global health check: - -``` -ktx status --json --no-input -``` - -Success requires (canonical shape - supersedes the example in the docs): -- `verdict: "ready"` at the top of the JSON. -- Every `connections[].status === "ok"`. -- `ktx connection test ` exited 0 for every connection. - -Do **not** run `--deep` ingest in this flow - that requires LLM time and is out of scope. - -### Optional: directly probe the ktx daemon - -If the user asks for stronger verification that `sentence-transformers` is actually serving (not just that setup said "ok"), do all of: - -1. `ktx admin runtime status --json` → expect `"kind": "ready"` and `"features": [..., "local-embeddings"]`. -2. `pgrep -fa ktx-daemon` → expect a process running `ktx-daemon serve-http`. -3. `curl -sS http://127.0.0.1:/health` → expect HTTP 200 with `{"status":"healthy",…}`. -4. `curl -sS -X POST http://127.0.0.1:/embeddings/compute -H 'content-type: application/json' -d '{"text":"hello"}'` → expect `{"embedding": [...384 floats...]}`. - -Discover the port from setup's log line `Started ktx daemon: http://127.0.0.1:` or from the daemon's OpenAPI at `GET /openapi.json`. Note: the routes are `/health` and `/embeddings/compute` - not `/healthz` or `/embeddings`. - -## Phase 6 - Final report - -Print a structured report: - -``` -ktx SETUP COMPLETE - -Project: -LLM: / -Embeddings: / -Runtime: managed Python ✓ (if the ktx daemon was started) - -Connections: - - () status=ok schemas=[…] tables= - - … - -Sources: -Verdict: ready -``` - -Then **Next steps** (copy-pasteable): -1. Enrich with AI descriptions and embeddings: `ktx ingest --deep` (several minutes per connection). -2. Add more connections later by rerunning this setup or via `ktx setup --database … --database-connection-id …`. -3. Configure context sources (dbt, Metabase, Looker, LookML, MetricFlow, Notion) - see `ktx setup --help` for `--source …` flags. -4. Install agent integration: `ktx setup --agents --target ` (with optional `--global` for `claude-code`/`codex`). -5. Connect the agent / MCP: see docs at `https://docs.kaelio.com/ktx/`. - -Under **Docs / CLI gaps to flag** include any of these that applied during your run: -- `ktx setup` exits non-zero after a successful fast build (deep-readiness gate); status reports ready. -- `ktx ingest` rejects `--yes` and `--no-input` together; docs don't note the conflict. -- `ktx status --json` real shape (`verdict`, `connections[]`) doesn't match the example in the docs page. -- The pasted DB URL was moved to `.ktx/secrets/-url` automatically. - -End with a single line: `RESULT: PASS` or `RESULT: FAIL - `. - -# Operating rules (recap) - -- Print every command you run and its exit code. Status updates may be terse, but never silent. -- On failure: capture the error, fetch the relevant docs page, fix the cause, retry. Never retry an unchanged command. -- Known soft-failures (listed in Phase 4 and Phase 5) are not real failures - handle them as documented; do not retry or escalate. -- If you find a docs/CLI gap ("docs say X but CLI does Y"), call it out in the final report. -- Never commit credentials - **ktx** accepts `env:` and `file:` references; prefer those. **ktx** will also auto-relocate literal URLs into `.ktx/secrets/`, but that does not protect anyone who pasted the URL into chat history. diff --git a/docs-site/content/docs/ai-resources/prompt-recipes.mdx b/docs-site/content/docs/ai-resources/prompt-recipes.mdx index c2a9f282..9ba8e3b8 100644 --- a/docs-site/content/docs/ai-resources/prompt-recipes.mdx +++ b/docs-site/content/docs/ai-resources/prompt-recipes.mdx @@ -14,7 +14,8 @@ Read https://docs.kaelio.com/ktx/llms.txt first. Then fetch only the ktx Markdow ## Set up a project ```text -Set up ktx in this repository. Start by reading /docs/ai-resources/agent-quickstart.md and /docs/getting-started/quickstart.md. Install the published CLI with npm; use pnpm only when working from a ktx source checkout. After setup, run ktx status and summarize which steps are complete, which files changed, and what still needs credentials or user input. +Run npx skills add Kaelio/ktx --skill ktx and use the ktx skill to install +and configure ktx in this project. ``` ## Find a command diff --git a/docs-site/content/docs/getting-started/quickstart.mdx b/docs-site/content/docs/getting-started/quickstart.mdx index f2ef3c7c..56b0389e 100644 --- a/docs-site/content/docs/getting-started/quickstart.mdx +++ b/docs-site/content/docs/getting-started/quickstart.mdx @@ -103,11 +103,8 @@ If you're a coding assistant choosing a docs route, start with the

You can ask an agent such as Claude Code, Codex, Cursor, or OpenCode to - install and configure **ktx** for you. The{' '} - - agent setup Markdown prompt - {' '} - tells the agent how to check prerequisites, ask only for credentials or + install and configure **ktx** for you. The installable **ktx** skill tells + the agent how to check prerequisites, ask only for credentials or connection choices, run ktx setup, verify connections, and report the result.
@@ -120,16 +117,18 @@ If you're a coding assistant choosing a docs route, start with the Prompt
-
Follow instructions from
-
https://docs.kaelio.com/ktx/docs/agents-setup.md
-
to install and configure ktx
+
+ Run npx skills add Kaelio/ktx --skill ktx and use the ktx skill to + install and configure ktx in this project. +
diff --git a/docs-site/lib/agent-setup-markdown.ts b/docs-site/lib/agent-setup-markdown.ts deleted file mode 100644 index 5a42ea1f..00000000 --- a/docs-site/lib/agent-setup-markdown.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { readFile } from "node:fs/promises"; -import { join } from "node:path"; - -export const agentSetupSlug = ["agents-setup"] as const; - -export function isAgentSetupSlug(slug: string[] | undefined) { - return slug?.length === 1 && slug[0] === agentSetupSlug[0]; -} - -export function readAgentSetupMarkdown() { - return readFile(join(process.cwd(), "content/agents-setup.md"), "utf8"); -} diff --git a/docs-site/lib/llm-docs.ts b/docs-site/lib/llm-docs.ts index 7ed338a0..fd6c8dd1 100644 --- a/docs-site/lib/llm-docs.ts +++ b/docs-site/lib/llm-docs.ts @@ -52,8 +52,9 @@ ktx provides semantic-layer files, warehouse scans, wiki pages, provenance, and ## Agent Entry Points +- Installable setup skill: run \`npx skills add Kaelio/ktx --skill ktx\` from + the project you want to configure. ${link("/docs/ai-resources/agent-quickstart", "Agent Quickstart", "Task-first route for coding assistants using ktx")} -${link("/docs/agents-setup", "Agent Setup", "Copy-pasteable prompt for agents installing and configuring ktx")} ${link("/docs/ai-resources/markdown-access", "Markdown Access", "Fetch ktx docs as llms.txt, llms-full.txt, or per-page Markdown")} ${link("/docs/ai-resources/agent-instructions", "Agent Instructions", "Suggested instructions for coding assistants that need to read and cite ktx docs")} diff --git a/skills.sh.json b/skills.sh.json new file mode 100644 index 00000000..6bc144ae --- /dev/null +++ b/skills.sh.json @@ -0,0 +1,11 @@ +{ + "$schema": "https://skills.sh/schemas/skills.sh.schema.json", + "notGrouped": "bottom", + "groupings": [ + { + "title": "ktx", + "description": "Skills for installing, configuring, and operating ktx.", + "skills": ["ktx"] + } + ] +} diff --git a/skills/ktx/SKILL.md b/skills/ktx/SKILL.md new file mode 100644 index 00000000..4a2b48a3 --- /dev/null +++ b/skills/ktx/SKILL.md @@ -0,0 +1,142 @@ +--- +name: ktx +description: Use when installing, configuring, verifying, or debugging ktx in a project, including ktx setup, ktx.yaml, database connectors, embeddings, agent integration, ingest, and ktx status checks. +--- + +# ktx + +Install and configure **ktx**, the open-source context layer for data agents. +Use this skill when a user wants an agent to add **ktx** to a project, connect +data sources, build initial context, install agent rules, or troubleshoot a +local **ktx** setup. + +## Operating rules + +- Act autonomously when the user asks you to install or configure **ktx**. +- Ask only for choices or values you cannot infer: project directory, + connection targets, credentials, account identifiers, and source selections. +- Never ask the user to paste secrets when an `env:VAR_NAME` or `file:/path` + reference would work. +- Do not commit `.ktx/secrets/*` or pasted credentials. +- Verify CLI flags and config keys with `ktx --help`, `ktx --help`, + or the docs at `https://docs.kaelio.com/ktx/` before using unfamiliar + options. +- Print or report each command you run and its result when doing setup work. +- If a command fails, identify the cause and change something before retrying. + +## Install workflow + +Use this workflow for a new or resumed project setup: + +1. Confirm the project directory. Default to the current working directory. +2. Check prerequisites: + - Node.js with `node --version`; require Node 22 or newer. + - `uv` with `uv --version`; install it only if missing and local Python + runtime features are needed. + - **ktx** with `ktx --version`; install the published CLI if missing. +3. Install the published CLI when needed: + + ```bash + npm install -g @kaelio/ktx + ``` + +4. Run interactive setup when the user is present: + + ```bash + ktx setup + ``` + +5. For scripted setup, prefer `ktx setup --no-input --yes` with explicit flags. + Verify exact flags with `ktx setup --help` and the docs first. +6. Configure one new database connection per scripted setup command. For + multiple connections, rerun setup once per connection. +7. Run fast ingest by default. Do not run deep ingest unless the user asks for + LLM-backed enrichment. +8. Install or repair agent integration after project setup: + + ```bash + ktx setup --agents + ``` + +9. Verify readiness: + + ```bash + ktx status + ``` + + Use `ktx status --json` when you need structured success criteria. + +## Common setup choices + +Default choices are usually: + +- LLM: `claude-code` if the user is already running Claude Code, otherwise ask. +- Embeddings: `sentence-transformers` for local embeddings with no API key, or + `openai` when the user wants hosted embeddings and has an API key. +- Databases: SQLite, PostgreSQL, MySQL, SQL Server, BigQuery, Snowflake, or + ClickHouse. +- Context sources: dbt, MetricFlow, LookML, Looker, Metabase, or Notion. + +Use `env:` or `file:` references for credentials: + +```bash +ktx setup \ + --project-dir ./analytics \ + --no-input \ + --yes \ + --database postgres \ + --database-connection-id warehouse \ + --database-url env:DATABASE_URL \ + --database-schema public +``` + +Then build or refresh fast context if setup did not already do it: + +```bash +ktx ingest warehouse --fast --no-input +``` + +## Files to inspect + +- `ktx.yaml`: project configuration. +- `.ktx/secrets/*`: local secret files. Never commit them. +- `semantic-layer//*.yaml`: semantic sources for SQL + compilation. +- `wiki/**/*.md`: project context pages for agents. +- `.claude/skills/ktx/`, `.agents/skills/ktx/`, `.cursor/rules/ktx.mdc`, and + `.opencode/commands/ktx.md`: generated agent integration files. + +## Verification + +After setup, run the smallest checks that cover the configured surface: + +```bash +ktx connection test +ktx status --json +``` + +Success means the project is ready, configured connections report healthy, and +the agent integration target requested by the user is installed. If fast setup +completed but deep context readiness is still missing, report that as the next +optional enrichment step rather than retrying setup unchanged. + +## Final report + +End setup work with a concise report: + +```text +ktx SETUP COMPLETE + +Project: +LLM: / +Embeddings: / +Connections: () status= +Sources: +Verdict: + +Next: +1. +2. + +RESULT: PASS +``` diff --git a/skills/ktx/agents/openai.yaml b/skills/ktx/agents/openai.yaml new file mode 100644 index 00000000..41eb75d2 --- /dev/null +++ b/skills/ktx/agents/openai.yaml @@ -0,0 +1,7 @@ +interface: + display_name: "ktx" + short_description: "Install and configure ktx for data agents" + default_prompt: "Use $ktx to install and configure ktx in this project." + +policy: + allow_implicit_invocation: true From 2a85346613e780c3b337872e9642d5dbdd7ed339 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Thu, 28 May 2026 12:51:17 +0200 Subject: [PATCH 05/61] fix(docs-site): disable Geist Mono ligatures on every font-mono surface (#228) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Geist Mono fuses `--` into an em-dash glyph that visually swallows the adjacent space, so prompts like `npx skills add Kaelio/ktx --skill ktx` rendered as `Kaelio/ktx--skill ktx` on the quickstart page. The existing ligature-off rule only covered /
 and the .ktx-code wrapper —
quickstart.mdx puts the prompt in a plain 
, so the rule didn't apply. Extend the selector to also match the .font-mono Tailwind utility and any inline-style opt-in via the mono font CSS variable. Document the convention in AGENTS.md so future docs additions keep ligatures off on any new monospace container. --- AGENTS.md | 16 ++++++++++++++++ docs-site/app/global.css | 8 ++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b5eccd67..3d8c1725 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -375,6 +375,22 @@ that do not change user-facing behavior. When you do update docs, follow the warrants docs but you are out of scope, call it out in your final summary rather than silently skipping it. +#### Monospace ligatures in `docs-site/` + +- **MUST**: Disable monospace ligatures on every surface that uses the + `var(--font-mono)` family (Geist Mono). Geist Mono fuses `--` into an + em-dash glyph that visually eats the adjacent space, so prompts like + `npx skills add Kaelio/ktx --skill ktx` render as `Kaelio/ktx--skill ktx`. +- **MUST**: When adding a new container that renders user-visible monospace + text outside `` / `
` (e.g. a styled `
` + for a copyable prompt), verify the global ligature-off rule in + `docs-site/app/global.css` covers its selector. Either use Tailwind's + `font-mono` utility (already covered) or extend the rule to match the new + class — do not silently rely on Geist Mono's defaults. +- **SHOULD**: Prefer `` / `
` (or a `font-mono` wrapper) for any
+  string that contains CLI flags, paths, or other tokens with `--`, `->`,
+  `>=`, `!=`, `==`, `//` so ligatures never alter intent.
+
 ## LLM and Prompt Development
 
 When creating or modifying agent prompts, system prompts, tool descriptions, or
diff --git a/docs-site/app/global.css b/docs-site/app/global.css
index a4cebc55..929e06b4 100644
--- a/docs-site/app/global.css
+++ b/docs-site/app/global.css
@@ -166,12 +166,16 @@ pre {
 }
 
 /* Disable monospace ligatures so `--flag` keeps a visible space and double
-   dashes don't fuse into an em-dash glyph. */
+   dashes don't fuse into an em-dash glyph. Covers every monospace surface:
+   raw /
, the ktx-code wrapper, Tailwind's `font-mono` utility,
+   and anything that opts in via the `var(--font-mono)` family directly. */
 code,
 pre,
 pre code,
 .ktx-code,
-.ktx-code code {
+.ktx-code code,
+.font-mono,
+[style*="--font-mono"] {
   font-variant-ligatures: none !important;
   font-feature-settings: "liga" 0, "calt" 0 !important;
 }

From b687167bc16d44a144210cf5d5b5b8080e045ba7 Mon Sep 17 00:00:00 2001
From: Andrey Avtomonov 
Date: Thu, 28 May 2026 13:00:49 +0200
Subject: [PATCH 06/61] Route ktx stars dashboard

---
 docs-site/next.config.mjs | 32 ++++++++++++++++++++++++--------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/docs-site/next.config.mjs b/docs-site/next.config.mjs
index b82803be..380dba85 100644
--- a/docs-site/next.config.mjs
+++ b/docs-site/next.config.mjs
@@ -6,12 +6,28 @@ const withMDX = createMDX();
 const config = {
   basePath: "/ktx",
   async rewrites() {
-    return [
-      {
-        source: "/docs/:path*.md",
-        destination: "/llms.mdx/docs/:path*",
-      },
-    ];
+    return {
+      beforeFiles: [
+        {
+          source: "/stars",
+          has: [{ type: "host", value: "ktx.sh" }],
+          destination: "https://ktx-stars.vercel.app/stars",
+          basePath: false,
+        },
+        {
+          source: "/stars/:path*",
+          has: [{ type: "host", value: "ktx.sh" }],
+          destination: "https://ktx-stars.vercel.app/stars/:path*",
+          basePath: false,
+        },
+      ],
+      afterFiles: [
+        {
+          source: "/docs/:path*.md",
+          destination: "/llms.mdx/docs/:path*",
+        },
+      ],
+    };
   },
   async redirects() {
     return [
@@ -43,9 +59,9 @@ const config = {
         basePath: false,
       },
       {
-        source: "/:path*",
+        source: "/:path((?!stars(?:/|$)).*)",
         has: [{ type: "host", value: "ktx.sh" }],
-        destination: "https://docs.kaelio.com/ktx/:path*",
+        destination: "https://docs.kaelio.com/ktx/:path",
         permanent: true,
         basePath: false,
       },

From c1ed5eedced10c468d55cad90c4d00f4d8688922 Mon Sep 17 00:00:00 2001
From: Andrey Avtomonov 
Date: Thu, 28 May 2026 15:17:06 +0200
Subject: [PATCH 07/61] fix(cli): preserve project artifacts when ktx setup
 steps fail (#229)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

ktx setup wiped ktx.yaml, .ktx/setup/state.json, wiki/, semantic-layer/,
raw-sources/, and .git/ — or removed the entire project dir — whenever any
single source in the context-build step failed, destroying hours of ingest
work and the persisted resume state. The cleanup hint was designed for an
"early abort, leave no trace" semantic but was applied indiscriminately to
every later step failure, in direct conflict with the .ktx/setup/state.json
resume mechanism.

Drop the cleanup mechanism entirely (KtxSetupCreatedProjectCleanup,
cleanupForFolderState, createProjectWithCleanup, cleanupCreatedProjectScaffold,
and the createdProjectCleanup plumbing through KtxSetupProjectResult). Step
failures now return non-zero without touching the filesystem, so re-running
ktx setup continues from completed steps and only re-attempts failed sources.

Rewrites the two tests that documented the wipe behavior to assert
preservation, and adds a regression test that simulates partial context-build
artifacts (state.json, wiki/, semantic-layer/) and verifies all survive a
failed context step.

Refs KLO-719
---
 packages/cli/src/setup-project.ts | 45 ++-------------------
 packages/cli/src/setup.ts         | 25 +-----------
 packages/cli/test/setup.test.ts   | 65 ++++++++++++++++++++++++++++---
 3 files changed, 63 insertions(+), 72 deletions(-)

diff --git a/packages/cli/src/setup-project.ts b/packages/cli/src/setup-project.ts
index d7d189e1..08f935e6 100644
--- a/packages/cli/src/setup-project.ts
+++ b/packages/cli/src/setup-project.ts
@@ -24,17 +24,12 @@ export interface KtxSetupProjectArgs {
   allowBack?: boolean;
 }
 
-export type KtxSetupCreatedProjectCleanup =
-  | { kind: 'remove-project-dir'; projectDir: string }
-  | { kind: 'remove-ktx-scaffold'; projectDir: string };
-
 export type KtxSetupProjectResult =
   | {
       status: 'ready';
       projectDir: string;
       project: KtxLocalProject;
       confirmedCreation?: boolean;
-      createdProjectCleanup?: KtxSetupCreatedProjectCleanup;
     }
   | { status: 'back'; projectDir: string }
   | { status: 'cancelled'; projectDir: string }
@@ -59,7 +54,6 @@ type PromptProjectDirResult =
       status: 'selected';
       projectDir: string;
       confirmedCreation: boolean;
-      createdProjectCleanup?: KtxSetupCreatedProjectCleanup;
     }
   | { status: 'cancelled'; projectDir: string }
   | { status: 'missing-input'; projectDir: string }
@@ -106,26 +100,12 @@ type ConfirmProjectDirResult =
   | {
       status: 'confirmed';
       confirmedCreation: boolean;
-      createdProjectCleanup?: KtxSetupCreatedProjectCleanup;
     }
   | { status: 'choose-another' }
   | { status: 'back' }
   | { status: 'cancelled' }
   | { status: 'not-directory' };
 
-function cleanupForFolderState(
-  projectDir: string,
-  state: Awaited>,
-): KtxSetupCreatedProjectCleanup | undefined {
-  if (state === 'missing') {
-    return { kind: 'remove-project-dir', projectDir };
-  }
-  if (state === 'empty-directory') {
-    return { kind: 'remove-ktx-scaffold', projectDir };
-  }
-  return undefined;
-}
-
 async function confirmProjectDir(
   selectedDir: string,
   io: KtxCliIo,
@@ -165,7 +145,7 @@ async function confirmProjectDir(
   if (action === 'choose-another') return { status: 'choose-another' };
   if (action === 'back') return { status: 'back' };
   if (action !== 'create') return { status: 'cancelled' };
-  return { status: 'confirmed', confirmedCreation: true, createdProjectCleanup: cleanupForFolderState(selectedDir, state) };
+  return { status: 'confirmed', confirmedCreation: true };
 }
 
 async function normalizeSetupGitignore(projectDir: string): Promise {
@@ -252,24 +232,10 @@ async function promptForNewProjectDir(
       status: 'selected',
       projectDir: selectedDir,
       confirmedCreation: confirmed.confirmedCreation,
-      ...(confirmed.createdProjectCleanup ? { createdProjectCleanup: confirmed.createdProjectCleanup } : {}),
     };
   }
 }
 
-async function createProjectWithCleanup(
-  projectDir: string,
-  deps: KtxSetupProjectDeps,
-): Promise<{ project: KtxLocalProject; createdProjectCleanup?: KtxSetupCreatedProjectCleanup }> {
-  const state = await existingFolderState(projectDir);
-  const project = await createProject(projectDir, deps);
-  const createdProjectCleanup = cleanupForFolderState(projectDir, state);
-  return {
-    project,
-    ...(createdProjectCleanup ? { createdProjectCleanup } : {}),
-  };
-}
-
 export async function runKtxSetupProjectStep(
   args: KtxSetupProjectArgs,
   io: KtxCliIo,
@@ -307,7 +273,6 @@ export async function runKtxSetupProjectStep(
       projectDir: selected.projectDir,
       project,
       confirmedCreation: selected.confirmedCreation,
-      ...(selected.createdProjectCleanup ? { createdProjectCleanup: selected.createdProjectCleanup } : {}),
     };
   }
 
@@ -322,13 +287,12 @@ export async function runKtxSetupProjectStep(
       io.stderr.write('Missing setup choice: pass --yes to create a project in non-interactive setup.\n');
       return { status: 'missing-input', projectDir };
     }
-    const { project, createdProjectCleanup } = await createProjectWithCleanup(projectDir, deps);
+    const project = await createProject(projectDir, deps);
     printProjectSummary(io, projectDir);
     return {
       status: 'ready',
       projectDir,
       project,
-      ...(createdProjectCleanup ? { createdProjectCleanup } : {}),
     };
   }
 
@@ -368,13 +332,12 @@ export async function runKtxSetupProjectStep(
     }
 
     if (choice === 'current') {
-      const { project, createdProjectCleanup } = await createProjectWithCleanup(projectDir, deps);
+      const project = await createProject(projectDir, deps);
       printProjectSummary(io, projectDir);
       return {
         status: 'ready',
         projectDir,
         project,
-        ...(createdProjectCleanup ? { createdProjectCleanup } : {}),
       };
     }
 
@@ -390,7 +353,6 @@ export async function runKtxSetupProjectStep(
         projectDir: defaultProjectDir,
         project,
         confirmedCreation: confirmed.confirmedCreation,
-        ...(confirmed.createdProjectCleanup ? { createdProjectCleanup: confirmed.createdProjectCleanup } : {}),
       };
     }
 
@@ -419,7 +381,6 @@ export async function runKtxSetupProjectStep(
         projectDir: customDir,
         project,
         confirmedCreation: confirmed.confirmedCreation,
-        ...(confirmed.createdProjectCleanup ? { createdProjectCleanup: confirmed.createdProjectCleanup } : {}),
       };
     }
 
diff --git a/packages/cli/src/setup.ts b/packages/cli/src/setup.ts
index 6b3442ca..74056542 100644
--- a/packages/cli/src/setup.ts
+++ b/packages/cli/src/setup.ts
@@ -1,5 +1,4 @@
 import { existsSync } from 'node:fs';
-import { rm } from 'node:fs/promises';
 import { basename, join, resolve } from 'node:path';
 import { getLatestLocalIngestStatus } from './context/ingest/local-ingest.js';
 import { savedMemoryCountsForReport } from './context/ingest/reports.js';
@@ -32,11 +31,7 @@ import {
   isKtxSetupLlmConfigReady,
   runKtxSetupAnthropicModelStep,
 } from './setup-models.js';
-import {
-  type KtxSetupCreatedProjectCleanup,
-  type KtxSetupProjectDeps,
-  runKtxSetupProjectStep,
-} from './setup-project.js';
+import { type KtxSetupProjectDeps, runKtxSetupProjectStep } from './setup-project.js';
 import {
   isKtxPreAgentSetupReady,
   isKtxSetupReady,
@@ -556,23 +551,6 @@ async function commitSetupConfigChanges(projectDir: string): Promise {
   await project.git.commitFile('ktx.yaml', 'setup: update KTX project config', 'ktx setup', 'setup@ktx.local');
 }
 
-const KTX_SETUP_SCAFFOLD_PATHS = ['ktx.yaml', '.ktx', 'wiki', 'semantic-layer', 'raw-sources', '.git'];
-
-async function cleanupCreatedProjectScaffold(cleanup: KtxSetupCreatedProjectCleanup | undefined): Promise {
-  if (!cleanup) {
-    return;
-  }
-  if (cleanup.kind === 'remove-project-dir') {
-    await rm(cleanup.projectDir, { recursive: true, force: true });
-    return;
-  }
-  await Promise.all(
-    KTX_SETUP_SCAFFOLD_PATHS.map((relativePath) =>
-      rm(join(cleanup.projectDir, relativePath), { recursive: true, force: true }),
-    ),
-  );
-}
-
 export async function runKtxSetup(args: KtxSetupArgs, io: KtxCliIo, deps: KtxSetupDeps = {}): Promise {
   try {
     return await runKtxSetupInner(args, io, deps);
@@ -869,7 +847,6 @@ async function runKtxSetupInner(args: KtxSetupArgs, io: KtxCliIo, deps: KtxSetup
       });
 
       if (stepResult.status === 'failed') {
-        await cleanupCreatedProjectScaffold(projectResult.createdProjectCleanup);
         return 1;
       }
       if (stepResult.status === 'missing-input') {
diff --git a/packages/cli/test/setup.test.ts b/packages/cli/test/setup.test.ts
index 6c928033..0bc00919 100644
--- a/packages/cli/test/setup.test.ts
+++ b/packages/cli/test/setup.test.ts
@@ -1,5 +1,5 @@
 import { execFile } from 'node:child_process';
-import { mkdir, mkdtemp, readFile, readdir, rm, stat, writeFile } from 'node:fs/promises';
+import { mkdir, mkdtemp, readFile, rm, stat, writeFile } from 'node:fs/promises';
 import { tmpdir } from 'node:os';
 import { join } from 'node:path';
 import { promisify } from 'node:util';
@@ -602,7 +602,7 @@ describe('setup status', () => {
     expect(testIo.stderr()).toBe('');
   });
 
-  it('removes a newly created missing project directory when a later runtime step fails', async () => {
+  it('preserves a newly created missing project directory when a later setup step fails', async () => {
     const projectDir = join(tempDir, 'missing-project');
     const testIo = makeIo();
 
@@ -634,10 +634,12 @@ describe('setup status', () => {
       ),
     ).resolves.toBe(1);
 
-    await expect(stat(projectDir)).rejects.toThrow();
+    await expect(stat(projectDir)).resolves.toBeDefined();
+    await expect(stat(join(projectDir, 'ktx.yaml'))).resolves.toBeDefined();
+    await expect(stat(join(projectDir, '.ktx'))).resolves.toBeDefined();
   });
 
-  it('removes KTX scaffold files from an initially empty project directory when runtime setup fails', async () => {
+  it('preserves KTX scaffold files in an initially empty project directory when setup fails', async () => {
     const testIo = makeIo();
 
     await expect(
@@ -668,8 +670,59 @@ describe('setup status', () => {
       ),
     ).resolves.toBe(1);
 
-    await expect(stat(tempDir)).resolves.toBeDefined();
-    expect(await readdir(tempDir)).toEqual([]);
+    await expect(stat(join(tempDir, 'ktx.yaml'))).resolves.toBeDefined();
+    await expect(stat(join(tempDir, '.ktx'))).resolves.toBeDefined();
+  });
+
+  it('preserves partial context-build artifacts and resume state when the context step fails', async () => {
+    const projectDir = join(tempDir, 'partial-context');
+    const testIo = makeIo();
+
+    await expect(
+      runKtxSetup(
+        {
+          command: 'run',
+          projectDir,
+          mode: 'auto',
+          agents: false,
+          skipAgents: true,
+          inputMode: 'disabled',
+          yes: true,
+          cliVersion: '0.2.0',
+          skipLlm: true,
+          skipEmbeddings: true,
+          databaseSchemas: [],
+          skipDatabases: true,
+          skipSources: true,
+        },
+        testIo.io,
+        {
+          model: async () => ({ status: 'skipped', projectDir }),
+          embeddings: async () => ({ status: 'skipped', projectDir }),
+          databases: async () => ({ status: 'skipped', projectDir }),
+          sources: async () => ({ status: 'skipped', projectDir }),
+          runtime: async () => runtimeReady(projectDir),
+          context: async () => {
+            await mkdir(join(projectDir, '.ktx', 'setup'), { recursive: true });
+            await writeFile(
+              join(projectDir, '.ktx', 'setup', 'state.json'),
+              JSON.stringify({ status: 'failed', retryableFailedTargets: [{ source: 'metabase' }] }),
+              'utf-8',
+            );
+            await mkdir(join(projectDir, 'wiki'), { recursive: true });
+            await writeFile(join(projectDir, 'wiki', 'postgres-warehouse.md'), '# warehouse\n', 'utf-8');
+            await mkdir(join(projectDir, 'semantic-layer'), { recursive: true });
+            await writeFile(join(projectDir, 'semantic-layer', 'orders.yaml'), 'name: orders\n', 'utf-8');
+            return { status: 'failed', projectDir };
+          },
+        },
+      ),
+    ).resolves.toBe(1);
+
+    await expect(stat(join(projectDir, 'ktx.yaml'))).resolves.toBeDefined();
+    await expect(readFile(join(projectDir, '.ktx', 'setup', 'state.json'), 'utf-8')).resolves.toContain('"status":"failed"');
+    await expect(readFile(join(projectDir, 'wiki', 'postgres-warehouse.md'), 'utf-8')).resolves.toContain('warehouse');
+    await expect(readFile(join(projectDir, 'semantic-layer', 'orders.yaml'), 'utf-8')).resolves.toContain('orders');
   });
 
   it('preserves a pre-existing non-empty project directory when runtime setup fails', async () => {

From 35cecdf65d6554f03ef8dcd2382c2610f12854f0 Mon Sep 17 00:00:00 2001
From: Andrey Avtomonov 
Date: Thu, 28 May 2026 15:30:51 +0200
Subject: [PATCH 08/61] docs(docs-site): tidy agent setup prompt copy and
 sizing

Co-Authored-By: Claude Opus 4.7 (1M context) 
---
 docs-site/content/docs/getting-started/quickstart.mdx | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/docs-site/content/docs/getting-started/quickstart.mdx b/docs-site/content/docs/getting-started/quickstart.mdx
index 56b0389e..5d49cfb3 100644
--- a/docs-site/content/docs/getting-started/quickstart.mdx
+++ b/docs-site/content/docs/getting-started/quickstart.mdx
@@ -105,7 +105,7 @@ If you're a coding assistant choosing a docs route, start with the
     You can ask an agent such as Claude Code, Codex, Cursor, or OpenCode to
     install and configure **ktx** for you. The installable **ktx** skill tells
     the agent how to check prerequisites, ask only for credentials or
-    connection choices, run ktx setup, verify connections, and
+    connection choices, run ktx setup, verify connections, and
     report the result.
   
@@ -119,15 +119,15 @@ If you're a coding assistant choosing a docs route, start with the
-
+
Run npx skills add Kaelio/ktx --skill ktx and use the ktx skill to - install and configure ktx in this project. + install and configure ktx
From 6c6a3e7bafccdc5c66873be6790882ba46f45f81 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Thu, 28 May 2026 15:36:56 +0200 Subject: [PATCH 09/61] docs(skills): correct ktx setup skill against agent-trial findings (#230) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit An external agent ran the skill end-to-end against `ktx setup` and reported seven concrete failures, all verified against the CLI source: - All useful setup flags are `.hideHelp()`, so the skill's "verify with --help" rule led the agent to conclude its own examples were wrong (setup-commands.ts:208-332). - The non-interactive LLM default is `anthropic` (and requires a key), not `claude-code` as the skill claimed (setup-models.ts:505-507). - `ktx status` exits 1 whenever the LLM is `none`, even with healthy embeddings and connections (status-project.ts:204-211, doctor.ts:647). - `ktx ingest` rejects `--yes`+`--no-input` while `ktx setup` accepts both (managed-python-command.ts:23-24). - `--database-url ` auto-externalizes to `.ktx/secrets/-url` — worth telling the agent (setup-databases.ts:671-683). - Resuming setup with only `--llm-backend` fails on missing DB flags even when `ktx.yaml` already has one (setup-databases.ts:1778-1782). - The `--agents` step prints `Required before using agents: ktx mcp start` but the skill never told agents to run it (setup-agents.ts:989,1227). Rewrite SKILL.md to: lead with the scripted (non-interactive) path; add a single "gather inputs once" checklist; correct the LLM default; document `--skip-*` flags and resumability; warn that `status` exit code ≠ readiness; fix the `ktx ingest` example to use `--no-input` only; require `ktx mcp start` after `--agents`; add a ktx-monorepo branch that avoids `npm install -g`. Add skills/ktx/troubleshooting.md (one level deep, per Anthropic's progressive-disclosure guidance) covering the five real failure signatures the agent hit: invalid ELF header, missing native CLI binary, missing Anthropic key, claude-code probe failure, and the resume-without-DB error. Description rewritten to combine what + when per the official skill authoring guidelines. --- skills/ktx/SKILL.md | 164 ++++++++++++++++++++-------------- skills/ktx/troubleshooting.md | 79 ++++++++++++++++ 2 files changed, 174 insertions(+), 69 deletions(-) create mode 100644 skills/ktx/troubleshooting.md diff --git a/skills/ktx/SKILL.md b/skills/ktx/SKILL.md index 4a2b48a3..85028de7 100644 --- a/skills/ktx/SKILL.md +++ b/skills/ktx/SKILL.md @@ -1,100 +1,113 @@ --- name: ktx -description: Use when installing, configuring, verifying, or debugging ktx in a project, including ktx setup, ktx.yaml, database connectors, embeddings, agent integration, ingest, and ktx status checks. +description: Installs and configures ktx, the open-source context layer for data agents — runs ktx setup non-interactively with hidden CLI flags, configures database connections and embeddings, installs agent integration, and verifies readiness. Use when the user asks an agent to add ktx to a project, connect data sources, install agent rules, ingest schema, or troubleshoot a local ktx install. --- # ktx Install and configure **ktx**, the open-source context layer for data agents. Use this skill when a user wants an agent to add **ktx** to a project, connect -data sources, build initial context, install agent rules, or troubleshoot a -local **ktx** setup. +data sources, build initial context, install agent integration, or troubleshoot +a local **ktx** setup. ## Operating rules - Act autonomously when the user asks you to install or configure **ktx**. -- Ask only for choices or values you cannot infer: project directory, - connection targets, credentials, account identifiers, and source selections. + The non-interactive scripted flow below is the canonical path — bare + `ktx setup` is interactive (clack prompts) and an agent cannot drive it. +- Setup's non-interactive flags are intentionally hidden from `--help`. Use the + flags listed below; verify uncommon flags against the docs at + `https://docs.kaelio.com/ktx/` or this skill — not against `--help` output. +- Ask only for values you cannot infer: project directory, connection targets, + credentials, account identifiers, and source selections. - Never ask the user to paste secrets when an `env:VAR_NAME` or `file:/path` - reference would work. -- Do not commit `.ktx/secrets/*` or pasted credentials. -- Verify CLI flags and config keys with `ktx --help`, `ktx --help`, - or the docs at `https://docs.kaelio.com/ktx/` before using unfamiliar - options. -- Print or report each command you run and its result when doing setup work. + reference would work. Pasting a literal URL is also safe — `ktx setup` + auto-externalizes URLs into `.ktx/secrets/-url` (see workflow step 2). +- Do not commit `.ktx/secrets/*`. +- Print each command you run and its result. - If a command fails, identify the cause and change something before retrying. +## Gather inputs once + +Before invoking `ktx setup`, collect in one round: + +1. Project directory (default: current working directory). +2. LLM backend and key strategy. In `--no-input` mode the CLI defaults to + `anthropic` and **requires an API key**. When the user is inside Claude + Code, pass `--llm-backend claude-code` explicitly; otherwise pass + `--llm-backend anthropic --anthropic-api-key-env ANTHROPIC_API_KEY`. +3. Embedding backend (`sentence-transformers` is the local default and needs + no key; use `openai` only if the user already has a key, then pass + `--embedding-api-key-env OPENAI_API_KEY`). +4. Database: driver, connection id, URL (or `env:` / `file:` ref), and one or + more schemas. +5. Optional context sources (dbt, Metabase, Looker, LookML, MetricFlow, + Notion). Skip with `--skip-sources` if the user has none. + +Do not discover these inputs across multiple setup runs. + ## Install workflow -Use this workflow for a new or resumed project setup: - -1. Confirm the project directory. Default to the current working directory. -2. Check prerequisites: - - Node.js with `node --version`; require Node 22 or newer. - - `uv` with `uv --version`; install it only if missing and local Python - runtime features are needed. - - **ktx** with `ktx --version`; install the published CLI if missing. -3. Install the published CLI when needed: +1. **Detect the install path.** If the working directory contains + `packages/cli/dist/bin.js` or `pnpm-workspace.yaml` referencing + `@kaelio/ktx` you are inside the **ktx** monorepo — build and link the + local CLI with `pnpm` and do **not** run `npm install -g`. Otherwise: ```bash - npm install -g @kaelio/ktx + node --version # require >= 22; stop and ask the user if older + ktx --version || npm install -g @kaelio/ktx ``` -4. Run interactive setup when the user is present: +2. **Run scripted setup** (canonical path): ```bash - ktx setup + ktx setup --no-input --yes \ + --project-dir \ + --llm-backend claude-code \ + --embedding-backend sentence-transformers \ + --database --database-connection-id \ + --database-url '' \ + --database-schema \ + --skip-sources ``` -5. For scripted setup, prefer `ktx setup --no-input --yes` with explicit flags. - Verify exact flags with `ktx setup --help` and the docs first. -6. Configure one new database connection per scripted setup command. For - multiple connections, rerun setup once per connection. -7. Run fast ingest by default. Do not run deep ingest unless the user asks for - LLM-backed enrichment. -8. Install or repair agent integration after project setup: + - Configure one new database connection per setup invocation. For multiple + connections, rerun setup once per connection. + - Pasting a literal `--database-url` is safe: the CLI relocates the URL + into `.ktx/secrets/-url` and rewrites `ktx.yaml` to a + `file:` ref automatically. + +3. **Resumability and `--skip-*`.** Re-running `ktx setup` against an existing + project resumes its config. Use `--skip-llm`, `--skip-databases`, + `--skip-sources`, or `--skip-embeddings` to leave a slice unconfigured but + let the rest complete instead of aborting on the first failure. **When + resuming an existing project to change one slice (e.g. only LLM), still + pass the database flags from the previous run** — setup validates current + flags, not persisted `ktx.yaml` state. + +4. **Run fast ingest** if setup did not already complete one: ```bash - ktx setup --agents + ktx ingest --fast --no-input ``` -9. Verify readiness: + Note: `ktx ingest` rejects `--yes` together with `--no-input` + (*Choose only one runtime install mode*); `ktx setup` accepts both. Use + `--no-input` only for ingest. Do not run `--deep` ingest unless the user + explicitly asks for LLM-backed enrichment. + +5. **Install agent integration:** ```bash - ktx status + ktx setup --agents --target + ktx mcp start --project-dir ``` - Use `ktx status --json` when you need structured success criteria. + Agent integration is **not usable until `ktx mcp start` is running**. The + `--agents` step prints this requirement as `Required before using agents`. -## Common setup choices - -Default choices are usually: - -- LLM: `claude-code` if the user is already running Claude Code, otherwise ask. -- Embeddings: `sentence-transformers` for local embeddings with no API key, or - `openai` when the user wants hosted embeddings and has an API key. -- Databases: SQLite, PostgreSQL, MySQL, SQL Server, BigQuery, Snowflake, or - ClickHouse. -- Context sources: dbt, MetricFlow, LookML, Looker, Metabase, or Notion. - -Use `env:` or `file:` references for credentials: - -```bash -ktx setup \ - --project-dir ./analytics \ - --no-input \ - --yes \ - --database postgres \ - --database-connection-id warehouse \ - --database-url env:DATABASE_URL \ - --database-schema public -``` - -Then build or refresh fast context if setup did not already do it: - -```bash -ktx ingest warehouse --fast --no-input -``` +6. **Fall back to bare `ktx setup` only when a human is at the keyboard** — + it uses interactive prompts an agent cannot answer. ## Files to inspect @@ -108,17 +121,30 @@ ktx ingest warehouse --fast --no-input ## Verification -After setup, run the smallest checks that cover the configured surface: +After setup, run: ```bash ktx connection test -ktx status --json +ktx status --json --no-input ``` -Success means the project is ready, configured connections report healthy, and -the agent integration target requested by the user is installed. If fast setup -completed but deep context readiness is still missing, report that as the next -optional enrichment step rather than retrying setup unchanged. +**Judge readiness from `ktx status --json` fields, not the exit code.** +`ktx status` exits 1 whenever the LLM is `none`, even when embeddings and +every database connection are healthy. Treat success as: + +- `verdict: "ready"` at the top of the JSON, and +- every `connections[].status === "ok"`, and +- every `ktx connection test ` exited 0. + +A non-zero exit with only the LLM unconfigured is still a usable context +layer — report it as "ready, LLM optional" rather than retrying setup. + +## Troubleshooting + +For known failure signatures (`invalid ELF header`, +`Native CLI binary for not found`, `Missing Anthropic API key`, +`claude-code` probe failure, `KTX cannot work without a database` on resume), +see [troubleshooting.md](troubleshooting.md). ## Final report diff --git a/skills/ktx/troubleshooting.md b/skills/ktx/troubleshooting.md new file mode 100644 index 00000000..812b45fc --- /dev/null +++ b/skills/ktx/troubleshooting.md @@ -0,0 +1,79 @@ +# ktx setup troubleshooting + +Known failure signatures hit by agent-driven `ktx setup` runs. Match the +error string in the left column, apply the fix in the right column. + +## `Error: invalid ELF header` from `better-sqlite3` + +Native module compiled for a different platform or architecture (e.g. +installed under Rosetta then run under native arm64). + +Fix: + +```bash +# Inside the ktx monorepo: +pnpm rebuild better-sqlite3 + +# Or for a global install: +npm rebuild --global better-sqlite3 +``` + +## `Native CLI binary for not found` + +The platform-specific optional dependency that ships the native CLI binary +was skipped during install (npm/pnpm "optional dep not for this platform"). + +Fix: + +```bash +npm install -g @kaelio/ktx --force +``` + +## `Missing Anthropic API key: pass --anthropic-api-key-env or --anthropic-api-key-file` + +`--no-input` mode defaulted the LLM backend to `anthropic` because no +`--llm-backend` flag was supplied. The CLI then required a key. + +Fix — pick one: + +```bash +# Inside Claude Code, prefer the local backend: +ktx setup --no-input --llm-backend claude-code ...other flags... + +# Otherwise point at an existing env var: +ktx setup --no-input --llm-backend anthropic \ + --anthropic-api-key-env ANTHROPIC_API_KEY ...other flags... +``` + +## `claude-code` LLM probe fails (auth or binary not found) + +The `claude` CLI is not on the agent's `PATH`, or the user has not run +`claude` interactively at least once to log in. + +Fix: + +```bash +which claude # confirm the binary resolves +claude --version # confirm it runs +# If auth probe still fails, the user must run `claude` once interactively +# to complete login; agents cannot do this step. +``` + +If `claude-code` cannot be made to work, fall back to `--skip-llm` and let +the rest of setup complete; the project is still a usable context layer +without an LLM. + +## `KTX cannot work without a database` when resuming setup + +`ktx setup` validates the **current invocation's flags**, not the persisted +`ktx.yaml`. Resuming setup with only `--llm-backend …` fails even when the +project already has a healthy database connection. + +Fix — re-pass the database flags from the original setup run, even when +only changing one slice: + +```bash +ktx setup --no-input \ + --database --database-connection-id \ + --llm-backend claude-code +``` From 57b607169f92d4555e8c921a2fa5fe81dbe0b654 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Thu, 28 May 2026 16:05:19 +0200 Subject: [PATCH 10/61] docs(docs-site): collapse agent setup explainer into a hover overlay (#231) --- .../docs/getting-started/quickstart.mdx | 81 +++++++++++++++---- 1 file changed, 65 insertions(+), 16 deletions(-) diff --git a/docs-site/content/docs/getting-started/quickstart.mdx b/docs-site/content/docs/getting-started/quickstart.mdx index 5d49cfb3..4251c57f 100644 --- a/docs-site/content/docs/getting-started/quickstart.mdx +++ b/docs-site/content/docs/getting-started/quickstart.mdx @@ -98,18 +98,70 @@ If you're a coding assistant choosing a docs route, start with the background: 'color-mix(in oklch, var(--color-fd-primary) 8%, transparent)', }} > -
- Run setup from an agent -
-
- You can ask an agent such as Claude Code, Codex, Cursor, or OpenCode to - install and configure **ktx** for you. The installable **ktx** skill tells - the agent how to check prerequisites, ask only for credentials or - connection choices, run ktx setup, verify connections, and - report the result. -
-
- Use a prompt like this from the project you want to configure: +
+
+ Or, ask an AI agent to install and configure **ktx** for you. +
+
+ + +
@@ -125,10 +177,7 @@ If you're a coding assistant choosing a docs route, start with the />
-
- Run npx skills add Kaelio/ktx --skill ktx and use the ktx skill to - install and configure ktx -
+ Run npx skills add Kaelio/ktx --skill ktx and use the ktx skill to install and configure ktx
From 00d5fd1b0f4c771cedae89d3db6432405bd691ae Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Thu, 28 May 2026 16:09:03 +0200 Subject: [PATCH 11/61] docs(docs-site): show setup prompt command in backticks --- docs-site/content/docs/getting-started/quickstart.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs-site/content/docs/getting-started/quickstart.mdx b/docs-site/content/docs/getting-started/quickstart.mdx index 4251c57f..6f65d6ec 100644 --- a/docs-site/content/docs/getting-started/quickstart.mdx +++ b/docs-site/content/docs/getting-started/quickstart.mdx @@ -177,7 +177,7 @@ If you're a coding assistant choosing a docs route, start with the />
- Run npx skills add Kaelio/ktx --skill ktx and use the ktx skill to install and configure ktx + Run {'`npx skills add Kaelio/ktx --skill ktx`'} and use the ktx skill to install and configure ktx
From ed8f523362be816af94e2d9daeda2f11766a5bc9 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 28 May 2026 15:21:40 +0000 Subject: [PATCH 12/61] chore(release): 0.7.0 [skip ci] ## [0.7.0](https://github.com/Kaelio/ktx/compare/v0.6.0...v0.7.0) (2026-05-28) ### Features * **docs-site:** redirect ktx.sh/slack to Slack community invite ([#224](https://github.com/Kaelio/ktx/issues/224)) ([a94f358](https://github.com/Kaelio/ktx/commit/a94f35800a6d6af52c46c71d8991c79e4a054e58)) ### Bug Fixes * **cli:** align ingest step counter with SDK num_turns ([#225](https://github.com/Kaelio/ktx/issues/225)) ([6837ab2](https://github.com/Kaelio/ktx/commit/6837ab253d6173d3270a8fdc08cff066d1137d1b)) * **cli:** preserve project artifacts when ktx setup steps fail ([#229](https://github.com/Kaelio/ktx/issues/229)) ([c1ed5ee](https://github.com/Kaelio/ktx/commit/c1ed5eedced10c468d55cad90c4d00f4d8688922)) * **docs-site:** disable Geist Mono ligatures on every font-mono surface ([#228](https://github.com/Kaelio/ktx/issues/228)) ([2a85346](https://github.com/Kaelio/ktx/commit/2a85346613e780c3b337872e9642d5dbdd7ed339)) ### Documentation * add context layer terminology ([#226](https://github.com/Kaelio/ktx/issues/226)) ([27842e1](https://github.com/Kaelio/ktx/commit/27842e14a91233818715d792f798032a70b0cfe4)) * add ktx skills.sh setup skill ([#227](https://github.com/Kaelio/ktx/issues/227)) ([39f94f3](https://github.com/Kaelio/ktx/commit/39f94f39ffce81ad7b5a635fb3327897533aea75)) * **docs-site:** collapse agent setup explainer into a hover overlay ([#231](https://github.com/Kaelio/ktx/issues/231)) ([57b6071](https://github.com/Kaelio/ktx/commit/57b607169f92d4555e8c921a2fa5fe81dbe0b654)) * **docs-site:** show setup prompt command in backticks ([00d5fd1](https://github.com/Kaelio/ktx/commit/00d5fd1b0f4c771cedae89d3db6432405bd691ae)) * **docs-site:** tidy agent setup prompt copy and sizing ([35cecdf](https://github.com/Kaelio/ktx/commit/35cecdf65d6554f03ef8dcd2382c2610f12854f0)) * **skills:** correct ktx setup skill against agent-trial findings ([#230](https://github.com/Kaelio/ktx/issues/230)) ([6c6a3e7](https://github.com/Kaelio/ktx/commit/6c6a3e7bafccdc5c66873be6790882ba46f45f81)) --- package.json | 2 +- packages/cli/package.json | 2 +- python/ktx-daemon/pyproject.toml | 2 +- python/ktx-sl/pyproject.toml | 2 +- release-policy.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index b60c1b82..b8c538e1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ktx-workspace", - "version": "0.6.0", + "version": "0.7.0", "description": "Workspace root for ktx packages", "private": true, "type": "module", diff --git a/packages/cli/package.json b/packages/cli/package.json index 81a699a6..4d6bd33b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@kaelio/ktx", - "version": "0.6.0", + "version": "0.7.0", "description": "Standalone ktx context layer for data agents", "type": "module", "engines": { diff --git a/python/ktx-daemon/pyproject.toml b/python/ktx-daemon/pyproject.toml index 8f2204c0..0c6c95e4 100644 --- a/python/ktx-daemon/pyproject.toml +++ b/python/ktx-daemon/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ktx-daemon" -version = "0.6.0" +version = "0.7.0" description = "Portable compute package for KTX semantic-layer operations" readme = "README.md" requires-python = ">=3.13" diff --git a/python/ktx-sl/pyproject.toml b/python/ktx-sl/pyproject.toml index f66af2e6..02cfd06a 100644 --- a/python/ktx-sl/pyproject.toml +++ b/python/ktx-sl/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "ktx-sl" -version = "0.6.0" +version = "0.7.0" description = "Agent-first semantic layer engine with aggregate locality" readme = "README.md" requires-python = ">=3.13" diff --git a/release-policy.json b/release-policy.json index 34119ad6..1cf1529b 100644 --- a/release-policy.json +++ b/release-policy.json @@ -19,7 +19,7 @@ }, "publishedPackageSmoke": { "packageName": "@kaelio/ktx", - "version": "0.6.0", + "version": "0.7.0", "registry": null }, "runtimeInstaller": { From d53cdac36666b647189576caefe66d79033292e8 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Fri, 29 May 2026 11:56:55 +0200 Subject: [PATCH 13/61] chore: upgrade dependencies and tooling (#232) * chore: upgrade dependencies and tooling * chore: upgrade dependencies and tooling --- .github/workflows/triage-issues.yml | 2 +- .pre-commit-config.yaml | 6 + docs-site/package.json | 4 +- package.json | 9 +- packages/cli/package.json | 36 +- pnpm-lock.yaml | 3021 ++++++++++++------------- pnpm-workspace.yaml | 1 + pyproject.toml | 16 +- python/ktx-daemon/pyproject.toml | 32 +- python/ktx-sl/pyproject.toml | 26 +- scripts/upgrade-dependencies.mjs | 111 + scripts/upgrade-dependencies.test.mjs | 123 + tombi.toml | 5 + uv.lock | 2055 ++++++++--------- 14 files changed, 2737 insertions(+), 2710 deletions(-) create mode 100644 scripts/upgrade-dependencies.mjs create mode 100644 scripts/upgrade-dependencies.test.mjs create mode 100644 tombi.toml diff --git a/.github/workflows/triage-issues.yml b/.github/workflows/triage-issues.yml index 41d2f048..e5817e2c 100644 --- a/.github/workflows/triage-issues.yml +++ b/.github/workflows/triage-issues.yml @@ -22,7 +22,7 @@ jobs: github.event.issue.author_association != 'COLLABORATOR' steps: - name: Apply needs-triage label - uses: actions/github-script@v7 + uses: actions/github-script@v9 with: script: | await github.rest.issues.addLabels({ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index cc2f483d..ec730d50 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -14,6 +14,12 @@ repos: - id: check-case-conflict - id: mixed-line-ending + - repo: https://github.com/tombi-toml/tombi-pre-commit + rev: v1.1.0 + hooks: + - id: tombi-format + args: ["--offline"] + - repo: https://github.com/asottile/pyupgrade rev: v3.21.2 hooks: diff --git a/docs-site/package.json b/docs-site/package.json index 4cf896ff..2af1c19d 100644 --- a/docs-site/package.json +++ b/docs-site/package.json @@ -12,7 +12,7 @@ "dependencies": { "@xyflow/react": "^12.10.2", "fumadocs-core": "16.8.10", - "fumadocs-mdx": "15.0.4", + "fumadocs-mdx": "15.0.7", "fumadocs-ui": "16.8.10", "next": "^16", "react": "19.2.6", @@ -20,7 +20,7 @@ }, "devDependencies": { "@tailwindcss/postcss": "^4", - "@types/node": "^25.7.0", + "@types/node": "^25.9.1", "@types/react": "^19", "@types/react-dom": "^19", "tailwindcss": "^4", diff --git a/package.json b/package.json index b8c538e1..5ffb93d6 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Workspace root for ktx packages", "private": true, "type": "module", - "packageManager": "pnpm@11.1.1", + "packageManager": "pnpm@11.4.0", "engines": { "node": ">=22.0.0", "pnpm": ">=10.20.0" @@ -24,6 +24,7 @@ "dead-code:fix": "biome check . --formatter-enabled=false --assist-enabled=false --write && knip --fix --format", "dead-code:knip": "knip --reporter compact", "dead-code:knip:production": "knip --production --reporter compact", + "deps:upgrade": "node scripts/upgrade-dependencies.mjs", "docs": "kill $(lsof -ti:3000) 2>/dev/null; pnpm --filter ktx-docs run dev", "ktx": "node scripts/run-ktx.mjs", "link:dev": "node scripts/link-dev-cli.mjs", @@ -58,11 +59,11 @@ "@semantic-release/github": "^12.0.8", "@semantic-release/npm": "^13.1.5", "@semantic-release/release-notes-generator": "^14.1.1", - "@types/node": "^25.7.0", + "@types/node": "^25.9.1", "better-sqlite3": "^12.10.0", "conventional-changelog-conventionalcommits": "^9.3.1", - "knip": "^6.12.2", - "pg": "^8.20.0", + "knip": "^6.14.1", + "pg": "^8.21.0", "semantic-release": "^25.0.3", "typescript": "^6.0.3", "yaml": "^2.9.0" diff --git a/packages/cli/package.json b/packages/cli/package.json index 4d6bd33b..f3dfaec2 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -43,36 +43,36 @@ "search:pglite-sl-prototype": "node ../../scripts/pglite-sl-search-prototype.mjs" }, "dependencies": { - "@ai-sdk/anthropic": "3.0.77", - "@ai-sdk/devtools": "0.0.17", - "@ai-sdk/google-vertex": "^4.0.128", - "@anthropic-ai/claude-agent-sdk": "0.3.142", + "@ai-sdk/anthropic": "3.0.78", + "@ai-sdk/devtools": "0.0.18", + "@ai-sdk/google-vertex": "^4.0.134", + "@anthropic-ai/claude-agent-sdk": "0.3.146", "@clack/prompts": "1.4.0", - "@clickhouse/client": "^1.18.4", + "@clickhouse/client": "^1.18.5", "@commander-js/extra-typings": "14.0.0", "@google-cloud/bigquery": "^8.3.1", "@looker/sdk": "^26.8.0", "@looker/sdk-node": "^26.8.0", "@looker/sdk-rtl": "^21.6.5", "@modelcontextprotocol/sdk": "^1.29.0", - "@notionhq/client": "^5.21.0", - "ai": "^6.0.180", + "@notionhq/client": "^5.22.0", + "ai": "^6.0.188", "better-sqlite3": "^12.10.0", "commander": "14.0.3", - "fflate": "^0.8.2", + "fflate": "^0.8.3", "handlebars": "^4.7.9", - "ink": "^7.0.2", + "ink": "^7.0.3", "lookml-parser": "7.1.0", "minimatch": "^10.2.5", - "mssql": "^12.5.2", + "mssql": "^12.5.4", "mysql2": "^3.22.3", - "openai": "^6.37.0", + "openai": "^6.38.0", "p-limit": "^7.3.0", - "pg": "^8.20.0", - "posthog-node": "^5.0.0", + "pg": "^8.21.0", + "posthog-node": "^5.34.9", "react": "^19.2.6", "simple-git": "3.36.0", - "snowflake-sdk": "^2.4.1", + "snowflake-sdk": "^2.4.2", "yaml": "^2.9.0", "zod": "^4.4.3" }, @@ -81,14 +81,14 @@ "@electric-sql/pglite-socket": "^0.1.5", "@types/better-sqlite3": "^7.6.13", "@types/mssql": "^12.3.0", - "@types/node": "^25.7.0", + "@types/node": "^25.9.1", "@types/pg": "^8.20.0", - "@types/react": "^19.2.14", - "@vitest/coverage-v8": "^4.1.6", + "@types/react": "^19.2.15", + "@vitest/coverage-v8": "^4.1.7", "ajv": "8.20.0", "ink-testing-library": "^4.0.0", "typescript": "^6.0.3", - "vitest": "^4.1.6" + "vitest": "^4.1.7" }, "license": "Apache-2.0", "repository": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index de0d2c24..bf496066 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,7 +48,7 @@ importers: version: 14.1.1(semantic-release@25.0.3(typescript@6.0.3)) '@types/node': specifier: ^24.3.0 - version: 24.12.2 + version: 24.12.4 better-sqlite3: specifier: ^12.10.0 version: 12.10.0 @@ -56,11 +56,11 @@ importers: specifier: ^9.3.1 version: 9.3.1 knip: - specifier: ^6.12.2 - version: 6.12.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + specifier: ^6.14.1 + version: 6.14.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) pg: - specifier: ^8.20.0 - version: 8.20.0 + specifier: ^8.21.0 + version: 8.21.0 semantic-release: specifier: ^25.0.3 version: 25.0.3(typescript@6.0.3) @@ -75,19 +75,19 @@ importers: dependencies: '@xyflow/react': specifier: ^12.10.2 - version: 12.10.2(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 12.10.2(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) fumadocs-core: specifier: 16.8.10 - version: 16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@1.14.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3) + version: 16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3) fumadocs-mdx: - specifier: 15.0.4 - version: 15.0.4(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.14)(fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@1.14.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)) + specifier: 15.0.7 + version: 15.0.7(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.15)(fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(rolldown@1.0.2)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)) fumadocs-ui: specifier: 16.8.10 - version: 16.8.10(@tailwindcss/oxide@4.3.0)(@types/mdx@2.0.13)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@1.14.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tailwindcss@4.3.0) + version: 16.8.10(@tailwindcss/oxide@4.3.0)(@types/mdx@2.0.13)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tailwindcss@4.3.0) next: specifier: ^16 - version: 16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + version: 16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: specifier: 19.2.6 version: 19.2.6 @@ -100,13 +100,13 @@ importers: version: 4.3.0 '@types/node': specifier: ^24.3.0 - version: 24.12.2 + version: 24.12.4 '@types/react': specifier: ^19 - version: 19.2.14 + version: 19.2.15 '@types/react-dom': specifier: ^19 - version: 19.2.3(@types/react@19.2.14) + version: 19.2.3(@types/react@19.2.15) tailwindcss: specifier: ^4 version: 4.3.0 @@ -117,23 +117,23 @@ importers: packages/cli: dependencies: '@ai-sdk/anthropic': - specifier: 3.0.77 - version: 3.0.77(zod@4.4.3) + specifier: 3.0.78 + version: 3.0.78(zod@4.4.3) '@ai-sdk/devtools': - specifier: 0.0.17 - version: 0.0.17 + specifier: 0.0.18 + version: 0.0.18 '@ai-sdk/google-vertex': - specifier: ^4.0.128 - version: 4.0.128(zod@4.4.3) + specifier: ^4.0.134 + version: 4.0.134(zod@4.4.3) '@anthropic-ai/claude-agent-sdk': - specifier: 0.3.142 - version: 0.3.142(zod@4.4.3) + specifier: 0.3.146 + version: 0.3.146(@anthropic-ai/sdk@0.97.1(zod@4.4.3))(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) '@clack/prompts': specifier: 1.4.0 version: 1.4.0 '@clickhouse/client': - specifier: ^1.18.4 - version: 1.18.4 + specifier: ^1.18.5 + version: 1.18.5 '@commander-js/extra-typings': specifier: 14.0.0 version: 14.0.0(commander@14.0.3) @@ -153,11 +153,11 @@ importers: specifier: ^1.29.0 version: 1.29.0(zod@4.4.3) '@notionhq/client': - specifier: ^5.21.0 - version: 5.21.0 + specifier: ^5.22.0 + version: 5.22.0 ai: - specifier: ^6.0.180 - version: 6.0.180(zod@4.4.3) + specifier: ^6.0.188 + version: 6.0.188(zod@4.4.3) better-sqlite3: specifier: ^12.10.0 version: 12.10.0 @@ -165,14 +165,14 @@ importers: specifier: 14.0.3 version: 14.0.3 fflate: - specifier: ^0.8.2 - version: 0.8.2 + specifier: ^0.8.3 + version: 0.8.3 handlebars: specifier: ^4.7.9 version: 4.7.9 ink: - specifier: ^7.0.2 - version: 7.0.2(@types/react@19.2.14)(react@19.2.6) + specifier: ^7.0.3 + version: 7.0.3(@types/react@19.2.15)(react@19.2.6) lookml-parser: specifier: 7.1.0 version: 7.1.0(js-yaml@4.1.1) @@ -180,23 +180,23 @@ importers: specifier: ^10.2.5 version: 10.2.5 mssql: - specifier: ^12.5.2 - version: 12.5.2(@azure/core-client@1.10.1) + specifier: ^12.5.4 + version: 12.5.4(@azure/core-client@1.10.1) mysql2: specifier: ^3.22.3 - version: 3.22.3(@types/node@24.12.2) + version: 3.22.3(@types/node@24.12.4) openai: - specifier: ^6.37.0 - version: 6.37.0(ws@8.20.1)(zod@4.4.3) + specifier: ^6.38.0 + version: 6.38.0(ws@8.20.1)(zod@4.4.3) p-limit: specifier: ^7.3.0 version: 7.3.0 pg: - specifier: ^8.20.0 - version: 8.20.0 + specifier: ^8.21.0 + version: 8.21.0 posthog-node: - specifier: ^5.0.0 - version: 5.0.0 + specifier: ^5.34.9 + version: 5.34.9 react: specifier: ^19.2.6 version: 19.2.6 @@ -204,8 +204,8 @@ importers: specifier: 3.36.0 version: 3.36.0 snowflake-sdk: - specifier: ^2.4.1 - version: 2.4.1(asn1.js@5.4.1) + specifier: ^2.4.2 + version: 2.4.2(asn1.js@5.4.1) yaml: specifier: ^2.9.0 version: 2.9.0 @@ -227,28 +227,28 @@ importers: version: 12.3.0(@azure/core-client@1.10.1) '@types/node': specifier: ^24.3.0 - version: 24.12.2 + version: 24.12.4 '@types/pg': specifier: ^8.20.0 version: 8.20.0 '@types/react': - specifier: ^19.2.14 - version: 19.2.14 + specifier: ^19.2.15 + version: 19.2.15 '@vitest/coverage-v8': - specifier: ^4.1.6 - version: 4.1.6(vitest@4.1.6) + specifier: ^4.1.7 + version: 4.1.7(vitest@4.1.7) ajv: specifier: 8.20.0 version: 8.20.0 ink-testing-library: specifier: ^4.0.0 - version: 4.0.0(@types/react@19.2.14) + version: 4.0.0(@types/react@19.2.15) typescript: specifier: ^6.0.3 version: 6.0.3 vitest: - specifier: ^4.1.6 - version: 4.1.6(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.6)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)) + specifier: ^4.1.7 + version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)) packages: @@ -264,31 +264,31 @@ packages: '@actions/io@3.0.2': resolution: {integrity: sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==} - '@ai-sdk/anthropic@3.0.77': - resolution: {integrity: sha512-ML8C2M1YvPA1ulEx4TiyF0k1xvC2ikEiPBIC1PPQ0a5xELUGrO2lAaEzsTEoJ+eCeDd8PSBuFJjs+r+9yIwQXA==} + '@ai-sdk/anthropic@3.0.78': + resolution: {integrity: sha512-0OY12G20cUt6iU6htpEA1491Oz++NVxZxlmWGX4B7rSbeZ5pnDmOu6YtW9BKzdZlNx5Gn23i6WMxyZFoMKNcgA==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/devtools@0.0.17': - resolution: {integrity: sha512-CJgo+3DMHOJbxxq1qTgnW4vpFXgBW1pHePMimBW4Go5FPU7iLqppoGX/UC798IXqlD3hncQRPfyBLZjbsJC91w==} + '@ai-sdk/devtools@0.0.18': + resolution: {integrity: sha512-0J25Q7occrkMJM1MrP0KeR8XNdGGKNgzxhOLfxBe/qZBQP6yXgV4H5Gf2DnDC3UgXDBJBskH9nh23doCo2Pebw==} engines: {node: '>=18'} hasBin: true - '@ai-sdk/gateway@3.0.114': - resolution: {integrity: sha512-MqkZ5sd+qiq6RgIxELkoFQXg2/JwK+WCMaot7U+rtrZpWJl3fSyYvc28SC03b256o4F7OXjQtdjTqs81B2w+dA==} + '@ai-sdk/gateway@3.0.118': + resolution: {integrity: sha512-XYPbVoDo1TDMVLe5Eg42gIjdOyxaizh9H0kiSSnTXr+AdrqZvutk/ypLOiqBXPV3D1K3+BSm/sbFeomZJlM64A==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/google-vertex@4.0.128': - resolution: {integrity: sha512-jK8fixb4km2yfgvb9DUFQRpV/jiDB0v9gyxHoHfPydaQvz+CpAz8DTt1quyaM+Wg9G2R8Zo68CYmHbIkUqW2AA==} + '@ai-sdk/google-vertex@4.0.134': + resolution: {integrity: sha512-EaVwzHk7P/Pj1JQtOfN3uLj+zKY6MQOn2hcEEACpbbjdVgBkpWxDjMRIpyYbVlXCLMUeWSYL0qUM54lmis/1BQ==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 - '@ai-sdk/google@3.0.73': - resolution: {integrity: sha512-o2MuIeyvZrFIeIbnbA8Thrr63irdyUBh0uWBZ2lY6yFeXuE/tcwyXF74bDKS4KvTu84uFpQfpbS/LXHGKKXz+g==} + '@ai-sdk/google@3.0.78': + resolution: {integrity: sha512-iPkZHiaaBNreaVX2fLpc+SAa7OJPV6f7pZRK98lWTI4vf0D546+9eEQ6T2FagJAHO0K0gEyzx5zogCoHbJnhQg==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -317,58 +317,60 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} - '@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.142': - resolution: {integrity: sha512-yBHOiRqJ8JcD9OAMGJALbypaD3u3K8hyUmcnZ+91AHJtymzWxuMkVi4IY1qp8L5jzkKeTnvYfCspzkbiHLuYWg==} + '@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.146': + resolution: {integrity: sha512-0IIvlEaenq2CRSVx5Bo5BaCtHQXS87GancM35WKEYveGVLn6DI+5G7ikYuTE4AKRPkMnogFtY4BJt6LulWGj+A==} cpu: [arm64] os: [darwin] - '@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.142': - resolution: {integrity: sha512-/a/bVMjvAl3gNzWiPIgynYktTYckTcp4YAacV/2F4Jd8XeCV0+DMQW7OFeR+3fnPcBg/8kcOAVYfLZXDExqO1w==} + '@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.146': + resolution: {integrity: sha512-Dk5xJ03Ff1JXbMRP1t2wc/TyfY6xF/2Ysp31wMhFPjoNiKSPHMWaIg242+T3CHdxLWmJ8plWHL1HL5cyZ/LCkw==} cpu: [x64] os: [darwin] - '@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.142': - resolution: {integrity: sha512-KZuwSupNJovnMJ7MZxjp1Qq0yu7rAmbzO4Zlmr3jtKDU95t2kgs3c6j4evzQDCgTQMlwH8QTSV4mItDGxlYEbg==} + '@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.146': + resolution: {integrity: sha512-QlCid0ucdrmhUAOewfQjaofN2wlokWcfFTxSFePTSj1umk35JO7TDFP700F7jU49r1fPWIdvJpPwWGyB0DeFPA==} cpu: [arm64] os: [linux] libc: [musl] - '@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.142': - resolution: {integrity: sha512-QKG553PSbIcQ5KLvnl2ekfy5lTyU3dW/X5fDQlRLv4YHNHnqf2o7scJ6eUdfaVTQdIZ+Pa7SNN3bsvVs4bNjQw==} + '@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.146': + resolution: {integrity: sha512-mzBXDDWWBAC/vDtAYpO1G/dq5QvJtYSPXsqcb+sNdcDhiuf4IYnYp7ytRncYlsUNDkLmX6Gk2jkWAHUUA2Lozg==} cpu: [arm64] os: [linux] libc: [glibc] - '@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.142': - resolution: {integrity: sha512-QkDwLMsdYO7n/i1zPCt5YZIet5u+Eo07UpF9UX5yD7bnwRZKDe22L6LVVwiLLjeTO0fTz+uNY7w9/XOYQMlxUQ==} + '@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.146': + resolution: {integrity: sha512-E3coK1ThQT08KIX80RLcsq7DWXFllCKOzoOe32it/bdtY56TBgPY9xemwXhIJ+cVBHTI9/MpBSIlKBcFCt+yQA==} cpu: [x64] os: [linux] libc: [musl] - '@anthropic-ai/claude-agent-sdk-linux-x64@0.3.142': - resolution: {integrity: sha512-o1QZmCNRL5BFTc14KEvT23Fxm1jNv0aa0e9T0OZUjua0oW8DRpri3HKvDEM36qEGWUOANBG7h6Ca/KNqxaTnYg==} + '@anthropic-ai/claude-agent-sdk-linux-x64@0.3.146': + resolution: {integrity: sha512-B2baXU1tCBT5CVlD7jJMKjpC4xdO45NUIWpqImmwuOfKvlM/PITjyTXyTY662mGZf1dBmdqBBsqirwFH/jhi8Q==} cpu: [x64] os: [linux] libc: [glibc] - '@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.142': - resolution: {integrity: sha512-x8lbY1m7E/BiFF0Gu/Mx9lkD/zW3vBr3viw0GYNuqY9GYHfLOX9+l9H8C+INeGzB4+ibG8+xD2pnRhWdQxuvUg==} + '@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.146': + resolution: {integrity: sha512-CIwQxGX2r/yWpjCJ6ahB3smKXhghWgGTxL98+LGW52TUwqTiBnlNrH9DPqqgv1/+Hyquw6xfLrKU+StyfMgiLw==} cpu: [arm64] os: [win32] - '@anthropic-ai/claude-agent-sdk-win32-x64@0.3.142': - resolution: {integrity: sha512-NpNxdiCEUNjjwvBltpDnkgdjVQ+nRsALpfM1Pe4GhnYiOkTk/TvjMZUuA2qGh0F8KyF0FbqzUsi0uXIgojJT5w==} + '@anthropic-ai/claude-agent-sdk-win32-x64@0.3.146': + resolution: {integrity: sha512-qmxrsyaqA8s4HShqJls7ZCRjdoqN66Jo/hbjQNB3uHepD8tEO1iD19aPV4+osdLT7feMkhDBfLT07Q30R2NB5w==} cpu: [x64] os: [win32] - '@anthropic-ai/claude-agent-sdk@0.3.142': - resolution: {integrity: sha512-k1xBon6ov0PT/vZNf+Z+SuAqmylGJU/+a+h/k04MW5cBbzOIwiVcGFRTGJ/qbY5pcboJbLtts/yBwSu9AvSipg==} + '@anthropic-ai/claude-agent-sdk@0.3.146': + resolution: {integrity: sha512-hK9/Ng+hOyexUemTxdIUsSWJ9o2LFi2YNWzHwz8/YMCohUYOnFMZkBiENvUAb0WIc5hieOyBZrOIlg5OewuJMg==} engines: {node: '>=18.0.0'} peerDependencies: + '@anthropic-ai/sdk': '>=0.93.0' + '@modelcontextprotocol/sdk': ^1.29.0 zod: ^4.0.0 - '@anthropic-ai/sdk@0.93.0': - resolution: {integrity: sha512-q9vaSZQVFx6B/gPxetGYfLXSJD5v0sOmh0OpZDq7yCrTSA+Rscvrtyol7JJTW40wEpQB4U1B4JXzxQitbQ3CAA==} + '@anthropic-ai/sdk@0.97.1': + resolution: {integrity: sha512-wOf7AUeJPitcVpvKO4UMu63mWH5SaVipkGd7OOQJt/G6VYGlV8D2Gp9dLxOrttDJh/9gqPqdaBwDGcBevumeAg==} hasBin: true peerDependencies: zod: ^3.25.0 || ^4.0.0 @@ -407,136 +409,127 @@ packages: resolution: {integrity: sha512-oDJJ7rM1osvfBdfZuhQ5DM6lHD9iuypL9m2LsEiA/lB8xuE5uPYsftNDcS0J9VRXFSvYTqC14K7Y5vMMKMg0vw==} engines: {node: '>=20.0.0'} - '@aws-sdk/core@3.974.8': - resolution: {integrity: sha512-njR2qoG6ZuB0kvAS2FyICsFZJ6gmCcf2X/7JcD14sUvGDm26wiZ5BrA6LOiUxKFEF+IVe7kdroxyE00YlkiYsw==} + '@aws-sdk/core@3.974.12': + resolution: {integrity: sha512-qrqgioqYFjwR6LatVNS1L2Vk++EwRIxqSQXPKNv5Ofux2D8UNgqMQ1znnMyEImXquVPTtbf71fc128pvmU6y9A==} engines: {node: '>=20.0.0'} - '@aws-sdk/crc64-nvme@3.972.7': - resolution: {integrity: sha512-QUagVVBbC8gODCF6e1aV0mE2TXWB9Opz4k8EJFdNrujUVQm5R4AjJa1mpOqzwOuROBzqJU9zawzig7M96L8Ejg==} + '@aws-sdk/crc64-nvme@3.972.8': + resolution: {integrity: sha512-fVfUCL/Xh2zINYMPZvj+iBn6XWouQf0DAnjaWCI9MkmqXzL2Iy5FoQB8O7syFe6gN6AH1ecDDU58T51Ou0kFkA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-env@3.972.34': - resolution: {integrity: sha512-XT0jtf8Fw9JE6ppsQeoNnZRiG+jqRixMT1v1ZR17G60UvVdsQmTG8nbEyHuEPfMxDXEhfdARaM/XiEhca4lGHQ==} + '@aws-sdk/credential-provider-env@3.972.38': + resolution: {integrity: sha512-m3WjZEgPtioMhPmwqUt+DhlTJ2i9ufR6DhfkyXojb9puEvfR+ur2U5shavu5/Cc9WHHsDCvALi6UFHgcqjhQ5w==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-http@3.972.36': - resolution: {integrity: sha512-DPoGWfy7J7RKxvbf5kOKIGQkD2ek3dbKgzKIGrnLuvZBz5myU+Im/H6pmc14QcnFbqHMqxvtWSgRDSJW3qXLQg==} + '@aws-sdk/credential-provider-http@3.972.40': + resolution: {integrity: sha512-D78L/m2Dr6cJnnSvWoAudPhQmCwmJ7j6APXsPYmFpPaKfQTfCSu0rdm8j14Np+VmXF9z8Aj8HE3xFpsrwtfgeg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-ini@3.972.38': - resolution: {integrity: sha512-oDzUBu2MGJFgoar05sPMCwSrhw44ASyccrHzj66vO69OZqi7I6hZZxXfuPLC8OCzW7C+sU+bI73XHij41yekgQ==} + '@aws-sdk/credential-provider-ini@3.972.42': + resolution: {integrity: sha512-Mu5ESvFXeinafVM8jTIvRqcvK2Ehj4kz3auT39yUcHwu1Vfxo6xRlmUafdKLW4tusjAJukQwK09sCSMgOm7OKg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-login@3.972.38': - resolution: {integrity: sha512-g1NosS8qe4OF++G2UFCM5ovSkgipC7YYor5KCWatG0UoMSO5YFj9C8muePlyVmOBV/WTI16Jo3/s1NUo/o1Bww==} + '@aws-sdk/credential-provider-login@3.972.42': + resolution: {integrity: sha512-O6WkZga3kf0yqyJYd1dbeJqVhEgJx/x1UaLgtbR+XuL/YP+K5y6QTxQKL7ka9z3jnQASESKGAPnRyt4D5hQrxA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-node@3.972.39': - resolution: {integrity: sha512-HEswDQyxUtadoZ/bJsPPENHg7R0Lzym5LuMksJeHvqhCOpP+rtkDLKI4/ZChH4w3cf5kG8n6bZuI8PzajoiqMg==} + '@aws-sdk/credential-provider-node@3.972.43': + resolution: {integrity: sha512-D/DJmbrWRP5BXEO3FH+ar4el+2n6OlGofiud7dQun2jES+AQEJjczenp1jBb4MBN7CpGpS8nsWGQLtuzc9tQbA==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-process@3.972.34': - resolution: {integrity: sha512-T3IFs4EVmVi1dVN5RciFnklCANSzvrQd/VuHY9ThHSQmYkTogjcGkoJEr+oNUPQZnso52183088NqysMPji1/Q==} + '@aws-sdk/credential-provider-process@3.972.38': + resolution: {integrity: sha512-EnbYVajGgbkb24s0K1eo4VNAPV5mHIET7LSvirTaFCwkfrfaOJxtSE+wY/tJdKDS21cEYkZs2ruCaAm+W4iblg==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-sso@3.972.38': - resolution: {integrity: sha512-5ZxG+t0+3Q3QPh8KEjX6syskhgNf7I0MN7oGioTf6Lm1NTjfP7sIcYGNsthXC2qR8vcD3edNZwCr2ovfSSWuRA==} + '@aws-sdk/credential-provider-sso@3.972.42': + resolution: {integrity: sha512-RVV/9NbFwI8ZHEH5dn39lGyFmSbSVj1+orZdr6QsOe1mW9DCglmlen0cFaNZmCcqkqc7erNRHNBduxbeZuHAnw==} engines: {node: '>=20.0.0'} - '@aws-sdk/credential-provider-web-identity@3.972.38': - resolution: {integrity: sha512-lYHFF30DGI20jZcYX8cm6Ns0V7f1dDN6g/MBDLTyD/5iw+bXs3yBr2iAiHDkx4RFU5JgsnZvCHYKiRVPRdmOgw==} + '@aws-sdk/credential-provider-web-identity@3.972.42': + resolution: {integrity: sha512-/67fXX0ddllD4u2Nujc5PvT4byHgpMUfz6+RxIKi/0nFIckeorm7JvXgzBuDyVKw0s58EbofmETDWUf9vTEuHQ==} engines: {node: '>=20.0.0'} '@aws-sdk/ec2-metadata-service@3.1045.0': resolution: {integrity: sha512-cYjEbjbGScw9l8TmI9AFYde1hIu5c9Wt0Qp7/cbWBHBiOzMfLwmjGhd5+4AUm1RsnmC5HZ/WOA9iGJHfHL4cuA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-bucket-endpoint@3.972.10': - resolution: {integrity: sha512-Vbc2frZH7wXlMNd+ZZSXUEs/l1Sv8Jj4zUnIfwrYF5lwaLdXHZ9xx4U3rjUcaye3HRhFVc+E5DbBxpRAbB16BA==} + '@aws-sdk/middleware-bucket-endpoint@3.972.14': + resolution: {integrity: sha512-Aaj0d+xbo1jJquBWJP0/9V/XZRYukO3LWIRp3dOLHmoFrYKb4YZ0aLefgVHfGcNOVBS2ZTq7L/n5JcrE7DaC+Q==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-expect-continue@3.972.10': - resolution: {integrity: sha512-2Yn0f1Qiq/DjxYR3wfI3LokXnjOhFM7Ssn4LTdFDIxRMCE6I32MAsVnhPX1cUZsuVA9tiZtwwhlSLAtFGxAZlQ==} + '@aws-sdk/middleware-expect-continue@3.972.12': + resolution: {integrity: sha512-dA5pKTom/Ls9mgeyeaRBNQrRIVOLVjv4AmKOB0/e4yaiXEUy0gSz2d3liP8JHtYoCAEWySU1jWnyzwLOREN+4g==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-flexible-checksums@3.974.16': - resolution: {integrity: sha512-6ru8doI0/XzszqLIPXf0E/V7HhAw1Pu94010XCKYtBUfD0LxF0BuOzrUf8OQGR6j2o6wgKTHUniOmndQycHwCA==} + '@aws-sdk/middleware-flexible-checksums@3.974.20': + resolution: {integrity: sha512-NdnMVQCR1YjIcqFAiNLdBiOwr2DyQDB2IiXQrBhzolKOv32ae4d4Ll7IzLMi04eMHiq/o/Y/GjFuVjF9HuG0QA==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-host-header@3.972.10': - resolution: {integrity: sha512-IJSsIMeVQ8MMCPbuh1AbltkFhLBLXn7aejzfX5YKT/VLDHn++Dcz8886tXckE+wQssyPUhaXrJhdakO2VilRhg==} + '@aws-sdk/middleware-host-header@3.972.13': + resolution: {integrity: sha512-EA3+u2LD3kGcfRNmCSjyJuzX4XvG4zYv57i4ZksH+1IEciuSyHQGvzivEz7vZ+jbRPdAAe7WWKy/4M8InCKDcw==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-location-constraint@3.972.10': resolution: {integrity: sha512-rI3NZvJcEvjoD0+0PI0iUAwlPw2IlSlhyvgBK/3WkKJQE/YiKFedd9dMN2lVacdNxPNhxL/jzQaKQdrGtQagjQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-logger@3.972.10': - resolution: {integrity: sha512-OOuGvvz1Dm20SjZo5oEBePFqxt5nf8AwkNDSyUHvD9/bfNASmstcYxFAHUowy4n6Io7mWUZ04JURZwSBvyQanQ==} + '@aws-sdk/middleware-logger@3.972.12': + resolution: {integrity: sha512-NxB2dS4/mV3380hNkC72TkhMaLLjWGGBeTAEucqlJptVVovTbNmQWZLwaMC74ICo9NZHmFiBVVTHzDfAh/3y6Q==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-recursion-detection@3.972.11': - resolution: {integrity: sha512-+zz6f79Kj9V5qFK2P+D8Ehjnw4AhphAlCAsPjUqEcInA9umtSSKMrHbSagEeOIsDNuvVrH98bjRHcyQukTrhaQ==} + '@aws-sdk/middleware-recursion-detection@3.972.14': + resolution: {integrity: sha512-bqL+upATpOJ/7px4IVfMVxcM6Lyt9uRizmEx3mNg4N6+IQlnOaYXXOJ4TNX6P0mKPPW0lwn9ZW8QEhXwQuCH9A==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-sdk-s3@3.972.37': - resolution: {integrity: sha512-Km7M+i8DrLArVzrid1gfxeGhYHBd3uxvE77g0s5a52zPSVosxzQBnJ0gwWb6NIp/DOk8gsBMhi7V+cpJG0ndTA==} + '@aws-sdk/middleware-sdk-s3@3.972.41': + resolution: {integrity: sha512-M4T2I2WPuH5WQpU8Tsp+u2bcO29zGRkU14ATzuqb9I4xh8tzsLqtp4hzaJM5aO2dhMZnHDzyQwSFVgc3XbnoGg==} engines: {node: '>=20.0.0'} '@aws-sdk/middleware-ssec@3.972.10': resolution: {integrity: sha512-Gli9A0u8EVVb+5bFDGS/QbSVg28w/wpEidg1ggVcSj65BDTdGR6punsOcVjqdiu1i42WHWo51MCvARPIIz9juw==} engines: {node: '>=20.0.0'} - '@aws-sdk/middleware-user-agent@3.972.38': - resolution: {integrity: sha512-iz+B29TXcAZsJpwB+AwG/TTGA5l/VnmMZ2UxtiySOZjI6gCdmviXPwdgzcmuazMy16rXoPY4mYCGe7zdNKfx5A==} + '@aws-sdk/middleware-user-agent@3.972.42': + resolution: {integrity: sha512-U7jjlJKQnuUlI2swC2umFLFzLAxMLudSRFv+Bqk2F8ORmr5bG25qsFxGm4GEFwoZeGaFFnAFmTY0xReVRfyl2A==} engines: {node: '>=20.0.0'} - '@aws-sdk/nested-clients@3.997.6': - resolution: {integrity: sha512-WBDnqatJl+kGObpfmfSxqnXeYTu3Me8wx8WCtvoxX3pfWrrTv8I4WTMSSs7PZqcRcVh8WeUKMgGFjMG+52SR1w==} + '@aws-sdk/nested-clients@3.997.10': + resolution: {integrity: sha512-FtQ/Bt327peZJuyo4WZSOLVUTw9ujRxntepiC7L65FxA2P82Xlq0g14T22BuqBUeMjDoxa9nvwiMHjLIfP3eUg==} engines: {node: '>=20.0.0'} - '@aws-sdk/region-config-resolver@3.972.13': - resolution: {integrity: sha512-CvJ2ZIjK/jVD/lbOpowBVElJyC1YxLTIJ13yM0AEo0t2v7swOzGjSA6lJGH+DwZXQhcjUjoYwc8bVYCX5MDr1A==} + '@aws-sdk/region-config-resolver@3.972.16': + resolution: {integrity: sha512-/YaivCvKUkEeMN9VTKBSvBn5w/4osAM1YboM58DKaLF/vqFGf/FdJCLmppqiPPJWZaXcASqByVjc3evE7KHKdA==} engines: {node: '>=20.0.0'} - '@aws-sdk/signature-v4-multi-region@3.996.25': - resolution: {integrity: sha512-+CMIt3e1VzlklAECmG+DtP1sV8iKq25FuA0OKpnJ4KA0kxUtd7CgClY7/RU6VzJBQwbN4EJ9Ue6plvqx1qGadw==} + '@aws-sdk/signature-v4-multi-region@3.996.27': + resolution: {integrity: sha512-0Phbz4t6HI3D3skxvG2uI+VWU034/nSIw1T8d+FPzzQG9EQTrw94o9mOKO2Gv3n3Oc8P7JD7RAUxkoneLWv5Eg==} engines: {node: '>=20.0.0'} - '@aws-sdk/token-providers@3.1041.0': - resolution: {integrity: sha512-Th7kPI6YPtvJUcdznooXJMy+9rQWjmEF81LxaJssngBzuysK4a/x+l8kjm1zb7nYsUPbndnBdUnwng/3PLvtGw==} + '@aws-sdk/token-providers@3.1049.0': + resolution: {integrity: sha512-r7+d0lQMTHKypkmaF5jRTBYLYHCUHzt3gaVoN9SidLhQeWhCmHk3AKrboDTpPF5b7Pt7vKu3+oeMjznM2Eu1ow==} engines: {node: '>=20.0.0'} '@aws-sdk/types@3.973.8': resolution: {integrity: sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-arn-parser@3.972.3': - resolution: {integrity: sha512-HzSD8PMFrvgi2Kserxuff5VitNq2sgf3w9qxmskKDiDTThWfVteJxuCS9JXiPIPtmCrp+7N9asfIaVhBFORllA==} - engines: {node: '>=20.0.0'} - - '@aws-sdk/util-endpoints@3.996.8': - resolution: {integrity: sha512-oOZHcRDihk5iEe5V25NVWg45b3qEA8OpHWVdU/XQh8Zj4heVPAJqWvMphQnU7LkufmUo10EpvFPZuQMiFLJK3g==} + '@aws-sdk/util-endpoints@3.996.11': + resolution: {integrity: sha512-BUMJ6VoL54r6Udj/wKy8uKRIndL04rGbaS/wTIV0dM1ewxSrR8yARBHdvZKQsK55ZSW2JrmAPk3KP15kBDxJMw==} engines: {node: '>=20.0.0'} '@aws-sdk/util-locate-window@3.965.5': resolution: {integrity: sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==} engines: {node: '>=20.0.0'} - '@aws-sdk/util-user-agent-browser@3.972.10': - resolution: {integrity: sha512-FAzqXvfEssGdSIz8ejatan0bOdx1qefBWKF/gWmVBXIP1HkS7v/wjjaqrAGGKvyihrXTXW00/2/1nTJtxpXz7g==} + '@aws-sdk/util-user-agent-browser@3.972.13': + resolution: {integrity: sha512-wfk9ZdVwh187gdGXB1EyAoprwjSMt/bSfVtva+OaZx+LyNdKD7smlZf611yMd42UpfQ9vaS8NOftjSajgpdd+w==} - '@aws-sdk/util-user-agent-node@3.973.24': - resolution: {integrity: sha512-ZWwlkjcIp7cEL8ZfTpTAPNkwx25p7xol0xlKoWVVf22+nsjwmLcHYtTPjIV1cSpmB/b6DaK4cb1fSkvCXHgRdw==} + '@aws-sdk/util-user-agent-node@3.973.28': + resolution: {integrity: sha512-A2l/PTRzsOS9L8dmZbXtDyJQgeeX+qjqLJ+fr0UU5Dz0AUQMuxgZCPSLKZgUDlHAmLFuk34owdMEvJxmDTBgRg==} engines: {node: '>=20.0.0'} - peerDependencies: - aws-crt: '>=1.0.0' - peerDependenciesMeta: - aws-crt: - optional: true - '@aws-sdk/xml-builder@3.972.22': - resolution: {integrity: sha512-PMYKKtJd70IsSG0yHrdAbxBr+ZWBKLvzFZfD3/urxgf6hXVMzuU5M+3MJ5G67RpOmLBu1fAUN65SbWuKUCOlAA==} + '@aws-sdk/xml-builder@3.972.24': + resolution: {integrity: sha512-V8z5YcDPfsvzrBlj0xR1vhRtocblhYbqdreCJB/voGd4Sr5zjNAeWxexbnqVtskTJe0vFb5KMqbSL++ePl+zRw==} engines: {node: '>=20.0.0'} '@aws/lambda-invoke-store@0.2.4': @@ -606,16 +599,16 @@ packages: resolution: {integrity: sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==} engines: {node: '>=20.0.0'} - '@azure/msal-browser@5.9.0': - resolution: {integrity: sha512-CzE+4PefDSJWj26zU7G1bKchlGRRHMBFreG4tAlGuzyI8hAPiYGobaJvZBgZBf6L63iphX7VH+ityL8VgEQz9Q==} + '@azure/msal-browser@5.11.0': + resolution: {integrity: sha512-zkGNYS3TwY8lUpPIafAmsFCYZbgFixY9y/LZB9GUg0IILoHTqpN26j5OrkL1AQThh/YdZsawe4iWXfp85lFVxg==} engines: {node: '>=0.8.0'} - '@azure/msal-common@16.5.2': - resolution: {integrity: sha512-GkDEL6TYo3HgT3UuqakdgE9PZfc1hMki6+Hwgy1uddb/EauvAKfu85vVhuofRSo22D1xTnWt8Ucwfg4vSCVwvA==} + '@azure/msal-common@16.6.2': + resolution: {integrity: sha512-hQjjsekAjB00cM1EmatWJlzhEoK2Qhz7Rj5gvM6tYf8iL7RM3tkxlpU9fG0+ofkulzg9AEEA6dIEnSmDr5ZqUA==} engines: {node: '>=0.8.0'} - '@azure/msal-node@5.1.5': - resolution: {integrity: sha512-ObTeMoNPmq19X3z40et9Xvs4ZoWVeJg43PZMRLG5iwVL+2nCtAerG3YTDItqPp1CfXNwmCXBbg8jn1DOx65c3g==} + '@azure/msal-node@5.2.2': + resolution: {integrity: sha512-toS+2AePxqyzb0YOKttDOOiSl3jrkK9aiqIvpurpis0O34QcIS5gToqrgT39p04Dpxw3YoUU0lxJKTpSFFfA6Q==} engines: {node: '>=20'} '@azure/storage-blob@12.26.0': @@ -716,11 +709,11 @@ packages: resolution: {integrity: sha512-S0My7XPGIgpRWMDG8uRqalbgT+a6FmCUdOW+HaIOVVpUPHOb7RrpvjTjiODadKp06fsrVDJZlIzc6yCTp4AnxA==} engines: {node: '>= 20.12.0'} - '@clickhouse/client-common@1.18.4': - resolution: {integrity: sha512-kPPtv8yQmplNAxfrAJvwBJq5dd+IWRewEbXSpUvtyEJXlrB8lt/ZH63jUS81Nmd+lK5MRvpOFXPoN3iogkvg+A==} + '@clickhouse/client-common@1.18.5': + resolution: {integrity: sha512-g9LwcS1dvkatKDsIjT1PwUHldsiYzwdKAB0nXfd9APLd+t4PrNJa+my+dXcqJdmcWyhWjKLP/2/ztBwgxp+sbQ==} - '@clickhouse/client@1.18.4': - resolution: {integrity: sha512-jjCrddI+e2OVXGh/MQY92K9r8Z/iwqaZtUXNI/MfZ/y9VGYwfbQsXRzp4Jv6w4Hgxvr4sLcz9YwIvkCBQ6X/mw==} + '@clickhouse/client@1.18.5': + resolution: {integrity: sha512-4FfoyMkFWhsdNMuXsoEL6l3c12svA63BBJBtDo9SrxRZ14RdmN6jLr/rF3f84BK8cFoxETZCSeKlsbk6NNYebw==} engines: {node: '>=16'} '@colors/colors@1.5.0': @@ -1240,8 +1233,8 @@ packages: '@nodable/entities@2.1.0': resolution: {integrity: sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==} - '@notionhq/client@5.21.0': - resolution: {integrity: sha512-X+T+hzaQFleOUGm4xUOUm51pOpdZ1+6T4BsRjGlcdEOTJLNkUEv8nZATq9O3ZY4NQEgICc0qwQ0I25OdYprX0w==} + '@notionhq/client@5.22.0': + resolution: {integrity: sha512-lZ3JGBCd6O6MNHWn/58QcUqX1FgmlcODcx/EaUEEpuxLXF5tSi+v29Vzoz8mZ6JgDWDn5pMzzjB69QevYjQQZA==} engines: {node: '>=18'} '@octokit/auth-token@6.0.0': @@ -1292,146 +1285,146 @@ packages: '@octokit/types@16.0.0': resolution: {integrity: sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg==} - '@opentelemetry/api@1.9.0': - resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + '@opentelemetry/api@1.9.1': + resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} '@orama/orama@3.1.18': resolution: {integrity: sha512-a61ljmRVVyG5MC/698C8/FfFDw5a8LOIvyOLW5fztgUXqUpc1jOfQzOitSCbge657OgXXThmY3Tk8fpiDb4UcA==} engines: {node: '>= 20.0.0'} - '@oxc-parser/binding-android-arm-eabi@0.128.0': - resolution: {integrity: sha512-aca6ZvzmCBUGOANQRiRQRZuRKYI3ENhcit6GisnknOOmcezfQc7xJ4dxlPU7MV7mOvrC7RNR1u3LAD7xyaiCxA==} + '@oxc-parser/binding-android-arm-eabi@0.130.0': + resolution: {integrity: sha512-h/xYU8/7ADWzVSf5I+YalLpj33LOy9CI/zgbJNIZ5eunRBG+Czqa3lZsvuPHHf3rOt6z1c5+UzoxjbAzAvhwVw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxc-parser/binding-android-arm64@0.128.0': - resolution: {integrity: sha512-BbeDmuohoJ7Rz/it5wnkj69i/OsCPS3Z51nLEzwO/Y6YshtC4JU+15oNwhY8v4LRKRYclRc7ggOikwrsJ/eOEQ==} + '@oxc-parser/binding-android-arm64@0.130.0': + resolution: {integrity: sha512-oFWFJrsGv9siFM4HjMqKNB7IuIZD/SMmZdCXl8xyx7lDplGvPKyewpOo272rSWgMXe2Wx7bWI0Yj+gkHv4qbeg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-parser/binding-darwin-arm64@0.128.0': - resolution: {integrity: sha512-tRUHPt80417QmvNpoSslJT1VY8NUbWdrWR+L14Zn+RbOTcaqB8E6PYE/ZGN8jjWBzqporiA/H4MfO50ew/NCNA==} + '@oxc-parser/binding-darwin-arm64@0.130.0': + resolution: {integrity: sha512-sGUzupdTplK9jQg7eJZ878HfEgQjJNBc6dAYVWJ9W5aU+J8rLfRJhTVsKThiu1pNwm6Y1qKCcbC6WhNWSXR3Ig==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.128.0': - resolution: {integrity: sha512-rWI2Hb1Nt3U/vKsjyNvZzDC8i/l144U20DKjhzaTmwIhIiSRGeroPWWiImwypmKLqrw8GuIixbWJkpGWLbkzrQ==} + '@oxc-parser/binding-darwin-x64@0.130.0': + resolution: {integrity: sha512-PsB4cdCISbC00Uy8eiD8bc2AkGWjZqrSrJnkBFuG2ptrrf6mZ2F5gLFSjOAVMMgZPg8B1D7OydJwLWSfyI2Plg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.128.0': - resolution: {integrity: sha512-hhpdVMaNCLgQxjgNPeeFzSeJMmZPc5lKfv0NGSI3egZq9EdnEGqeC8JsYsQjK7PoQgbvZ17xlj0SO5ziH5Obkg==} + '@oxc-parser/binding-freebsd-x64@0.130.0': + resolution: {integrity: sha512-DgABp3l38hS77JbXCV4qk1+n6DPym5u8zzwuweokezm2tX194nDSJDENbDRECxVsiNbprKATLbk+Z5wlHT0OHw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.128.0': - resolution: {integrity: sha512-093zNw0zZ/e/obML+rhlSdmnzR0mVZluPcAkxunEc5E3F0yBVsFn24Y1ILfsEte11Ud041qn/gp2OJ1jxNqUng==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.130.0': + resolution: {integrity: sha512-4Kn3CTEmwFrzhTSC/JuUW16qovmaMdX7jeSKbL8w0pLtLww7To1a2XJi9Z5uD8QWUkfUHhqfV+VD6dVzBnWzoA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.128.0': - resolution: {integrity: sha512-fq7DmKmfC+dvD97IXrgbph6Jzwe0EDu+PYMofmzZ6fv5X1k9vtaqLpDGMuICO9MmUnyKAQmVl+wIv2RNy4Dz8g==} + '@oxc-parser/binding-linux-arm-musleabihf@0.130.0': + resolution: {integrity: sha512-D35KZM3F4rRu1uAFKyBlg3Gaf/ybCjyaPR1hfgvk5ex8NtcTmRgc0JgSighEyNg96TPrFhemFba68SZuxaha8w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.128.0': - resolution: {integrity: sha512-Xvm48jJah8TlIrURIjNOP/gNiGe6aKvCB+r06VliflFo8Kq7VOLE8PxtgShJzZIqubrgdMdYfvuPPozn7F6MbQ==} + '@oxc-parser/binding-linux-arm64-gnu@0.130.0': + resolution: {integrity: sha512-Q9o7oVlo955KHwS8l1u0bCzIx+JsZUA3XToLXC+MsMhye/9LeBQbt84nh120cl2XLy+TEzvugYDiHShg5yaX6Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-arm64-musl@0.128.0': - resolution: {integrity: sha512-M7iwBGmYJTx+pKOYFjI0buop4gJvlmcVzFGaXPt21DKpQkbQZG1f63Yg7LloIYT/t9yLxCw0Lhfx/RFlAlMSjA==} + '@oxc-parser/binding-linux-arm64-musl@0.130.0': + resolution: {integrity: sha512-EiJ/gC0ljbcwVpycC8YWw6ggMbtsPX8XMOt0mPx0aqWeMsNR+L9m05Flbvd5T+GlivG+GkSWQL7tM9SRFpM/dw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-ppc64-gnu@0.128.0': - resolution: {integrity: sha512-21LGNIZb1Pcfk5/EGsqabrxv4yqQOWis1407JJrClS7XpFCrbvr74YAB1V+m54cYbwvO6UWwQqS4WecxiyfCRg==} + '@oxc-parser/binding-linux-ppc64-gnu@0.130.0': + resolution: {integrity: sha512-b+h/lsLLurp756dMGizNs5uPaJfyEdWrTcV5t8M609jWm1DEHB1StpRXCkyvwtkJx3m+qL5BNQ0dEKan/4yGFA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-gnu@0.128.0': - resolution: {integrity: sha512-gyHjOTFpg9bTTYjxPmQirvufb89+VdZwVfcMtAUyPr6F5H8ZswvCQshK4qOW+Q+2Xyb33hduRgY/eFHJQjU/vQ==} + '@oxc-parser/binding-linux-riscv64-gnu@0.130.0': + resolution: {integrity: sha512-O19Cil83XAyjEFfo8WhkMwY58ALqZ7ckjGL+25mjMIuF84urWBeANH0FC8B8BsSSygWU3/1aY3ADdDbp+wlBnw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-musl@0.128.0': - resolution: {integrity: sha512-X6Q2oKUrP5GyDd2xniuEBLk6aFQCZ97W2+aVXGgJXdjx5t4/oFuA9ri0wLOUrBIX+qdSuK581snMBio4z910eA==} + '@oxc-parser/binding-linux-riscv64-musl@0.130.0': + resolution: {integrity: sha512-BgXRVC0+83n3YzCscLQjj6nbyeBIVeZYPTI4fFMAE4WNm2+4RXhWp03IVizL7esIz36kgmT48aebk1iM+cs8sw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-s390x-gnu@0.128.0': - resolution: {integrity: sha512-BdzTmqxfxoYkpgokoLaSnOX6T+R3/goL42klre2tnG+kHbG2TXS0VN+P5BPofH1axdKOHy5ei4ENZrjmCOt2lA==} + '@oxc-parser/binding-linux-s390x-gnu@0.130.0': + resolution: {integrity: sha512-6tJz0xvnGhsokE7N1WlUSBXibpYmT9xSJFS1Ce41Km/+8gQvdlW8MLhRv8PD0L7ix8vRG0FDDepp3jdOFzdVdw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-gnu@0.128.0': - resolution: {integrity: sha512-OO1nW2Q7sSYYvJZpDHdvyFSdRaVcQqRijZSSmWVMqFxPYy8cEF45zJ9fcdIYuzIT3jYq6YRhEFm/VMWNWhE22Q==} + '@oxc-parser/binding-linux-x64-gnu@0.130.0': + resolution: {integrity: sha512-9aCWj83dp3heTQGmGnZGdIWgxjZrr/7VQ0TGFHH5PKByxJKF2Hcr4qvaSUHhhGEa3MSsDjTL1YDP8RAgdL5/Cg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-musl@0.128.0': - resolution: {integrity: sha512-4NehAe404MRdoZVS9DW8C5XbJwbXIc/KfVlYdpi5vE4081zc9Y0YzKVqyOYj/Puye7/Do+ohaONBFWlEHYl9hw==} + '@oxc-parser/binding-linux-x64-musl@0.130.0': + resolution: {integrity: sha512-afXt87aZBqrUVli8TB/I8H1G50RDWcwirjWtXGXYqJ2ZqWEiErH7V72j3LUSDZaivmtu2OLX0KQ/mbhP81mr7A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-parser/binding-openharmony-arm64@0.128.0': - resolution: {integrity: sha512-kVbqgW9xLL8bh8oc7aYOJilRKXE5G33+tE0jan+duo/9OriaFRpijcCwT2waWs2oqYROYq0GlE7/p3ywoshVeg==} + '@oxc-parser/binding-openharmony-arm64@0.130.0': + resolution: {integrity: sha512-I0NCrZV/YZuCGWgqwNN/GO/iXlLF2z+Wgc7u+Aa9N4P51oYeIa0XT+zVBUne4csO9GqxskXgI4g8JzzWGRpfOw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxc-parser/binding-wasm32-wasi@0.128.0': - resolution: {integrity: sha512-L38ojghJYHmgiz6fJd7jwLB/ESDBpB02NdFxh+smqVM6P2anCEvHn0jhaSrt5eVNR1Ak8+moOeftUlofeyvniA==} + '@oxc-parser/binding-wasm32-wasi@0.130.0': + resolution: {integrity: sha512-sJgQkGaBX0WJvPUDfwciex6IcTk5O5NLQ1bhEb6f3nBruh1GshKMRSMt2bxZlYrgBzjyBbJzsnO+InPG0bg+fA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@oxc-parser/binding-win32-arm64-msvc@0.128.0': - resolution: {integrity: sha512-xgvO35GyHBtjlQ5AEpaYr7Rll1rvY7zqIhT6ty8E3ezBW2J1SFLjIDEvI/tcgDg6oaseDAqVcM+jU1HuCekgZw==} + '@oxc-parser/binding-win32-arm64-msvc@0.130.0': + resolution: {integrity: sha512-bjcma99sQrNh6RY4mPO9yTkfxql6TDFoN3HWdK31RCKXwNhcDgJXW/l8PUtzKNiQ+9vpKJfJtQq+LklBuxSOBA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-ia32-msvc@0.128.0': - resolution: {integrity: sha512-OY+3eM2SN72prHKRB22mPz8o5A/7dJ+f5DFLBVvggyZhEaNDAH9IB+ElMjmOkOIwf5MDCUAowCK7pAncNxzpBA==} + '@oxc-parser/binding-win32-ia32-msvc@0.130.0': + resolution: {integrity: sha512-hRYbv6HhpSTzT4xTiIkadLI7upLQxuOdLPR/9nL1fTjwhgutBTPXrwaAPb/jTFVx6/8C7Jb5HcUKhmNwloTbFA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.128.0': - resolution: {integrity: sha512-NE9ny+cPUCCObXa0IKLfj0tCdPd7pe/dz9ZpkxpUOymB3miNeMPybdlYYTBSGJUalMWeBM85/4JcCErCNTqOXw==} + '@oxc-parser/binding-win32-x64-msvc@0.130.0': + resolution: {integrity: sha512-RBpA9TsRucJq6HNVNCFF1iKg+QeTkLdZf7hi4xaOGCPvMZWvDHjQgSOEZMUpuW4JNciHbxNhLEYmz5CVygjVGQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@oxc-project/types@0.127.0': - resolution: {integrity: sha512-aIYXQBo4lCbO4z0R3FHeucQHpF46l2LbMdxRvqvuRuW2OxdnSkcng5B8+K12spgLDj93rtN3+J2Vac/TIO+ciQ==} + '@oxc-project/types@0.130.0': + resolution: {integrity: sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==} - '@oxc-project/types@0.128.0': - resolution: {integrity: sha512-huv1Y/LzBJkBVHt3OlC7u0zHBW9qXf1FdD7sGmc1rXc2P1mTwHssYv7jyGx5KAACSCH+9B3Bhn6Z9luHRvf7pQ==} + '@oxc-project/types@0.132.0': + resolution: {integrity: sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==} '@oxc-resolver/binding-android-arm-eabi@11.19.1': resolution: {integrity: sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg==} @@ -1553,6 +1546,12 @@ packages: resolution: {integrity: sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==} engines: {node: '>=12'} + '@posthog/core@1.29.7': + resolution: {integrity: sha512-WcBD9/YQVGI9r/5+/IGeaPgsmTIg0YfyzaTei5TNlhmAeFOccnhs269rhtQJcAXngZFpvWSj+RTxX2ONdgxBDQ==} + + '@posthog/types@1.374.4': + resolution: {integrity: sha512-OHBo+gReFwPJtt/yLY6xxa1EYMp7Ti07O1C1KE9ZXXyyuLNqekRaHZxJ/SKUfEvt1LhFV/9sioz8O0xfsSffsQ==} + '@radix-ui/number@1.1.1': resolution: {integrity: sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==} @@ -1918,103 +1917,103 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} - '@rolldown/binding-android-arm64@1.0.0-rc.17': - resolution: {integrity: sha512-s70pVGhw4zqGeFnXWvAzJDlvxhlRollagdCCKRgOsgUOH3N1l0LIxf83AtGzmb5SiVM4Hjl5HyarMRfdfj3DaQ==} + '@rolldown/binding-android-arm64@1.0.2': + resolution: {integrity: sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.0-rc.17': - resolution: {integrity: sha512-4ksWc9n0mhlZpZ9PMZgTGjeOPRu8MB1Z3Tz0Mo02eWfWCHMW1zN82Qz/pL/rC+yQa+8ZnutMF0JjJe7PjwasYw==} + '@rolldown/binding-darwin-arm64@1.0.2': + resolution: {integrity: sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.0-rc.17': - resolution: {integrity: sha512-SUSDOI6WwUVNcWxd02QEBjLdY1VPHvlEkw6T/8nYG322iYWCTxRb1vzk4E+mWWYehTp7ERibq54LSJGjmouOsw==} + '@rolldown/binding-darwin-x64@1.0.2': + resolution: {integrity: sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.0-rc.17': - resolution: {integrity: sha512-hwnz3nw9dbJ05EDO/PvcjaaewqqDy7Y1rn1UO81l8iIK1GjenME75dl16ajbvSSMfv66WXSRCYKIqfgq2KCfxw==} + '@rolldown/binding-freebsd-x64@1.0.2': + resolution: {integrity: sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': - resolution: {integrity: sha512-IS+W7epTcwANmFSQFrS1SivEXHtl1JtuQA9wlxrZTcNi6mx+FDOYrakGevvvTwgj2JvWiK8B29/qD9BELZPyXQ==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.2': + resolution: {integrity: sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': - resolution: {integrity: sha512-e6usGaHKW5BMNZOymS1UcEYGowQMWcgZ71Z17Sl/h2+ZziNJ1a9n3Zvcz6LdRyIW5572wBCTH/Z+bKuZouGk9Q==} + '@rolldown/binding-linux-arm64-gnu@1.0.2': + resolution: {integrity: sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': - resolution: {integrity: sha512-b/CgbwAJpmrRLp02RPfhbudf5tZnN9nsPWK82znefso832etkem8H7FSZwxrOI9djcdTP7U6YfNhbRnh7djErg==} + '@rolldown/binding-linux-arm64-musl@1.0.2': + resolution: {integrity: sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': - resolution: {integrity: sha512-4EII1iNGRUN5WwGbF/kOh/EIkoDN9HsupgLQoXfY+D1oyJm7/F4t5PYU5n8SWZgG0FEwakyM8pGgwcBYruGTlA==} + '@rolldown/binding-linux-ppc64-gnu@1.0.2': + resolution: {integrity: sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': - resolution: {integrity: sha512-AH8oq3XqQo4IibpVXvPeLDI5pzkpYn0WiZAfT05kFzoJ6tQNzwRdDYQ45M8I/gslbodRZwW8uxLhbSBbkv96rA==} + '@rolldown/binding-linux-s390x-gnu@1.0.2': + resolution: {integrity: sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': - resolution: {integrity: sha512-cLnjV3xfo7KslbU41Z7z8BH/E1y5mzUYzAqih1d1MDaIGZRCMqTijqLv76/P7fyHuvUcfGsIpqCdddbxLLK9rA==} + '@rolldown/binding-linux-x64-gnu@1.0.2': + resolution: {integrity: sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': - resolution: {integrity: sha512-0phclDw1spsL7dUB37sIARuis2tAgomCJXAHZlpt8PXZ4Ba0dRP1e+66lsRqrfhISeN9bEGNjQs+T/Fbd7oYGw==} + '@rolldown/binding-linux-x64-musl@1.0.2': + resolution: {integrity: sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': - resolution: {integrity: sha512-0ag/hEgXOwgw4t8QyQvUCxvEg+V0KBcA6YuOx9g0r02MprutRF5dyljgm3EmR02O292UX7UeS6HzWHAl6KgyhA==} + '@rolldown/binding-openharmony-arm64@1.0.2': + resolution: {integrity: sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': - resolution: {integrity: sha512-LEXei6vo0E5wTGwpkJ4KoT3OZJRnglwldt5ziLzOlc6qqb55z4tWNq2A+PFqCJuvWWdP53CVhG1Z9NtToDPJrA==} + '@rolldown/binding-wasm32-wasi@1.0.2': + resolution: {integrity: sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': - resolution: {integrity: sha512-gUmyzBl3SPMa6hrqFUth9sVfcLBlYsbMzBx5PlexMroZStgzGqlZ26pYG89rBb45Mnia+oil6YAIFeEWGWhoZA==} + '@rolldown/binding-win32-arm64-msvc@1.0.2': + resolution: {integrity: sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': - resolution: {integrity: sha512-3hkiolcUAvPB9FLb3UZdfjVVNWherN1f/skkGWJP/fgSQhYUZpSIRr0/I8ZK9TkF3F7kxvJAk0+IcKvPHk9qQg==} + '@rolldown/binding-win32-x64-msvc@1.0.2': + resolution: {integrity: sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@rolldown/pluginutils@1.0.0-rc.17': - resolution: {integrity: sha512-n8iosDOt6Ig1UhJ2AYqoIhHWh/isz0xpicHTzpKBeotdVsTEcxsSA/i3EVM7gQAj0rU27OLAxCjzlj15IWY7bg==} + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} @@ -2063,32 +2062,32 @@ packages: peerDependencies: semantic-release: '>=20.1.0' - '@shikijs/core@4.0.2': - resolution: {integrity: sha512-hxT0YF4ExEqB8G/qFdtJvpmHXBYJ2lWW7qTHDarVkIudPFE6iCIrqdgWxGn5s+ppkGXI0aEGlibI0PAyzP3zlw==} + '@shikijs/core@4.1.0': + resolution: {integrity: sha512-jLJtSJeuFffqX6/inRE1zqU5aFv2hrszvYgq3OjbAgFRZiWv7abKMDdQzYxuSDfmUPQozZvI/kuy6VMTvnvqTQ==} engines: {node: '>=20'} - '@shikijs/engine-javascript@4.0.2': - resolution: {integrity: sha512-7PW0Nm49DcoUIQEXlJhNNBHyoGMjalRETTCcjMqEaMoJRLljy1Bi/EGV3/qLBgLKQejdspiiYuHGQW6dX94Nag==} + '@shikijs/engine-javascript@4.1.0': + resolution: {integrity: sha512-YquhawCUgaBfhsS72e2Y/dI59gCBNPHu3fEO/tvLaXrTssxZrY5ddjtNLTwndrMgPo8b3IscE+xoICDzpTmlFQ==} engines: {node: '>=20'} - '@shikijs/engine-oniguruma@4.0.2': - resolution: {integrity: sha512-UpCB9Y2sUKlS9z8juFSKz7ZtysmeXCgnRF0dlhXBkmQnek7lAToPte8DkxmEYGNTMii72zU/lyXiCB6StuZeJg==} + '@shikijs/engine-oniguruma@4.1.0': + resolution: {integrity: sha512-axLpjVs45YBvvINa+dJF+NPW+KtFkNXsFr4SDw2BMj9GdeMnGxVB9PQb2xXlJYovslt/nz6giedAyOANkfc7hg==} engines: {node: '>=20'} - '@shikijs/langs@4.0.2': - resolution: {integrity: sha512-KaXby5dvoeuZzN0rYQiPMjFoUrz4hgwIE+D6Du9owcHcl6/g16/yT5BQxSW5cGt2MZBz6Hl0YuRqf12omRfUUg==} + '@shikijs/langs@4.1.0': + resolution: {integrity: sha512-nwOMruEkbgdZfQ/b8CgpNBVOpvG1k0N5tbmgiFeqsan401+x3ILqlzZJowSla4Agmq4hG2Uf2wh5jLTEhR8VSg==} engines: {node: '>=20'} - '@shikijs/primitive@4.0.2': - resolution: {integrity: sha512-M6UMPrSa3fN5ayeJwFVl9qWofl273wtK1VG8ySDZ1mQBfhCpdd8nEx7nPZ/tk7k+TYcpqBZzj/AnwxT9lO+HJw==} + '@shikijs/primitive@4.1.0': + resolution: {integrity: sha512-zx2/2Uwj2q9X3KSyYREEhXO23xBw5WUhP4orK2lE4r+t9JGITmEe0JH+wPmJhqHpOT2bRRs6lAL945+LDvOAGw==} engines: {node: '>=20'} - '@shikijs/themes@4.0.2': - resolution: {integrity: sha512-mjCafwt8lJJaVSsQvNVrJumbnnj1RI8jbUKrPKgE6E3OvQKxnuRoBaYC51H4IGHePsGN/QtALglWBU7DoKDFnA==} + '@shikijs/themes@4.1.0': + resolution: {integrity: sha512-emCcTnUM7yO2wltYbaxm+yLvcCI4+h8XBKc4KmJ7EZUXoSGjcCHifkI//R4OFit9ewpg7H2/9tjOuXrT2v/Knw==} engines: {node: '>=20'} - '@shikijs/types@4.0.2': - resolution: {integrity: sha512-qzbeRooUTPnLE+sHD/Z8DStmaDgnbbc/pMrU203950aRqjX/6AFHeDYT+j00y2lPdz0ywJKx7o/7qnqTivtlXg==} + '@shikijs/types@4.1.0': + resolution: {integrity: sha512-3EQWX54fMpniOrDblzAhiwiJwpiTMW6+B9DWyUd9ska483tbayFYuw47UxwuPknI31bKnySfVQ/QW+jFL4rFdA==} engines: {node: '>=20'} '@shikijs/vscode-textmate@10.0.2': @@ -2112,222 +2111,164 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@smithy/chunked-blob-reader-native@4.2.3': - resolution: {integrity: sha512-jA5k5Udn7Y5717L86h4EIv06wIr3xn8GM1qHRi/Nf31annXcXHJjBKvgztnbn2TxH3xWrPBfgwHsOwZf0UmQWw==} + '@smithy/config-resolver@4.5.3': + resolution: {integrity: sha512-TpS6Am5zSEtx3ow7VynThEL7UwRM06zZZcmFaP6Ij9hqKPfsFhTYCLcgU7gjFjw9QAI2kzwXrfS7InH8BivJTA==} engines: {node: '>=18.0.0'} - '@smithy/chunked-blob-reader@5.2.2': - resolution: {integrity: sha512-St+kVicSyayWQca+I1rGitaOEH6uKgE8IUWoYnnEX26SWdWQcL6LvMSD19Lg+vYHKdT9B2Zuu7rd3i6Wnyb/iw==} + '@smithy/core@3.24.3': + resolution: {integrity: sha512-Ep/7tPamGY8mgESE3LyLKtxJyy6U52WWAqr/3wial47Sj4u3PiIF73AOGI27UyLy9duTkhZbgzodOfLV4TduZg==} engines: {node: '>=18.0.0'} - '@smithy/config-resolver@4.4.17': - resolution: {integrity: sha512-TzDZcAnhTyAHbXVxWZo7/tEcrIeFq20IBk8So3OLOetWpR8EwY/yEqBMBFaJMeyEiREDq4NfEl+qO3OAUD+vbQ==} + '@smithy/credential-provider-imds@4.3.3': + resolution: {integrity: sha512-I2Bti0DKFo2IJyN28ijCsx51BAumEYR4/1yZ1FXyBygy9MqbnMqCev4JPth/MbpRfBSRAX35hITSnAdJRo1u5w==} engines: {node: '>=18.0.0'} - '@smithy/core@3.23.17': - resolution: {integrity: sha512-x7BlLbUFL8NWCGjMF9C+1N5cVCxcPa7g6Tv9B4A2luWx3be3oU8hQ96wIwxe/s7OhIzvoJH73HAUSg5JXVlEtQ==} + '@smithy/eventstream-serde-browser@4.3.3': + resolution: {integrity: sha512-LXg5yYJPYnVSrpa6LOZ+/wqpI2OlIccy7j5F16EFNYDbXWmnhry/PFRRPyM30H+hJeqfVgckFuvNGnAGCt56cA==} engines: {node: '>=18.0.0'} - '@smithy/credential-provider-imds@4.2.14': - resolution: {integrity: sha512-Au28zBN48ZAoXdooGUHemuVBrkE+Ie6RPmGNIAJsFqj33Vhb6xAgRifUydZ2aY+M+KaMAETAlKk5NC5h1G7wpg==} + '@smithy/eventstream-serde-config-resolver@4.4.3': + resolution: {integrity: sha512-MdQxEX5SFNc3QmpiLXtcZXsWk4imCfGVN7Ikz9I/XvavypvHT4mqxwo5JHdr/LBKCfAv89+8193ZWlUwDp8YXQ==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-codec@4.2.14': - resolution: {integrity: sha512-erZq0nOIpzfeZdCyzZjdJb4nVSKLUmSkaQUVkRGQTXs30gyUGeKnrYEg+Xe1W5gE3aReS7IgsvANwVPxSzY6Pw==} + '@smithy/eventstream-serde-node@4.3.3': + resolution: {integrity: sha512-54RbRsw9eVaVnqYUXi3F6nMAPgUyKsBvAKBY2lf+81mIgM7N+yS9V5LYk7yUGbrM789b2e1qBuyDSjX1/Axxcw==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-browser@4.2.14': - resolution: {integrity: sha512-8IelTCtTctWRbb+0Dcy+C0aICh1qa0qWXqgjcXDmMuCvPJRnv26hiDZoAau2ILOniki65mCPKqOQs/BaWvO4CQ==} + '@smithy/fetch-http-handler@5.4.3': + resolution: {integrity: sha512-F+DRf8IJazRJgYog2A/yJK7eYVc0rqTlRzO+5ZxjJd4WkZoKz0IJRncf7G6t1pdVT3kryJcwuTFhN1c5m6N47A==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-config-resolver@4.3.14': - resolution: {integrity: sha512-sqHiHpYRYo3FJlaIxD1J8PhbcmJAm7IuM16mVnwSkCToD7g00IBZzKuiLNMGmftULmEUX6/UAz8/NN5uMP8bVA==} + '@smithy/hash-blob-browser@4.3.3': + resolution: {integrity: sha512-TkGfDlYeWOGwYvAunHHHmKgvFtD7DFAl6gWxATI4pv4B6w0Wnx6RK5zCMoXTTqMVd+zPcWm7w8RPTgHytoCDJA==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-node@4.2.14': - resolution: {integrity: sha512-Ht/8BuGlKfFTy0H3+8eEu0vdpwGztCnaLLXtpXNdQqiR7Hj4vFScU3T436vRAjATglOIPjJXronY+1WxxNLSiw==} + '@smithy/hash-node@4.3.3': + resolution: {integrity: sha512-tSUA38sM7kzMoLhqQ2aCGTwLXovjurz3jjG+a0sxqD4qT/4FhQr/wxMdhCumT70giM+axC1pPjimAHLlEQCfzw==} engines: {node: '>=18.0.0'} - '@smithy/eventstream-serde-universal@4.2.14': - resolution: {integrity: sha512-lWyt4T2XQZUZgK3tQ3Wn0w3XBvZsK/vjTuJl6bXbnGZBHH0ZUSONTYiK9TgjTTzU54xQr3DRFwpjmhp0oLm3gg==} + '@smithy/hash-stream-node@4.3.3': + resolution: {integrity: sha512-ZyDAlpKKc7BKHUp+kDBiTwNhiHrOf3syQdvQadvnwWs0QJhYMHMg6QSarlhpzN6qr+KBFM/oF/xP/bvzR6KI9w==} engines: {node: '>=18.0.0'} - '@smithy/fetch-http-handler@5.3.17': - resolution: {integrity: sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw==} - engines: {node: '>=18.0.0'} - - '@smithy/hash-blob-browser@4.2.15': - resolution: {integrity: sha512-0PJ4Al3fg2nM4qKrAIxyNcApgqHAXcBkN8FeizOz69z0rb26uZ6lMESYtxegaTlXB5Hj84JfwMPavMrwDMjucA==} - engines: {node: '>=18.0.0'} - - '@smithy/hash-node@4.2.14': - resolution: {integrity: sha512-8ZBDY2DD4wr+GGjTpPtiglEsqr0lUP+KHqgZcWczFf6qeZ/YRjMIOoQWVQlmwu7EtxKTd8YXD8lblmYcpBIA1g==} - engines: {node: '>=18.0.0'} - - '@smithy/hash-stream-node@4.2.14': - resolution: {integrity: sha512-tw4GANWkZPb6+BdD4Fgucqzey2+r73Z/GRo9zklsCdwrnxxumUV83ZIaBDdudV4Ylazw3EPTiJZhpX42105ruQ==} - engines: {node: '>=18.0.0'} - - '@smithy/invalid-dependency@4.2.14': - resolution: {integrity: sha512-c21qJiTSb25xvvOp+H2TNZzPCngrvl5vIPqPB8zQ/DmJF4QWXO19x1dWfMJZ6wZuuWUPPm0gV8C0cU3+ifcWuw==} + '@smithy/invalid-dependency@4.3.3': + resolution: {integrity: sha512-wUWowbCm7DGczl6bfLI6wGGtoxwN5Pon8DhF0Q8AA4NvgLwYfLo3h2DWI7sHr33lLcEsyTLQKeUeTHydqSfQ5Q==} engines: {node: '>=18.0.0'} '@smithy/is-array-buffer@2.2.0': resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} engines: {node: '>=14.0.0'} - '@smithy/is-array-buffer@4.2.2': - resolution: {integrity: sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==} + '@smithy/md5-js@4.3.3': + resolution: {integrity: sha512-pFw8gEMrHw9BbRwNm//UU4WgnVO7+dhfFRaSAkFPfwslWU2LXt0mM+oap3iFwGbdD8kuAWIeOAxqSiamOcM3Dw==} engines: {node: '>=18.0.0'} - '@smithy/md5-js@4.2.14': - resolution: {integrity: sha512-V2v0vx+h0iUSNG1Alt+GNBMSLGCrl9iVsdd+Ap67HPM9PN479x12V8LkuMoKImNZxn3MXeuyUjls+/7ZACZghA==} + '@smithy/middleware-content-length@4.3.3': + resolution: {integrity: sha512-Up1XAYnj6oxFBypWpkhNpgX+yReQxkKAV/iLaeP0KVLb2oTkmA9X+UJuGBVvEA9uZIN06y0irDi7sBMuTZMVJg==} engines: {node: '>=18.0.0'} - '@smithy/middleware-content-length@4.2.14': - resolution: {integrity: sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw==} + '@smithy/middleware-endpoint@4.5.3': + resolution: {integrity: sha512-p60HGFflWsJC6V9GAYeFgbfORn+9ILx8FqgMa/8PzA0rhIUxF57EKoOR4Irs6oe1oy8RLzhjhcGS8CBtPv/t+Q==} engines: {node: '>=18.0.0'} - '@smithy/middleware-endpoint@4.4.32': - resolution: {integrity: sha512-ZZkgyjnJppiZbIm6Qbx92pbXYi1uzenIvGhBSCDlc7NwuAkiqSgS75j1czAD25ZLs2FjMjYy1q7gyRVWG6JA0Q==} + '@smithy/middleware-retry@4.6.3': + resolution: {integrity: sha512-MnfYnJs3cBXK3ZBqbPzXRPHIp+QtgpkX5NogcUOWHPU5GbgTAQSIfPLi91lTcEbkFDcH2YbgjLPQjWeyQ689rA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-retry@4.5.7': - resolution: {integrity: sha512-bRt6ZImqVSeTk39Nm81K20ObIiAZ3WefY7G6+iz/0tZjs4dgRRjvRX2sgsH+zi6iDCRR/aQvQofLKxxz4rPBZg==} + '@smithy/middleware-serde@4.3.3': + resolution: {integrity: sha512-RUVCZgn92izDAARs5OJSM2+KWSfTRvQWwN9t0MmiybT3pquRgDx9vD9t/YZjd/5lwcFbsNuPojJSddYQEZGeWw==} engines: {node: '>=18.0.0'} - '@smithy/middleware-serde@4.2.20': - resolution: {integrity: sha512-Lx9JMO9vArPtiChE3wbEZ5akMIDQpWQtlu90lhACQmNOXcGXRbaDywMHDzuDZ2OkZzP+9wQfZi3YJT9F67zTQQ==} + '@smithy/middleware-stack@4.3.3': + resolution: {integrity: sha512-+BPabWluqxo3EfMMvOgnAmPtWnCSzj+gf5mJ27wTZUbvS0hpdUIU1g80R01bEGKZx4JCi8P58jAXD9FUGMjhwA==} engines: {node: '>=18.0.0'} - '@smithy/middleware-stack@4.2.14': - resolution: {integrity: sha512-2dvkUKLuFdKsCRmOE4Mn63co0Djtsm+JMh0bYZQupN1pJwMeE8FmQmRLLzzEMN0dnNi7CDCYYH8F0EVwWiPBeA==} + '@smithy/node-config-provider@4.4.3': + resolution: {integrity: sha512-vDtz5OuytrjP4o9GtAOz1JloN003p94utJIQeO0WAjorhpafFFjpbDOrP6btPoCN3UxaU/U84OIEt5dM7ZRRLA==} engines: {node: '>=18.0.0'} - '@smithy/node-config-provider@4.3.14': - resolution: {integrity: sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg==} + '@smithy/node-http-handler@4.7.3': + resolution: {integrity: sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==} engines: {node: '>=18.0.0'} - '@smithy/node-http-handler@4.6.1': - resolution: {integrity: sha512-iB+orM4x3xrr57X3YaXazfKnntl0LHlZB1kcXSGzMV1Tt0+YwEjGlbjk/44qEGtBzXAz6yFDzkYTKSV6Pj2HUg==} + '@smithy/protocol-http@5.4.3': + resolution: {integrity: sha512-P16TBD/d8ZcD9MHQ0ubQ9BbOYSd5HZKbHOLsyFWxKk2oBEoghbRFPfGOoqToZX1yrfLITXRylL16EyPP4IzLPg==} engines: {node: '>=18.0.0'} - '@smithy/property-provider@4.2.14': - resolution: {integrity: sha512-WuM31CgfsnQ/10i7NYr0PyxqknD72Y5uMfUMVSniPjbEPceiTErb4eIqJQ+pdxNEAUEWrewrGjIRjVbVHsxZiQ==} + '@smithy/signature-v4@5.4.3': + resolution: {integrity: sha512-53+75QuPl6DL+ct6vVEB51FDO5oulXr20TPV46VvJZg76lIlXNWfxi8j+G2V/t0I2qxCBOa3vX/8bmjrpFVo9g==} engines: {node: '>=18.0.0'} - '@smithy/protocol-http@5.3.14': - resolution: {integrity: sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ==} + '@smithy/smithy-client@4.13.3': + resolution: {integrity: sha512-Z8mQ+YryjP5krDadV6unnp5035L4S1brafXpTiRmjPweKSaQ6X9CYDYWvmEggXjDIa1oufX/2a/bdwu8EIz/lw==} engines: {node: '>=18.0.0'} - '@smithy/querystring-builder@4.2.14': - resolution: {integrity: sha512-XYA5Z0IqTeF+5XDdh4BBmSA0HvbgVZIyv4cmOoUheDNR57K1HgBp9ukUMx3Cr3XpDHHpLBnexPE3LAtDsZkj2A==} + '@smithy/types@4.14.2': + resolution: {integrity: sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==} engines: {node: '>=18.0.0'} - '@smithy/querystring-parser@4.2.14': - resolution: {integrity: sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw==} + '@smithy/url-parser@4.3.3': + resolution: {integrity: sha512-TsMTAOnjuMOv1zJBw8cfYGWhopyc3og8tZX/KuyCPjg7V3ji3f4YjFOVu843UjBmrfS/+X6kwFv5ZKg7sSm1bQ==} engines: {node: '>=18.0.0'} - '@smithy/service-error-classification@4.3.1': - resolution: {integrity: sha512-aUQuDGh760ts/8MU+APjIZhlLPKhIIfqyzZaJikLEIMrdxFvxuLYD0WxWzaYWpmLbQlXDe9p7EWM3HsBe0K6Gw==} + '@smithy/util-base64@4.4.3': + resolution: {integrity: sha512-91lxjhFpAktA9yPBxniqVR/NSH9zyjMjLmoa+jbQHQFR9WiJA+n61T7HBrfh5APdEoAledJwGq8l4cS+ZJFUnQ==} engines: {node: '>=18.0.0'} - '@smithy/shared-ini-file-loader@4.4.9': - resolution: {integrity: sha512-495/V2I15SHgedSJoDPD23JuSfKAp726ZI1V0wtjB07Wh7q/0tri/0e0DLefZCHgxZonrGKt/OCTpAtP1wE1kQ==} + '@smithy/util-body-length-browser@4.3.3': + resolution: {integrity: sha512-/M6Ya1Fjq8hg3rYjiwwqTen6s1bAa3U3g/2eicBaBQfaoa4ymLUke/x4T8mwb9dSq/L8TQ4YgndS0MaB9ShgmA==} engines: {node: '>=18.0.0'} - '@smithy/signature-v4@5.3.14': - resolution: {integrity: sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==} - engines: {node: '>=18.0.0'} - - '@smithy/smithy-client@4.12.13': - resolution: {integrity: sha512-y/Pcj1V9+qG98gyu1gvftHB7rDpdh+7kIBIggs55yGm3JdtBV8GT8IFF3a1qxZ79QnaJHX9GXzvBG6tAd+czJA==} - engines: {node: '>=18.0.0'} - - '@smithy/types@4.14.1': - resolution: {integrity: sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg==} - engines: {node: '>=18.0.0'} - - '@smithy/url-parser@4.2.14': - resolution: {integrity: sha512-p06BiBigJ8bTA3MgnOfCtDUWnAMY0YfedO/GRpmc7p+wg3KW8vbXy1xwSu5ASy0wV7rRYtlfZOIKH4XqfhjSQQ==} - engines: {node: '>=18.0.0'} - - '@smithy/util-base64@4.3.2': - resolution: {integrity: sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==} - engines: {node: '>=18.0.0'} - - '@smithy/util-body-length-browser@4.2.2': - resolution: {integrity: sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==} - engines: {node: '>=18.0.0'} - - '@smithy/util-body-length-node@4.2.3': - resolution: {integrity: sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==} + '@smithy/util-body-length-node@4.3.3': + resolution: {integrity: sha512-M+zdSrevWj0grtZx2RBULPUyjTq1aB+n+13Hrm9owiGpow6DqY/WqiSj6sHVQy/rKp0j7NzV3TNf2LrwDel8JQ==} engines: {node: '>=18.0.0'} '@smithy/util-buffer-from@2.2.0': resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} engines: {node: '>=14.0.0'} - '@smithy/util-buffer-from@4.2.2': - resolution: {integrity: sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==} + '@smithy/util-defaults-mode-browser@4.4.3': + resolution: {integrity: sha512-Q60hxKkMEkmBsOEzxlMWEymBWov0dtWGgoJhOUs6mE8k2FDPjK8NlsRdMkmO80n2pwzreHtrYcX5jiRP7ZkP3w==} engines: {node: '>=18.0.0'} - '@smithy/util-config-provider@4.2.2': - resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} + '@smithy/util-defaults-mode-node@4.3.3': + resolution: {integrity: sha512-RYj+8gr95WiiBqvVghoRvL12NS9ryvLyufp7FOs7EzKwGX0W5gOVlXdCrFkJScSf8gxdjQMRyIZ3Y82/MvXQ3Q==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-browser@4.3.49': - resolution: {integrity: sha512-a5bNrdiONYB/qE2BuKegvUMd/+ZDwdg4vsNuuSzYE8qs2EYAdK9CynL+Rzn29PbPiUqoz/cbpRbcLzD5lEevHw==} + '@smithy/util-endpoints@3.5.3': + resolution: {integrity: sha512-2JqSmzQtKDKqBckLl/9NXTL1fY+zQBU5fNGMpud7AT65vql0tVFhb2UEZNZmLSHayLeD+X/Qzn84oXw5KS+KSQ==} engines: {node: '>=18.0.0'} - '@smithy/util-defaults-mode-node@4.2.54': - resolution: {integrity: sha512-g1cvrJvOnzeJgEdf7AE4luI7gp6L8weE0y9a9wQUSGtjb8QRHDbCJYuE4Sy0SD9N8RrnNPFsPltAz/OSoBR9Zw==} + '@smithy/util-middleware@4.3.3': + resolution: {integrity: sha512-8NZwlQ+nyAIWn9YZxH14FC8ca0i6ZGW1aJyPjD+zMZz3k9jOhXXKhdCSRvjmcSYLW42uhbrxavXqMkrTKHyY3A==} engines: {node: '>=18.0.0'} - '@smithy/util-endpoints@3.4.2': - resolution: {integrity: sha512-a55Tr+3OKld4TTtnT+RhKOQHyPxm3j/xL4OR83WBUhLJaKDS9dnJ7arRMOp3t31dcLhApwG9bgvrRXBHlLdIkg==} + '@smithy/util-retry@4.4.3': + resolution: {integrity: sha512-8RJXeU5lEhdNfXm4XAuHlf6VtNzd279Z2FJZSR7VaELYCR46ffgjJBSjc+3UAy7V1YqBOLV0G9gWhLB/nA44nA==} engines: {node: '>=18.0.0'} - '@smithy/util-hex-encoding@4.2.2': - resolution: {integrity: sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==} - engines: {node: '>=18.0.0'} - - '@smithy/util-middleware@4.2.14': - resolution: {integrity: sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==} - engines: {node: '>=18.0.0'} - - '@smithy/util-retry@4.3.6': - resolution: {integrity: sha512-p6/FO1n2KxMeQyna067i0uJ6TSbb165ZhnRtCpWh4Foxqbfc6oW+XITaL8QkFJj3KFnDe2URt4gOhgU06EP9ew==} - engines: {node: '>=18.0.0'} - deprecated: '@smithy/util-retry v4.3.6 contains a bug in Adaptive Retry, see https://github.com/smithy-lang/smithy-typescript/issues/1993. Upgrade to 4.3.7+' - - '@smithy/util-stream@4.5.25': - resolution: {integrity: sha512-/PFpG4k8Ze8Ei+mMKj3oiPICYekthuzePZMgZbCqMiXIHHf4n2aZ4Ps0aSRShycFTGuj/J6XldmC0x0DwednIA==} - engines: {node: '>=18.0.0'} - - '@smithy/util-uri-escape@4.2.2': - resolution: {integrity: sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==} + '@smithy/util-stream@4.6.3': + resolution: {integrity: sha512-DSpJpPg0rQwjZk9/CSlOTplD6xSUu+bz8eDJQkq/Fmy9JlSD4ZGhXG/qFl0aRHmouDbBF75tnZ00lPxiL/sgRQ==} engines: {node: '>=18.0.0'} '@smithy/util-utf8@2.3.0': resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} engines: {node: '>=14.0.0'} - '@smithy/util-utf8@4.2.2': - resolution: {integrity: sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==} + '@smithy/util-utf8@4.3.3': + resolution: {integrity: sha512-c1QpRBn3aMsoqE64dd4Imgjy8Pynfw+eR7GkjElquxUFSnezwYVaOFm8JcYa+Bo/5ssbEyPKcT3+4bmrWYh6eQ==} engines: {node: '>=18.0.0'} - '@smithy/util-waiter@4.3.0': - resolution: {integrity: sha512-JyjYmLAfS+pdxF92o4yLgEoy0zhayKTw73FU1aofLWwLcJw7iSqIY2exGmMTrl/lmZugP5p/zxdFSippJDfKWA==} - engines: {node: '>=18.0.0'} - - '@smithy/uuid@1.1.2': - resolution: {integrity: sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==} + '@smithy/util-waiter@4.4.3': + resolution: {integrity: sha512-WSHSF865zDGFGtJdMmYPI2Blq/MbUrn5CB4bLDg4ARbQ9z7oA87ZZ/FSiwNZbQrU/EiVyl9lpINswALgI4lZXA==} engines: {node: '>=18.0.0'} '@so-ric/colorspace@1.1.6': resolution: {integrity: sha512-/KiKkpHNOBgkFJwu9sh48LkHSMYGyuTcSFK/qMBdnOAlrRJzRSXAOFB5qwzaVQuDl8wAvHVMkaASQDReTahxuw==} + '@stablelib/base64@1.0.1': + resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} + '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -2432,8 +2373,8 @@ packages: '@tediousjs/connection-string@1.1.0': resolution: {integrity: sha512-z9ZBWEG+8pIB5V1zYzlRPXx0oRJ5H7coPnMQK8EZOw03UTPI9Umn6viL36f5w+CuqkKsnCM50RVStpjZmR0Bng==} - '@tybys/wasm-util@0.10.1': - resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} '@types/better-sqlite3@7.6.13': resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} @@ -2468,8 +2409,8 @@ packages: '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} @@ -2486,8 +2427,8 @@ packages: '@types/mssql@12.3.0': resolution: {integrity: sha512-+jy+AJtfuTDI5+nhh0hDNcir1p8P+pf+qsHXpUpYvg7EikxUUePBe+a+Kr6j/Xs89o4EbHlVzrh0HOxbqWM31Q==} - '@types/node@24.12.2': - resolution: {integrity: sha512-A1sre26ke7HDIuY/M23nd9gfB+nrmhtYyMINbjI1zHJxYteKR6qSMX56FsmjMcDb3SMcjJg5BiRRgOCC/yBD0g==} + '@types/node@24.12.4': + resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} '@types/normalize-package-data@2.4.4': resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} @@ -2500,8 +2441,8 @@ packages: peerDependencies: '@types/react': ^19.2.0 - '@types/react@19.2.14': - resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + '@types/react@19.2.15': + resolution: {integrity: sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==} '@types/readable-stream@4.0.23': resolution: {integrity: sha512-wwXrtQvbMHxCbBgjHaMGEmImFTQxxpfMOR/ZoQnXxB1woqkUbdLGFDgauo00Py9IudiaqSeiBiulSV9i6XIPig==} @@ -2526,20 +2467,20 @@ packages: resolution: {integrity: sha512-UycprH3T6n3jH0k44NHMa7pnFHGu/N05MjojYr+Mc6I7obkoLIJujSWwin1pCvdy/eOxrI/l3uDLQsmcrOb4ug==} engines: {node: '>= 20'} - '@vitest/coverage-v8@4.1.6': - resolution: {integrity: sha512-36l628fQ/9a/8ihy97eOtEnvWQEdqULQOJtcaxtoNq0G1w3Mxd4szSahOaMM9/NGyZ+hyKcMtIW/WIxq0XQViQ==} + '@vitest/coverage-v8@4.1.7': + resolution: {integrity: sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ==} peerDependencies: - '@vitest/browser': 4.1.6 - vitest: 4.1.6 + '@vitest/browser': 4.1.7 + vitest: 4.1.7 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.6': - resolution: {integrity: sha512-7EHDquPthALSV0jhhjgEW8FXaviMx7rSqu8W6oqCoAuOhKov814P99QDV1pxMA3QPv21YudvJngIhjrNI4opLg==} + '@vitest/expect@4.1.7': + resolution: {integrity: sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==} - '@vitest/mocker@4.1.6': - resolution: {integrity: sha512-MCFc63czMjEInOlcY2cpQCvCN+KgbAn+60xu9cMgP4sKaLC5JNAKw7JH8QdAnoAC88hW1IiSNZ+GgVXlN1UcMQ==} + '@vitest/mocker@4.1.7': + resolution: {integrity: sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -2549,20 +2490,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.6': - resolution: {integrity: sha512-h5SxD/IzNhZYnrSZRsUZQIC+vD0GY8cUvq0iwsmkFKixRCKLLWqCXa/FIQ4S1R+sI+PGoojkHsdNrbZiM9Qpgw==} + '@vitest/pretty-format@4.1.7': + resolution: {integrity: sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==} - '@vitest/runner@4.1.6': - resolution: {integrity: sha512-nOPCmn2+yD0ZNmKdsXGv/UxMMWbMuKeD6GyYncNwdkYDxpQvrPSKYj2rWuDjC2Y4b6w6hjip5dBKFzEUuZe3vA==} + '@vitest/runner@4.1.7': + resolution: {integrity: sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==} - '@vitest/snapshot@4.1.6': - resolution: {integrity: sha512-YhsdE6xAVfTDmzjxL2ZDUvjj+ZsgyOKe+TdQzqkD72wIOmHka8NuGQ6NpTNZv9D2Z63fbwWKJPeVpEw4EQgYxw==} + '@vitest/snapshot@4.1.7': + resolution: {integrity: sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==} - '@vitest/spy@4.1.6': - resolution: {integrity: sha512-JFKxMx6udhwKh/Ldo270e17QX710vgunMkuPAvXjHSvC6oqLWAHhVhjg/I71q0u0CBSErIODV1Kjv0FQNSWjdg==} + '@vitest/spy@4.1.7': + resolution: {integrity: sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==} - '@vitest/utils@4.1.6': - resolution: {integrity: sha512-FxIY+U81R3LGKCxaHHFRQ5+g6/iRgGLmeHWdp2Amj4ljQRrEIWHmZyDfDYBRZlpyqA7qKxtS9DD1dhk8RnRIVQ==} + '@vitest/utils@4.1.7': + resolution: {integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==} '@xyflow/react@12.10.2': resolution: {integrity: sha512-CgIi6HwlcHXwlkTpr0fxLv/0sRVNZ8IdwKLzzeCscaYBwpvfcH1QFOCeaTCuEn1FQEs/B8CjnTSjhs8udgmBgQ==} @@ -2591,6 +2532,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + agent-base@7.1.4: resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} engines: {node: '>= 14'} @@ -2607,8 +2552,8 @@ packages: resolution: {integrity: sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==} engines: {node: '>=18'} - ai@6.0.180: - resolution: {integrity: sha512-tOyRbwD0PEjMZKGvYQcTsv95K2zktwwNhQ49QOUAh0g8MNprO7ELIO1SgANMuPc0BFtkP6Ny6OAdjq3TtxLCbQ==} + ai@6.0.188: + resolution: {integrity: sha512-kNwIl1MM4ESzeOPDYuN+FidJ2QY5kGWHLtTMru6HHPW/JJ6nPuvHRhJ8tMX/Y2Tijx9DCiv2W7y5IBouuB712g==} engines: {node: '>=18'} peerDependencies: zod: ^3.25.76 || ^4.1.8 @@ -2708,8 +2653,8 @@ packages: resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} engines: {node: '>= 6.0.0'} - axios@1.15.2: - resolution: {integrity: sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==} + axios@1.16.1: + resolution: {integrity: sha512-caYkukvroVPO8KrzuJEb50Hm07KwfBZPEC3VeFHTsqWHvKTsy54hjJz9BS/cdaypROE2rH6xvm9mHX4fgWkr3A==} bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -2724,8 +2669,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.10.29: - resolution: {integrity: sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==} + baseline-browser-mapping@2.10.31: + resolution: {integrity: sha512-MujYO3eP72uvmSE0i4wltsodRfIpZATP3jvzRNRGGxgzId7aVocVJJV3nf01qnzzKFGxQVC9bpWxl5cjxTr/7Q==} engines: {node: '>=6.0.0'} hasBin: true @@ -2811,8 +2756,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001792: - resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==} + caniuse-lite@1.0.30001793: + resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -3191,8 +3136,8 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.21.2: - resolution: {integrity: sha512-xe9vQb5kReirPUxgQrXA3ihgbCqssmTiM7cOZ+Gzu+VeGWgpV98lLZvp0dl4yriyAePcewxGUs9UpKD8PET9KQ==} + enhanced-resolve@5.21.6: + resolution: {integrity: sha512-aNnGCvbJ/RIyWo1IuhNdVjnNF+EjH9wpzpNHt+ci/m9He9LJvUN8wrCcXjp9cWsGNAuvSpVFTx/vraAFQ8qGjQ==} engines: {node: '>=10.13.0'} entities@6.0.1: @@ -3334,8 +3279,8 @@ packages: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} - express-rate-limit@8.4.1: - resolution: {integrity: sha512-NGVYwQSAyEQgzxX1iCM978PP9AdO/hW93gMcF6ZwQCm+rFvLsBH6w4xcXWTcliS8La5EPRN3p9wzItqBwJrfNw==} + express-rate-limit@8.5.2: + resolution: {integrity: sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==} engines: {node: '>= 16'} peerDependencies: express: '>= 4.11' @@ -3353,6 +3298,9 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-sha256@1.3.0: + resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} + fast-string-truncated-width@3.0.3: resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} @@ -3362,14 +3310,18 @@ packages: fast-uri@3.1.2: resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} - fast-wrap-ansi@0.2.0: - resolution: {integrity: sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==} + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} fast-xml-builder@1.1.7: resolution: {integrity: sha512-Yh7/7rQuMXICNr0oMYDR2yHP6oUvmQsTToFeOWj/kIDhAwQ+c4Ol/lbcwOmEM5OHYQmh6S6EQSQ1sljCKP36bQ==} - fast-xml-parser@5.7.2: - resolution: {integrity: sha512-P7oW7tLbYnhOLQk/Gv7cZgzgMPP/XN03K02/Jy6Y/NHzyIAIpxuZIM/YqAkfiXFPxA2CTm7NtCijK9EDu09u2w==} + fast-xml-parser@5.7.3: + resolution: {integrity: sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==} + hasBin: true + + fast-xml-parser@5.8.0: + resolution: {integrity: sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==} hasBin: true fastest-levenshtein@1.0.16: @@ -3395,8 +3347,8 @@ packages: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} - fflate@0.8.2: - resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + fflate@0.8.3: + resolution: {integrity: sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==} figures@2.0.0: resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} @@ -3458,8 +3410,8 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} - framer-motion@12.38.0: - resolution: {integrity: sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==} + framer-motion@12.40.0: + resolution: {integrity: sha512-uaBd3qC1v3KQqBEjwTUd183K6PbS+j0yR9w9VmEOLWA/tnUcSn8Xa3uck7t4dgpDoUss8xQTcj8W2L07lrnLFg==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -3550,8 +3502,8 @@ packages: zod: optional: true - fumadocs-mdx@15.0.4: - resolution: {integrity: sha512-swJ7VB9x8fPjVAcH4xMg7qplgm7m6Hy3woB5s/yssBWVPkvET7wGOHoYZ05iW9TDIWruk5vyqwEDrwq3t4PZUw==} + fumadocs-mdx@15.0.7: + resolution: {integrity: sha512-3ffG5th20eL3CvEH9YSYfmn0MPeaJkdnu1MMXNsR1zduhn6tW5ieQ8YX+EC4+BfnpwcB3y2wwAlGM0PWl/YPNg==} hasBin: true peerDependencies: '@types/mdast': '*' @@ -3627,8 +3579,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.5.0: - resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -3785,6 +3737,10 @@ packages: resolution: {integrity: sha512-FcF8VhXYLQcxWCnt/cCpT2apKsRDUGeVEeMqGu4HSTu29U8Yw0TLOjdYIlDsYk3IkUh+taX4IDWpPcCqKDhCjA==} engines: {node: '>= 20'} + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + https-proxy-agent@7.0.6: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} @@ -3858,8 +3814,8 @@ packages: '@types/react': optional: true - ink@7.0.2: - resolution: {integrity: sha512-cnkE2SsDC/gieJ+BD8+gWpXrZPMInv7agBYN5gcKVlQZYp+IKa/FKM5bp1OIuJFp3ZIuRK7ZNxY4MZR3tUzyfQ==} + ink@7.0.3: + resolution: {integrity: sha512-5kxHkIj9+RuqCU3zyvP4qvYWNOSHP2TW/SHayHGHOmk87KwfVcZwvJGemi9ch+ci2gXUqerK/Eh2DGEDt5q45g==} engines: {node: '>=22'} peerDependencies: '@types/react': '>=19.2.0' @@ -3997,8 +3953,8 @@ packages: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true - jose@6.2.2: - resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + jose@6.2.3: + resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==} js-md4@0.3.2: resolution: {integrity: sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA==} @@ -4051,8 +4007,8 @@ packages: jws@4.0.1: resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} - knip@6.12.2: - resolution: {integrity: sha512-RcZpT1sVziKZgDk1F0hAcp+bq71VJAF8vg1Y9ZLXc1+UXQaMm1rjiUqpJQTIj+lqwmiBQT19/u7ikgazs23cvA==} + knip@6.14.1: + resolution: {integrity: sha512-SN3Ly0ixzj5CQkY/rc4OPHpWrCC0XRIIjgdP76G9Cni5k72ur5jBYOyvJuF5oPTM14v8eHcMUgPbElHa+lnR0g==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -4202,24 +4158,24 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.3.6: - resolution: {integrity: sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==} + lru-cache@11.5.0: + resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==} engines: {node: 20 || >=22} lru.min@1.1.4: resolution: {integrity: sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==} engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} - lucide-react@1.14.0: - resolution: {integrity: sha512-+1mdWcfSJVUsaTIjN9zoezmUhfXo5l0vP7ekBMPo3jcS/aIkxHnXqAPsByszMZx/Y8oQBRJxJx5xg+RH3urzxA==} + lucide-react@1.16.0: + resolution: {integrity: sha512-dYwyPzb4MEKpGUmNYk3WKWPnMrHs3FKM+q94kAnJrcDIqqn1hq2xY8scaS2ovsOCM5D51ey2gaRG3PBb1vgoYQ==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0 magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magicast@0.5.2: - resolution: {integrity: sha512-E3ZJh4J3S9KfwdjZhe2afj6R9lGIN5Pher1pF39UGrXRqq/VDaGVIGN13BjHd2u8B61hArAGOnso7nBOouW3TQ==} + magicast@0.5.3: + resolution: {integrity: sha512-pVKE4UdSQ7DvHzivsCIFx2BJn1mHG6KsyrFcaxFx6tONdneEuThrDx0Cj3AMg58KyN4pzYT+LHOotxDQDjNvkw==} make-asynchronous@1.1.0: resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==} @@ -4478,14 +4434,14 @@ packages: moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} - motion-dom@12.38.0: - resolution: {integrity: sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==} + motion-dom@12.40.0: + resolution: {integrity: sha512-HxU3ZaBwNPVQUBQf1xxgq+7JrPNZvjLVxgbpEZL7RrWJnsxOf0/OM+yrHG9ogLQ31Do/r57Oz2gQWPK+6q62mg==} - motion-utils@12.36.0: - resolution: {integrity: sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==} + motion-utils@12.39.0: + resolution: {integrity: sha512-8nadJAJjTtqRkmRF36FoJTrywK9nnFmnPwnSMyxaOCU7GDjN9RTMJIxx9De8ErM+vpPhMccr/6fo5WciyQLnMQ==} - motion@12.38.0: - resolution: {integrity: sha512-uYfXzeHlgThchzwz5Te47dlv5JOUC7OB4rjJ/7XTUgtBZD8CchMN8qEJ4ZVsUmTyYA44zjV0fBwsiktRuFnn+w==} + motion@12.40.0: + resolution: {integrity: sha512-yjrHUrBFW6kQvjJwRsoiPSAhC5tRwRqNGJWmiJ4CrGnbKp0V88AdzkhBmDoqIsIPfarOe0Uddd37Xq43/gIocA==} peerDependencies: '@emotion/is-prop-valid': '*' react: ^18.0.0 || ^19.0.0 @@ -4501,8 +4457,8 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - mssql@12.5.2: - resolution: {integrity: sha512-rPXZdvYGCayb4+pRmqZ3oymDJB4ZrMpjnZfs3/EZYg8cXfYMWHZo8Kh5zVxny0GyRfPOCslcGuEEMUIyCWRRxg==} + mssql@12.5.4: + resolution: {integrity: sha512-f8UzhpO1STCYhxBybEgT4kaPa2Pda+nucQcMMad7RqOmmTZu3tjkvpPeI9h0RdSK//eua4ybRsLcalz/ttagwQ==} engines: {node: '>=18.19.0'} hasBin: true @@ -4519,8 +4475,8 @@ packages: resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==} engines: {node: '>=8.0.0'} - nanoid@3.3.11: - resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -4567,8 +4523,8 @@ packages: sass: optional: true - node-abi@3.89.0: - resolution: {integrity: sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==} + node-abi@3.92.0: + resolution: {integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==} engines: {node: '>=10'} node-domexception@1.0.0: @@ -4592,8 +4548,8 @@ packages: resolution: {integrity: sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==} engines: {node: ^20.17.0 || >=22.9.0} - normalize-url@9.0.0: - resolution: {integrity: sha512-z9nC87iaZXXySbWWtTHfCFJyFvKaUAW6lODhikG7ILSbVgmwuFjUqkgnheHvAUcGedO29e2QGBRXMUD64aurqQ==} + normalize-url@9.0.1: + resolution: {integrity: sha512-ARftfC5HdUNu9jJeL8pHj8debUIHA2b91FizCoMzY4lG6dDX13jdvTK0TBe24IBDRf2HvJSzzwEPvmbkQWHRSg==} engines: {node: '>=20'} npm-run-path@4.0.1: @@ -4608,8 +4564,8 @@ packages: resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} engines: {node: '>=18'} - npm@11.14.1: - resolution: {integrity: sha512-aopNZ0eEl6LbxoFcrXLmTEPzNBNxfiQnVgR9RmJBqzm+5h5pFoOmRljpRJbsXxocBeSl7GLcx3MoDf2UlEOjZw==} + npm@11.15.0: + resolution: {integrity: sha512-+k0tk7lRnpMUPnC7kTuU/yrV/mnFoPhJQ75VfLtZ6fwbzOVXaPsTE/Il9Pn1DHi482byMyqkHv/XsQ76mNjXLw==} engines: {node: ^20.17.0 || >=22.9.0} hasBin: true bundledDependencies: @@ -4725,8 +4681,8 @@ packages: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} - openai@6.37.0: - resolution: {integrity: sha512-0H5dEGFmmLv6KSd0W1w2nyL8WsLkX6yoLeQpU+dZAOuGcany5qkYQMmj35ZrKgb6yiyYqpUzFOpR8mZQkgqeEQ==} + openai@6.38.0: + resolution: {integrity: sha512-AoMplt2UalrpgUDMh3L09QWjNRlgJPipclQvA6sYAaeF6nHNBMgmikAZGmcYLn8on4d9sQY9Q8bOLfrBS7Lc8g==} hasBin: true peerDependencies: ws: 8.20.1 @@ -4737,8 +4693,8 @@ packages: zod: optional: true - oxc-parser@0.128.0: - resolution: {integrity: sha512-XkOw3eiIxAgQ19WRew/Bq9wc5Ga/guaWIzDBzq80z1PyuDNGvWBpPby9k6YGwV8A8uMw+Nlq3xqlzuDYmUFYUw==} + oxc-parser@0.130.0: + resolution: {integrity: sha512-X0PJ+NmOok8qP3vK9uaW431ngkdM9UPEK7KG466urtIL2+EYTEgbZK2yqe2MWKJKBjRlFweP/pJPx0x9muMEVw==} engines: {node: ^20.19.0 || >=22.12.0} oxc-resolver@11.19.1: @@ -4870,30 +4826,30 @@ packages: engines: {node: '>=0.10'} hasBin: true - pg-cloudflare@1.3.0: - resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} + pg-cloudflare@1.4.0: + resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==} - pg-connection-string@2.12.0: - resolution: {integrity: sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==} + pg-connection-string@2.13.0: + resolution: {integrity: sha512-EMnU9E2fSULdsbErBbMaXJvFeD9B4+nPcM3f+4lsiCR0BHLPrLVjv3DbyM2hgQQviKJaTWIRRTjKjWlHg3p2ig==} pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - pg-pool@3.13.0: - resolution: {integrity: sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==} + pg-pool@3.14.0: + resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==} peerDependencies: pg: '>=8.0' - pg-protocol@1.13.0: - resolution: {integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==} + pg-protocol@1.14.0: + resolution: {integrity: sha512-n5taZ1kO3s9ngDTVxsEznOqCyToTgz0FLuPq0B33COy5pPpuWJpY3/2oRBVETuOgzdqRXfWpM9HIhp2LBBT1BA==} pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} engines: {node: '>=4'} - pg@8.20.0: - resolution: {integrity: sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==} + pg@8.21.0: + resolution: {integrity: sha512-AUP1EYJuHraQGsVoCQVIcM7TEJVGtDzxWtGFZd8rds9d+CCXlU5Js1rYgfLNvxy9iJrpHjGrRjoi/3BT9fRyiA==} engines: {node: '>= 16.0.0'} peerDependencies: pg-native: '>=3.0.1' @@ -4947,9 +4903,14 @@ packages: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} - posthog-node@5.0.0: - resolution: {integrity: sha512-gontigBt1pGHGXZme3+ojDdCYL66h/vvo+6KaQ6A51xqUOYgRvyzCLkS9Xv816jNBesRO8ouRjG428SDb2fFkg==} - engines: {node: '>=20'} + posthog-node@5.34.9: + resolution: {integrity: sha512-vOH+71q/Cb68ILXj58M2fV3GcE2sHimVFn2JQJYpe2wxAdZjWyt7sGhY1NI2/87DVjJ0zisEboVCX9/WXxXlMg==} + engines: {node: ^20.20.0 || >=22.22.0} + peerDependencies: + rxjs: ^7.0.0 + peerDependenciesMeta: + rxjs: + optional: true prebuild-install@7.1.3: resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} @@ -4985,8 +4946,8 @@ packages: pump@3.0.4: resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} - qs@6.15.1: - resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} + qs@6.15.2: + resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} engines: {node: '>=0.6'} range-parser@1.2.1: @@ -5155,8 +5116,8 @@ packages: resolution: {integrity: sha512-JzFPAfklk1kjR1w76f0QOIhoDkNkSqW8wYKT08n9yysTmZfB+RQ2QoXoTAeOi1HD9ZipTyTAZg3c4pM/jeqgSw==} engines: {node: '>=18'} - rolldown@1.0.0-rc.17: - resolution: {integrity: sha512-ZrT53oAKrtA4+YtBWPQbtPOxIbVDbxT0orcYERKd63VJTF13zPcgXTvD4843L8pcsI7M6MErt8QtON6lrB9tyA==} + rolldown@1.0.2: + resolution: {integrity: sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -5196,8 +5157,8 @@ packages: resolution: {integrity: sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==} engines: {node: '>=12'} - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + semver@7.8.0: + resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} engines: {node: '>=10'} hasBin: true @@ -5224,8 +5185,8 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - shiki@4.0.2: - resolution: {integrity: sha512-eAVKTMedR5ckPo4xne/PjYQYrU3qx78gtJZ+sHlXEg5IHhhoQhMfZVzetTYuaJS0L2Ef3AcCRzCHV8T0WI6nIQ==} + shiki@4.1.0: + resolution: {integrity: sha512-l/ABZPUR5v70jI10EzqfMS/I96vjSGv2y0ihUV+WYFzv0EfvW4s54m0Lg8wCrrL+2IkwBzFTuxkZjPf8b2NX9Q==} engines: {node: '>=20'} side-channel-list@1.0.1: @@ -5285,8 +5246,8 @@ packages: resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} engines: {node: '>= 18'} - snowflake-sdk@2.4.1: - resolution: {integrity: sha512-JIdqz9ed2FzkU8oEstf06hTJRoX9+PRRG9LJT1vfGTXN3A52kGxhGoWzmK0GtFTUnxTMxMoMYgD5QdoQbckyag==} + snowflake-sdk@2.4.2: + resolution: {integrity: sha512-sN9683tRetlGC1rFGLUSkwpUVaVwRbATho7DcHUwft76rg2EHq8ooiMs6iHHtXLSG6IGmly51oajAyc7/nOOhg==} engines: {node: '>=18'} peerDependencies: asn1.js: ^5.4.1 @@ -5345,6 +5306,9 @@ packages: stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + standardwebhooks@1.0.0: + resolution: {integrity: sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==} + statuses@2.0.2: resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} engines: {node: '>= 0.8'} @@ -5386,8 +5350,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.2: - resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} engines: {node: '>=12'} strip-bom@3.0.0: @@ -5414,8 +5378,8 @@ packages: resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} engines: {node: '>=14.16'} - strnum@2.2.3: - resolution: {integrity: sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==} + strnum@2.3.0: + resolution: {integrity: sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==} stubs@3.0.0: resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==} @@ -5520,10 +5484,6 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@1.1.1: - resolution: {integrity: sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==} - engines: {node: '>=18'} - tinyexec@1.1.2: resolution: {integrity: sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==} engines: {node: '>=18'} @@ -5590,9 +5550,9 @@ packages: resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==} engines: {node: '>=20'} - type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} typescript@6.0.3: resolution: {integrity: sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==} @@ -5722,13 +5682,13 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} - vite@8.0.10: - resolution: {integrity: sha512-rZuUu9j6J5uotLDs+cAA4O5H4K1SfPliUlQwqa6YEwSrWDZzP4rhm00oJR5snMewjxF5V/K3D4kctsUTsIU9Mw==} + vite@8.0.14: + resolution: {integrity: sha512-s4BJJ+5y1pYL6Otw51FHhVJQhPnuRinKig64g/1+EUNaJsd3gCKdD31IPFvswUgW9/60QT9oFHbZHbQK5imcxw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^24.3.0 - '@vitejs/devtools': ^0.1.0 + '@vitejs/devtools': ^0.1.18 esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 @@ -5765,20 +5725,20 @@ packages: yaml: optional: true - vitest@4.1.6: - resolution: {integrity: sha512-6lvjbS3p9b4CrdCmguzbh2/4uoXhGE2q71R4OX5sqF9R1bo9Xd6fGrMAfvp5wnCzlBnFVdCOp6onuTQVbo8iUQ==} + vitest@4.1.7: + resolution: {integrity: sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^24.3.0 - '@vitest/browser-playwright': 4.1.6 - '@vitest/browser-preview': 4.1.6 - '@vitest/browser-webdriverio': 4.1.6 - '@vitest/coverage-istanbul': 4.1.6 - '@vitest/coverage-v8': 4.1.6 - '@vitest/ui': 4.1.6 + '@vitest/browser-playwright': 4.1.7 + '@vitest/browser-preview': 4.1.7 + '@vitest/browser-webdriverio': 4.1.7 + '@vitest/coverage-istanbul': 4.1.7 + '@vitest/coverage-v8': 4.1.7 + '@vitest/ui': 4.1.7 happy-dom: '*' jsdom: '*' vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -5876,6 +5836,10 @@ packages: resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} engines: {node: '>=18'} + xml-naming@0.1.0: + resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==} + engines: {node: '>=16.0.0'} + xtend@4.0.2: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} @@ -5960,29 +5924,29 @@ snapshots: '@actions/io@3.0.2': {} - '@ai-sdk/anthropic@3.0.77(zod@4.4.3)': + '@ai-sdk/anthropic@3.0.78(zod@4.4.3)': dependencies: '@ai-sdk/provider': 3.0.10 '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) zod: 4.4.3 - '@ai-sdk/devtools@0.0.17': + '@ai-sdk/devtools@0.0.18': dependencies: '@ai-sdk/provider': 3.0.10 '@hono/node-server': 1.19.14(hono@4.12.18) hono: 4.12.18 - '@ai-sdk/gateway@3.0.114(zod@4.4.3)': + '@ai-sdk/gateway@3.0.118(zod@4.4.3)': dependencies: '@ai-sdk/provider': 3.0.10 '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) '@vercel/oidc': 3.2.0 zod: 4.4.3 - '@ai-sdk/google-vertex@4.0.128(zod@4.4.3)': + '@ai-sdk/google-vertex@4.0.134(zod@4.4.3)': dependencies: - '@ai-sdk/anthropic': 3.0.77(zod@4.4.3) - '@ai-sdk/google': 3.0.73(zod@4.4.3) + '@ai-sdk/anthropic': 3.0.78(zod@4.4.3) + '@ai-sdk/google': 3.0.78(zod@4.4.3) '@ai-sdk/openai-compatible': 2.0.47(zod@4.4.3) '@ai-sdk/provider': 3.0.10 '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) @@ -5991,7 +5955,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@ai-sdk/google@3.0.73(zod@4.4.3)': + '@ai-sdk/google@3.0.78(zod@4.4.3)': dependencies: '@ai-sdk/provider': 3.0.10 '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) @@ -6021,51 +5985,49 @@ snapshots: '@alloc/quick-lru@5.2.0': {} - '@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.142': + '@anthropic-ai/claude-agent-sdk-darwin-arm64@0.3.146': optional: true - '@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.142': + '@anthropic-ai/claude-agent-sdk-darwin-x64@0.3.146': optional: true - '@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.142': + '@anthropic-ai/claude-agent-sdk-linux-arm64-musl@0.3.146': optional: true - '@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.142': + '@anthropic-ai/claude-agent-sdk-linux-arm64@0.3.146': optional: true - '@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.142': + '@anthropic-ai/claude-agent-sdk-linux-x64-musl@0.3.146': optional: true - '@anthropic-ai/claude-agent-sdk-linux-x64@0.3.142': + '@anthropic-ai/claude-agent-sdk-linux-x64@0.3.146': optional: true - '@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.142': + '@anthropic-ai/claude-agent-sdk-win32-arm64@0.3.146': optional: true - '@anthropic-ai/claude-agent-sdk-win32-x64@0.3.142': + '@anthropic-ai/claude-agent-sdk-win32-x64@0.3.146': optional: true - '@anthropic-ai/claude-agent-sdk@0.3.142(zod@4.4.3)': + '@anthropic-ai/claude-agent-sdk@0.3.146(@anthropic-ai/sdk@0.97.1(zod@4.4.3))(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3)': dependencies: - '@anthropic-ai/sdk': 0.93.0(zod@4.4.3) + '@anthropic-ai/sdk': 0.97.1(zod@4.4.3) '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3) zod: 4.4.3 optionalDependencies: - '@anthropic-ai/claude-agent-sdk-darwin-arm64': 0.3.142 - '@anthropic-ai/claude-agent-sdk-darwin-x64': 0.3.142 - '@anthropic-ai/claude-agent-sdk-linux-arm64': 0.3.142 - '@anthropic-ai/claude-agent-sdk-linux-arm64-musl': 0.3.142 - '@anthropic-ai/claude-agent-sdk-linux-x64': 0.3.142 - '@anthropic-ai/claude-agent-sdk-linux-x64-musl': 0.3.142 - '@anthropic-ai/claude-agent-sdk-win32-arm64': 0.3.142 - '@anthropic-ai/claude-agent-sdk-win32-x64': 0.3.142 - transitivePeerDependencies: - - '@cfworker/json-schema' - - supports-color + '@anthropic-ai/claude-agent-sdk-darwin-arm64': 0.3.146 + '@anthropic-ai/claude-agent-sdk-darwin-x64': 0.3.146 + '@anthropic-ai/claude-agent-sdk-linux-arm64': 0.3.146 + '@anthropic-ai/claude-agent-sdk-linux-arm64-musl': 0.3.146 + '@anthropic-ai/claude-agent-sdk-linux-x64': 0.3.146 + '@anthropic-ai/claude-agent-sdk-linux-x64-musl': 0.3.146 + '@anthropic-ai/claude-agent-sdk-win32-arm64': 0.3.146 + '@anthropic-ai/claude-agent-sdk-win32-x64': 0.3.146 - '@anthropic-ai/sdk@0.93.0(zod@4.4.3)': + '@anthropic-ai/sdk@0.97.1(zod@4.4.3)': dependencies: json-schema-to-ts: 3.1.1 + standardwebhooks: 1.0.0 optionalDependencies: zod: 4.4.3 @@ -6121,452 +6083,346 @@ snapshots: '@aws-crypto/sha1-browser': 5.2.0 '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.8 - '@aws-sdk/credential-provider-node': 3.972.39 - '@aws-sdk/middleware-bucket-endpoint': 3.972.10 - '@aws-sdk/middleware-expect-continue': 3.972.10 - '@aws-sdk/middleware-flexible-checksums': 3.974.16 - '@aws-sdk/middleware-host-header': 3.972.10 + '@aws-sdk/core': 3.974.12 + '@aws-sdk/credential-provider-node': 3.972.43 + '@aws-sdk/middleware-bucket-endpoint': 3.972.14 + '@aws-sdk/middleware-expect-continue': 3.972.12 + '@aws-sdk/middleware-flexible-checksums': 3.974.20 + '@aws-sdk/middleware-host-header': 3.972.13 '@aws-sdk/middleware-location-constraint': 3.972.10 - '@aws-sdk/middleware-logger': 3.972.10 - '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-sdk-s3': 3.972.37 + '@aws-sdk/middleware-logger': 3.972.12 + '@aws-sdk/middleware-recursion-detection': 3.972.14 + '@aws-sdk/middleware-sdk-s3': 3.972.41 '@aws-sdk/middleware-ssec': 3.972.10 - '@aws-sdk/middleware-user-agent': 3.972.38 - '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/signature-v4-multi-region': 3.996.25 + '@aws-sdk/middleware-user-agent': 3.972.42 + '@aws-sdk/region-config-resolver': 3.972.16 + '@aws-sdk/signature-v4-multi-region': 3.996.27 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.8 - '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.24 - '@smithy/config-resolver': 4.4.17 - '@smithy/core': 3.23.17 - '@smithy/eventstream-serde-browser': 4.2.14 - '@smithy/eventstream-serde-config-resolver': 4.3.14 - '@smithy/eventstream-serde-node': 4.2.14 - '@smithy/fetch-http-handler': 5.3.17 - '@smithy/hash-blob-browser': 4.2.15 - '@smithy/hash-node': 4.2.14 - '@smithy/hash-stream-node': 4.2.14 - '@smithy/invalid-dependency': 4.2.14 - '@smithy/md5-js': 4.2.14 - '@smithy/middleware-content-length': 4.2.14 - '@smithy/middleware-endpoint': 4.4.32 - '@smithy/middleware-retry': 4.5.7 - '@smithy/middleware-serde': 4.2.20 - '@smithy/middleware-stack': 4.2.14 - '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.1 - '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-base64': 4.3.2 - '@smithy/util-body-length-browser': 4.2.2 - '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.49 - '@smithy/util-defaults-mode-node': 4.2.54 - '@smithy/util-endpoints': 3.4.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.6 - '@smithy/util-stream': 4.5.25 - '@smithy/util-utf8': 4.2.2 - '@smithy/util-waiter': 4.3.0 + '@aws-sdk/util-endpoints': 3.996.11 + '@aws-sdk/util-user-agent-browser': 3.972.13 + '@aws-sdk/util-user-agent-node': 3.973.28 + '@smithy/config-resolver': 4.5.3 + '@smithy/core': 3.24.3 + '@smithy/eventstream-serde-browser': 4.3.3 + '@smithy/eventstream-serde-config-resolver': 4.4.3 + '@smithy/eventstream-serde-node': 4.3.3 + '@smithy/fetch-http-handler': 5.4.3 + '@smithy/hash-blob-browser': 4.3.3 + '@smithy/hash-node': 4.3.3 + '@smithy/hash-stream-node': 4.3.3 + '@smithy/invalid-dependency': 4.3.3 + '@smithy/md5-js': 4.3.3 + '@smithy/middleware-content-length': 4.3.3 + '@smithy/middleware-endpoint': 4.5.3 + '@smithy/middleware-retry': 4.6.3 + '@smithy/middleware-serde': 4.3.3 + '@smithy/middleware-stack': 4.3.3 + '@smithy/node-config-provider': 4.4.3 + '@smithy/node-http-handler': 4.7.3 + '@smithy/protocol-http': 5.4.3 + '@smithy/smithy-client': 4.13.3 + '@smithy/types': 4.14.2 + '@smithy/url-parser': 4.3.3 + '@smithy/util-base64': 4.4.3 + '@smithy/util-body-length-browser': 4.3.3 + '@smithy/util-body-length-node': 4.3.3 + '@smithy/util-defaults-mode-browser': 4.4.3 + '@smithy/util-defaults-mode-node': 4.3.3 + '@smithy/util-endpoints': 3.5.3 + '@smithy/util-middleware': 4.3.3 + '@smithy/util-retry': 4.4.3 + '@smithy/util-stream': 4.6.3 + '@smithy/util-utf8': 4.3.3 + '@smithy/util-waiter': 4.4.3 tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt '@aws-sdk/client-sts@3.1045.0': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.8 - '@aws-sdk/credential-provider-node': 3.972.39 - '@aws-sdk/middleware-host-header': 3.972.10 - '@aws-sdk/middleware-logger': 3.972.10 - '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-user-agent': 3.972.38 - '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/signature-v4-multi-region': 3.996.25 + '@aws-sdk/core': 3.974.12 + '@aws-sdk/credential-provider-node': 3.972.43 + '@aws-sdk/middleware-host-header': 3.972.13 + '@aws-sdk/middleware-logger': 3.972.12 + '@aws-sdk/middleware-recursion-detection': 3.972.14 + '@aws-sdk/middleware-user-agent': 3.972.42 + '@aws-sdk/region-config-resolver': 3.972.16 + '@aws-sdk/signature-v4-multi-region': 3.996.27 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.8 - '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.24 - '@smithy/config-resolver': 4.4.17 - '@smithy/core': 3.23.17 - '@smithy/fetch-http-handler': 5.3.17 - '@smithy/hash-node': 4.2.14 - '@smithy/invalid-dependency': 4.2.14 - '@smithy/middleware-content-length': 4.2.14 - '@smithy/middleware-endpoint': 4.4.32 - '@smithy/middleware-retry': 4.5.7 - '@smithy/middleware-serde': 4.2.20 - '@smithy/middleware-stack': 4.2.14 - '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.1 - '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-base64': 4.3.2 - '@smithy/util-body-length-browser': 4.2.2 - '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.49 - '@smithy/util-defaults-mode-node': 4.2.54 - '@smithy/util-endpoints': 3.4.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.6 - '@smithy/util-utf8': 4.2.2 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/core@3.974.8': - dependencies: - '@aws-sdk/types': 3.973.8 - '@aws-sdk/xml-builder': 3.972.22 - '@smithy/core': 3.23.17 - '@smithy/node-config-provider': 4.3.14 - '@smithy/property-provider': 4.2.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/signature-v4': 5.3.14 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 - '@smithy/util-base64': 4.3.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.6 - '@smithy/util-utf8': 4.2.2 + '@aws-sdk/util-endpoints': 3.996.11 + '@aws-sdk/util-user-agent-browser': 3.972.13 + '@aws-sdk/util-user-agent-node': 3.973.28 + '@smithy/config-resolver': 4.5.3 + '@smithy/core': 3.24.3 + '@smithy/fetch-http-handler': 5.4.3 + '@smithy/hash-node': 4.3.3 + '@smithy/invalid-dependency': 4.3.3 + '@smithy/middleware-content-length': 4.3.3 + '@smithy/middleware-endpoint': 4.5.3 + '@smithy/middleware-retry': 4.6.3 + '@smithy/middleware-serde': 4.3.3 + '@smithy/middleware-stack': 4.3.3 + '@smithy/node-config-provider': 4.4.3 + '@smithy/node-http-handler': 4.7.3 + '@smithy/protocol-http': 5.4.3 + '@smithy/smithy-client': 4.13.3 + '@smithy/types': 4.14.2 + '@smithy/url-parser': 4.3.3 + '@smithy/util-base64': 4.4.3 + '@smithy/util-body-length-browser': 4.3.3 + '@smithy/util-body-length-node': 4.3.3 + '@smithy/util-defaults-mode-browser': 4.4.3 + '@smithy/util-defaults-mode-node': 4.3.3 + '@smithy/util-endpoints': 3.5.3 + '@smithy/util-middleware': 4.3.3 + '@smithy/util-retry': 4.4.3 + '@smithy/util-utf8': 4.3.3 tslib: 2.8.1 - '@aws-sdk/crc64-nvme@3.972.7': + '@aws-sdk/core@3.974.12': dependencies: - '@smithy/types': 4.14.1 + '@aws-sdk/types': 3.973.8 + '@aws-sdk/xml-builder': 3.972.24 + '@aws/lambda-invoke-store': 0.2.4 + '@smithy/core': 3.24.3 + '@smithy/signature-v4': 5.4.3 + '@smithy/types': 4.14.2 + bowser: 2.14.1 tslib: 2.8.1 - '@aws-sdk/credential-provider-env@3.972.34': + '@aws-sdk/crc64-nvme@3.972.8': dependencies: - '@aws-sdk/core': 3.974.8 - '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/types': 4.14.1 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-http@3.972.36': + '@aws-sdk/credential-provider-env@3.972.38': dependencies: - '@aws-sdk/core': 3.974.8 + '@aws-sdk/core': 3.974.12 '@aws-sdk/types': 3.973.8 - '@smithy/fetch-http-handler': 5.3.17 - '@smithy/node-http-handler': 4.6.1 - '@smithy/property-provider': 4.2.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 - '@smithy/util-stream': 4.5.25 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-ini@3.972.38': + '@aws-sdk/credential-provider-http@3.972.40': dependencies: - '@aws-sdk/core': 3.974.8 - '@aws-sdk/credential-provider-env': 3.972.34 - '@aws-sdk/credential-provider-http': 3.972.36 - '@aws-sdk/credential-provider-login': 3.972.38 - '@aws-sdk/credential-provider-process': 3.972.34 - '@aws-sdk/credential-provider-sso': 3.972.38 - '@aws-sdk/credential-provider-web-identity': 3.972.38 - '@aws-sdk/nested-clients': 3.997.6 + '@aws-sdk/core': 3.974.12 '@aws-sdk/types': 3.973.8 - '@smithy/credential-provider-imds': 4.2.14 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/credential-provider-login@3.972.38': - dependencies: - '@aws-sdk/core': 3.974.8 - '@aws-sdk/nested-clients': 3.997.6 - '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/credential-provider-node@3.972.39': - dependencies: - '@aws-sdk/credential-provider-env': 3.972.34 - '@aws-sdk/credential-provider-http': 3.972.36 - '@aws-sdk/credential-provider-ini': 3.972.38 - '@aws-sdk/credential-provider-process': 3.972.34 - '@aws-sdk/credential-provider-sso': 3.972.38 - '@aws-sdk/credential-provider-web-identity': 3.972.38 - '@aws-sdk/types': 3.973.8 - '@smithy/credential-provider-imds': 4.2.14 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/credential-provider-process@3.972.34': - dependencies: - '@aws-sdk/core': 3.974.8 - '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 + '@smithy/fetch-http-handler': 5.4.3 + '@smithy/node-http-handler': 4.7.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/credential-provider-sso@3.972.38': + '@aws-sdk/credential-provider-ini@3.972.42': dependencies: - '@aws-sdk/core': 3.974.8 - '@aws-sdk/nested-clients': 3.997.6 - '@aws-sdk/token-providers': 3.1041.0 + '@aws-sdk/core': 3.974.12 + '@aws-sdk/credential-provider-env': 3.972.38 + '@aws-sdk/credential-provider-http': 3.972.40 + '@aws-sdk/credential-provider-login': 3.972.42 + '@aws-sdk/credential-provider-process': 3.972.38 + '@aws-sdk/credential-provider-sso': 3.972.42 + '@aws-sdk/credential-provider-web-identity': 3.972.42 + '@aws-sdk/nested-clients': 3.997.10 '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 + '@smithy/credential-provider-imds': 4.3.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - '@aws-sdk/credential-provider-web-identity@3.972.38': + '@aws-sdk/credential-provider-login@3.972.42': dependencies: - '@aws-sdk/core': 3.974.8 - '@aws-sdk/nested-clients': 3.997.6 + '@aws-sdk/core': 3.974.12 + '@aws-sdk/nested-clients': 3.997.10 '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-node@3.972.43': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.38 + '@aws-sdk/credential-provider-http': 3.972.40 + '@aws-sdk/credential-provider-ini': 3.972.42 + '@aws-sdk/credential-provider-process': 3.972.38 + '@aws-sdk/credential-provider-sso': 3.972.42 + '@aws-sdk/credential-provider-web-identity': 3.972.42 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/credential-provider-imds': 4.3.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-process@3.972.38': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.972.42': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/nested-clients': 3.997.10 + '@aws-sdk/token-providers': 3.1049.0 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-web-identity@3.972.42': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/nested-clients': 3.997.10 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt '@aws-sdk/ec2-metadata-service@3.1045.0': dependencies: '@aws-sdk/types': 3.973.8 - '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.1 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-stream': 4.5.25 + '@smithy/node-config-provider': 4.4.3 + '@smithy/node-http-handler': 4.7.3 + '@smithy/protocol-http': 5.4.3 + '@smithy/types': 4.14.2 + '@smithy/util-stream': 4.6.3 tslib: 2.8.1 - '@aws-sdk/middleware-bucket-endpoint@3.972.10': + '@aws-sdk/middleware-bucket-endpoint@3.972.14': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/middleware-expect-continue@3.972.12': dependencies: '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-arn-parser': 3.972.3 - '@smithy/node-config-provider': 4.3.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-config-provider': 4.2.2 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/middleware-expect-continue@3.972.10': - dependencies: - '@aws-sdk/types': 3.973.8 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@aws-sdk/middleware-flexible-checksums@3.974.16': + '@aws-sdk/middleware-flexible-checksums@3.974.20': dependencies: '@aws-crypto/crc32': 5.2.0 '@aws-crypto/crc32c': 5.2.0 '@aws-crypto/util': 5.2.0 - '@aws-sdk/core': 3.974.8 - '@aws-sdk/crc64-nvme': 3.972.7 + '@aws-sdk/core': 3.974.12 + '@aws-sdk/crc64-nvme': 3.972.8 '@aws-sdk/types': 3.973.8 - '@smithy/is-array-buffer': 4.2.2 - '@smithy/node-config-provider': 4.3.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.25 - '@smithy/util-utf8': 4.2.2 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/middleware-host-header@3.972.10': + '@aws-sdk/middleware-host-header@3.972.13': dependencies: - '@aws-sdk/types': 3.973.8 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 + '@aws-sdk/core': 3.974.12 tslib: 2.8.1 '@aws-sdk/middleware-location-constraint@3.972.10': dependencies: '@aws-sdk/types': 3.973.8 - '@smithy/types': 4.14.1 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/middleware-logger@3.972.10': + '@aws-sdk/middleware-logger@3.972.12': dependencies: - '@aws-sdk/types': 3.973.8 - '@smithy/types': 4.14.1 + '@aws-sdk/core': 3.974.12 tslib: 2.8.1 - '@aws-sdk/middleware-recursion-detection@3.972.11': + '@aws-sdk/middleware-recursion-detection@3.972.14': dependencies: - '@aws-sdk/types': 3.973.8 - '@aws/lambda-invoke-store': 0.2.4 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 + '@aws-sdk/core': 3.974.12 tslib: 2.8.1 - '@aws-sdk/middleware-sdk-s3@3.972.37': + '@aws-sdk/middleware-sdk-s3@3.972.41': dependencies: - '@aws-sdk/core': 3.974.8 + '@aws-sdk/core': 3.974.12 + '@aws-sdk/signature-v4-multi-region': 3.996.27 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-arn-parser': 3.972.3 - '@smithy/core': 3.23.17 - '@smithy/node-config-provider': 4.3.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/signature-v4': 5.3.14 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 - '@smithy/util-config-provider': 4.2.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.25 - '@smithy/util-utf8': 4.2.2 + '@smithy/core': 3.24.3 + '@smithy/signature-v4': 5.4.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 '@aws-sdk/middleware-ssec@3.972.10': dependencies: '@aws-sdk/types': 3.973.8 - '@smithy/types': 4.14.1 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/middleware-user-agent@3.972.38': + '@aws-sdk/middleware-user-agent@3.972.42': dependencies: - '@aws-sdk/core': 3.974.8 - '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.8 - '@smithy/core': 3.23.17 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-retry': 4.3.6 + '@aws-sdk/core': 3.974.12 tslib: 2.8.1 - '@aws-sdk/nested-clients@3.997.6': + '@aws-sdk/nested-clients@3.997.10': dependencies: '@aws-crypto/sha256-browser': 5.2.0 '@aws-crypto/sha256-js': 5.2.0 - '@aws-sdk/core': 3.974.8 - '@aws-sdk/middleware-host-header': 3.972.10 - '@aws-sdk/middleware-logger': 3.972.10 - '@aws-sdk/middleware-recursion-detection': 3.972.11 - '@aws-sdk/middleware-user-agent': 3.972.38 - '@aws-sdk/region-config-resolver': 3.972.13 - '@aws-sdk/signature-v4-multi-region': 3.996.25 + '@aws-sdk/core': 3.974.12 + '@aws-sdk/signature-v4-multi-region': 3.996.27 '@aws-sdk/types': 3.973.8 - '@aws-sdk/util-endpoints': 3.996.8 - '@aws-sdk/util-user-agent-browser': 3.972.10 - '@aws-sdk/util-user-agent-node': 3.973.24 - '@smithy/config-resolver': 4.4.17 - '@smithy/core': 3.23.17 - '@smithy/fetch-http-handler': 5.3.17 - '@smithy/hash-node': 4.2.14 - '@smithy/invalid-dependency': 4.2.14 - '@smithy/middleware-content-length': 4.2.14 - '@smithy/middleware-endpoint': 4.4.32 - '@smithy/middleware-retry': 4.5.7 - '@smithy/middleware-serde': 4.2.20 - '@smithy/middleware-stack': 4.2.14 - '@smithy/node-config-provider': 4.3.14 - '@smithy/node-http-handler': 4.6.1 - '@smithy/protocol-http': 5.3.14 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-base64': 4.3.2 - '@smithy/util-body-length-browser': 4.2.2 - '@smithy/util-body-length-node': 4.2.3 - '@smithy/util-defaults-mode-browser': 4.3.49 - '@smithy/util-defaults-mode-node': 4.2.54 - '@smithy/util-endpoints': 3.4.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.6 - '@smithy/util-utf8': 4.2.2 - tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt - - '@aws-sdk/region-config-resolver@3.972.13': - dependencies: - '@aws-sdk/types': 3.973.8 - '@smithy/config-resolver': 4.4.17 - '@smithy/node-config-provider': 4.3.14 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 + '@smithy/fetch-http-handler': 5.4.3 + '@smithy/node-http-handler': 4.7.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/signature-v4-multi-region@3.996.25': + '@aws-sdk/region-config-resolver@3.972.16': dependencies: - '@aws-sdk/middleware-sdk-s3': 3.972.37 - '@aws-sdk/types': 3.973.8 - '@smithy/protocol-http': 5.3.14 - '@smithy/signature-v4': 5.3.14 - '@smithy/types': 4.14.1 + '@aws-sdk/core': 3.974.12 tslib: 2.8.1 - '@aws-sdk/token-providers@3.1041.0': + '@aws-sdk/signature-v4-multi-region@3.996.27': dependencies: - '@aws-sdk/core': 3.974.8 - '@aws-sdk/nested-clients': 3.997.6 '@aws-sdk/types': 3.973.8 - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 + '@smithy/signature-v4': 5.4.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1049.0': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/nested-clients': 3.997.10 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 - transitivePeerDependencies: - - aws-crt '@aws-sdk/types@3.973.8': dependencies: - '@smithy/types': 4.14.1 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@aws-sdk/util-arn-parser@3.972.3': + '@aws-sdk/util-endpoints@3.996.11': dependencies: - tslib: 2.8.1 - - '@aws-sdk/util-endpoints@3.996.8': - dependencies: - '@aws-sdk/types': 3.973.8 - '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-endpoints': 3.4.2 + '@aws-sdk/core': 3.974.12 + '@smithy/core': 3.24.3 tslib: 2.8.1 '@aws-sdk/util-locate-window@3.965.5': dependencies: tslib: 2.8.1 - '@aws-sdk/util-user-agent-browser@3.972.10': + '@aws-sdk/util-user-agent-browser@3.972.13': dependencies: - '@aws-sdk/types': 3.973.8 - '@smithy/types': 4.14.1 - bowser: 2.14.1 + '@aws-sdk/core': 3.974.12 tslib: 2.8.1 - '@aws-sdk/util-user-agent-node@3.973.24': + '@aws-sdk/util-user-agent-node@3.973.28': dependencies: - '@aws-sdk/middleware-user-agent': 3.972.38 - '@aws-sdk/types': 3.973.8 - '@smithy/node-config-provider': 4.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-config-provider': 4.2.2 + '@aws-sdk/core': 3.974.12 tslib: 2.8.1 - '@aws-sdk/xml-builder@3.972.22': + '@aws-sdk/xml-builder@3.972.24': dependencies: '@nodable/entities': 2.1.0 - '@smithy/types': 4.14.1 - fast-xml-parser: 5.7.2 + '@smithy/types': 4.14.2 + fast-xml-parser: 5.7.3 tslib: 2.8.1 '@aws/lambda-invoke-store@0.2.4': {} @@ -6651,7 +6507,7 @@ snapshots: '@azure/core-xml@1.5.1': dependencies: - fast-xml-parser: 5.7.2 + fast-xml-parser: 5.8.0 tslib: 2.8.1 '@azure/identity@4.13.1': @@ -6663,8 +6519,8 @@ snapshots: '@azure/core-tracing': 1.3.1 '@azure/core-util': 1.13.1 '@azure/logger': 1.3.0 - '@azure/msal-browser': 5.9.0 - '@azure/msal-node': 5.1.5 + '@azure/msal-browser': 5.11.0 + '@azure/msal-node': 5.2.2 open: 10.2.0 tslib: 2.8.1 transitivePeerDependencies: @@ -6708,15 +6564,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@azure/msal-browser@5.9.0': + '@azure/msal-browser@5.11.0': dependencies: - '@azure/msal-common': 16.5.2 + '@azure/msal-common': 16.6.2 - '@azure/msal-common@16.5.2': {} + '@azure/msal-common@16.6.2': {} - '@azure/msal-node@5.1.5': + '@azure/msal-node@5.2.2': dependencies: - '@azure/msal-common': 16.5.2 + '@azure/msal-common': 16.6.2 jsonwebtoken: 9.0.3 '@azure/storage-blob@12.26.0': @@ -6797,21 +6653,21 @@ snapshots: '@clack/core@1.3.1': dependencies: - fast-wrap-ansi: 0.2.0 + fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 '@clack/prompts@1.4.0': dependencies: '@clack/core': 1.3.1 fast-string-width: 3.0.2 - fast-wrap-ansi: 0.2.0 + fast-wrap-ansi: 0.2.2 sisteransi: 1.0.5 - '@clickhouse/client-common@1.18.4': {} + '@clickhouse/client-common@1.18.5': {} - '@clickhouse/client@1.18.4': + '@clickhouse/client@1.18.5': dependencies: - '@clickhouse/client-common': 1.18.4 + '@clickhouse/client-common': 1.18.5 '@colors/colors@1.5.0': optional: true @@ -7135,7 +6991,7 @@ snapshots: '@mdx-js/mdx@3.1.1': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 '@types/mdx': 2.0.13 @@ -7174,9 +7030,9 @@ snapshots: eventsource: 3.0.7 eventsource-parser: 3.0.8 express: 5.2.1 - express-rate-limit: 8.4.1(express@5.2.1) + express-rate-limit: 8.5.2(express@5.2.1) hono: 4.12.18 - jose: 6.2.2 + jose: 6.2.3 json-schema-typed: 8.0.2 pkce-challenge: 5.0.1 raw-body: 3.0.2 @@ -7189,7 +7045,7 @@ snapshots: dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 - '@tybys/wasm-util': 0.10.1 + '@tybys/wasm-util': 0.10.2 optional: true '@next/env@16.2.6': {} @@ -7220,7 +7076,7 @@ snapshots: '@nodable/entities@2.1.0': {} - '@notionhq/client@5.21.0': {} + '@notionhq/client@5.22.0': {} '@octokit/auth-token@6.0.0': {} @@ -7283,77 +7139,77 @@ snapshots: dependencies: '@octokit/openapi-types': 27.0.0 - '@opentelemetry/api@1.9.0': {} + '@opentelemetry/api@1.9.1': {} '@orama/orama@3.1.18': {} - '@oxc-parser/binding-android-arm-eabi@0.128.0': + '@oxc-parser/binding-android-arm-eabi@0.130.0': optional: true - '@oxc-parser/binding-android-arm64@0.128.0': + '@oxc-parser/binding-android-arm64@0.130.0': optional: true - '@oxc-parser/binding-darwin-arm64@0.128.0': + '@oxc-parser/binding-darwin-arm64@0.130.0': optional: true - '@oxc-parser/binding-darwin-x64@0.128.0': + '@oxc-parser/binding-darwin-x64@0.130.0': optional: true - '@oxc-parser/binding-freebsd-x64@0.128.0': + '@oxc-parser/binding-freebsd-x64@0.130.0': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.128.0': + '@oxc-parser/binding-linux-arm-gnueabihf@0.130.0': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.128.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.130.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.128.0': + '@oxc-parser/binding-linux-arm64-gnu@0.130.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.128.0': + '@oxc-parser/binding-linux-arm64-musl@0.130.0': optional: true - '@oxc-parser/binding-linux-ppc64-gnu@0.128.0': + '@oxc-parser/binding-linux-ppc64-gnu@0.130.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.128.0': + '@oxc-parser/binding-linux-riscv64-gnu@0.130.0': optional: true - '@oxc-parser/binding-linux-riscv64-musl@0.128.0': + '@oxc-parser/binding-linux-riscv64-musl@0.130.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.128.0': + '@oxc-parser/binding-linux-s390x-gnu@0.130.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.128.0': + '@oxc-parser/binding-linux-x64-gnu@0.130.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.128.0': + '@oxc-parser/binding-linux-x64-musl@0.130.0': optional: true - '@oxc-parser/binding-openharmony-arm64@0.128.0': + '@oxc-parser/binding-openharmony-arm64@0.130.0': optional: true - '@oxc-parser/binding-wasm32-wasi@0.128.0': + '@oxc-parser/binding-wasm32-wasi@0.130.0': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.128.0': + '@oxc-parser/binding-win32-arm64-msvc@0.130.0': optional: true - '@oxc-parser/binding-win32-ia32-msvc@0.128.0': + '@oxc-parser/binding-win32-ia32-msvc@0.130.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.128.0': + '@oxc-parser/binding-win32-x64-msvc@0.130.0': optional: true - '@oxc-project/types@0.127.0': {} + '@oxc-project/types@0.130.0': {} - '@oxc-project/types@0.128.0': {} + '@oxc-project/types@0.132.0': {} '@oxc-resolver/binding-android-arm-eabi@11.19.1': optional: true @@ -7432,412 +7288,418 @@ snapshots: '@pnpm/network.ca-file': 1.0.2 config-chain: 1.1.13 + '@posthog/core@1.29.7': + dependencies: + '@posthog/types': 1.374.4 + + '@posthog/types@1.374.4': {} + '@radix-ui/number@1.1.1': {} '@radix-ui/primitive@1.1.3': {} - '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-arrow@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-collapsible@1.1.12(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-collection@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-compose-refs@1.1.2(@types/react@19.2.15)(react@19.2.6)': dependencies: react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-context@1.1.2(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-context@1.1.2(@types/react@19.2.15)(react@19.2.6)': dependencies: react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-dialog@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.15)(react@19.2.6) aria-hidden: 1.2.6 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.6) + react-remove-scroll: 2.7.2(@types/react@19.2.15)(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-direction@1.1.1(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-direction@1.1.1(@types/react@19.2.15)(react@19.2.6)': dependencies: react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-dismissable-layer@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-focus-guards@1.1.3(@types/react@19.2.15)(react@19.2.6)': dependencies: react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-focus-scope@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-id@1.1.1(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-id@1.1.1(@types/react@19.2.15)(react@19.2.6)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-previous': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.15)(react@19.2.6) aria-hidden: 1.2.6 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.6) + react-remove-scroll: 2.7.2(@types/react@19.2.15)(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-rect': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.15)(react@19.2.6) '@radix-ui/rect': 1.1.1 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-portal@1.1.9(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-presence@1.1.5(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-primitive@2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@radix-ui/react-slot': 1.2.3(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-slot': 1.2.3(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-roving-focus@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-scroll-area@1.2.10(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/number': 1.1.1 '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-slot@1.2.3(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-slot@1.2.3(@types/react@19.2.15)(react@19.2.6)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-slot@1.2.4(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-slot@1.2.4(@types/react@19.2.15)(react@19.2.6)': dependencies: - '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-tabs@1.1.13(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@radix-ui/primitive': 1.1.3 - '@radix-ui/react-context': 1.1.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-id': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-context': 1.1.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-id': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) - '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-use-callback-ref@1.1.1(@types/react@19.2.15)(react@19.2.6)': dependencies: react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-use-controllable-state@1.2.2(@types/react@19.2.15)(react@19.2.6)': dependencies: - '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-use-effect-event@0.0.2(@types/react@19.2.15)(react@19.2.6)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-use-escape-keydown@1.1.1(@types/react@19.2.15)(react@19.2.6)': dependencies: - '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-use-layout-effect@1.1.1(@types/react@19.2.15)(react@19.2.6)': dependencies: react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-use-previous@1.1.1(@types/react@19.2.15)(react@19.2.6)': dependencies: react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-use-rect@1.1.1(@types/react@19.2.15)(react@19.2.6)': dependencies: '@radix-ui/rect': 1.1.1 react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-use-size@1.1.1(@types/react@19.2.14)(react@19.2.6)': + '@radix-ui/react-use-size@1.1.1(@types/react@19.2.15)(react@19.2.6)': dependencies: - '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.14)(react@19.2.6) + '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.15)(react@19.2.6) react: 19.2.6 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@radix-ui/react-visually-hidden@1.2.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: - '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 - '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/react': 19.2.15 + '@types/react-dom': 19.2.3(@types/react@19.2.15) '@radix-ui/rect@1.1.1': {} - '@rolldown/binding-android-arm64@1.0.0-rc.17': + '@rolldown/binding-android-arm64@1.0.2': optional: true - '@rolldown/binding-darwin-arm64@1.0.0-rc.17': + '@rolldown/binding-darwin-arm64@1.0.2': optional: true - '@rolldown/binding-darwin-x64@1.0.0-rc.17': + '@rolldown/binding-darwin-x64@1.0.2': optional: true - '@rolldown/binding-freebsd-x64@1.0.0-rc.17': + '@rolldown/binding-freebsd-x64@1.0.2': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.0-rc.17': + '@rolldown/binding-linux-arm-gnueabihf@1.0.2': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.0-rc.17': + '@rolldown/binding-linux-arm64-gnu@1.0.2': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.0-rc.17': + '@rolldown/binding-linux-arm64-musl@1.0.2': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.0-rc.17': + '@rolldown/binding-linux-ppc64-gnu@1.0.2': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.0-rc.17': + '@rolldown/binding-linux-s390x-gnu@1.0.2': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.0-rc.17': + '@rolldown/binding-linux-x64-gnu@1.0.2': optional: true - '@rolldown/binding-linux-x64-musl@1.0.0-rc.17': + '@rolldown/binding-linux-x64-musl@1.0.2': optional: true - '@rolldown/binding-openharmony-arm64@1.0.0-rc.17': + '@rolldown/binding-openharmony-arm64@1.0.2': optional: true - '@rolldown/binding-wasm32-wasi@1.0.0-rc.17': + '@rolldown/binding-wasm32-wasi@1.0.2': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.0-rc.17': + '@rolldown/binding-win32-arm64-msvc@1.0.2': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.0-rc.17': + '@rolldown/binding-win32-x64-msvc@1.0.2': optional: true - '@rolldown/pluginutils@1.0.0-rc.17': {} + '@rolldown/pluginutils@1.0.1': {} '@sec-ant/readable-stream@0.4.1': {} @@ -7918,13 +7780,13 @@ snapshots: fs-extra: 11.3.5 lodash-es: 4.18.1 nerf-dart: 1.0.0 - normalize-url: 9.0.0 - npm: 11.14.1 + normalize-url: 9.0.1 + npm: 11.15.0 rc: 1.2.8 read-pkg: 10.1.0 registry-auth-token: 5.1.1 semantic-release: 25.0.3(typescript@6.0.3) - semver: 7.7.4 + semver: 7.8.0 tempy: 3.2.0 '@semantic-release/release-notes-generator@14.1.1(semantic-release@25.0.3(typescript@6.0.3))': @@ -7941,40 +7803,40 @@ snapshots: transitivePeerDependencies: - supports-color - '@shikijs/core@4.0.2': + '@shikijs/core@4.1.0': dependencies: - '@shikijs/primitive': 4.0.2 - '@shikijs/types': 4.0.2 + '@shikijs/primitive': 4.1.0 + '@shikijs/types': 4.1.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/engine-javascript@4.0.2': + '@shikijs/engine-javascript@4.1.0': dependencies: - '@shikijs/types': 4.0.2 + '@shikijs/types': 4.1.0 '@shikijs/vscode-textmate': 10.0.2 oniguruma-to-es: 4.3.6 - '@shikijs/engine-oniguruma@4.0.2': + '@shikijs/engine-oniguruma@4.1.0': dependencies: - '@shikijs/types': 4.0.2 + '@shikijs/types': 4.1.0 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/langs@4.0.2': + '@shikijs/langs@4.1.0': dependencies: - '@shikijs/types': 4.0.2 + '@shikijs/types': 4.1.0 - '@shikijs/primitive@4.0.2': + '@shikijs/primitive@4.1.0': dependencies: - '@shikijs/types': 4.0.2 + '@shikijs/types': 4.1.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 - '@shikijs/themes@4.0.2': + '@shikijs/themes@4.1.0': dependencies: - '@shikijs/types': 4.0.2 + '@shikijs/types': 4.1.0 - '@shikijs/types@4.0.2': + '@shikijs/types@4.1.0': dependencies: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -7993,251 +7855,148 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@smithy/chunked-blob-reader-native@4.2.3': + '@smithy/config-resolver@4.5.3': dependencies: - '@smithy/util-base64': 4.3.2 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/chunked-blob-reader@5.2.2': - dependencies: - tslib: 2.8.1 - - '@smithy/config-resolver@4.4.17': - dependencies: - '@smithy/node-config-provider': 4.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-config-provider': 4.2.2 - '@smithy/util-endpoints': 3.4.2 - '@smithy/util-middleware': 4.2.14 - tslib: 2.8.1 - - '@smithy/core@3.23.17': - dependencies: - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-base64': 4.3.2 - '@smithy/util-body-length-browser': 4.2.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-stream': 4.5.25 - '@smithy/util-utf8': 4.2.2 - '@smithy/uuid': 1.1.2 - tslib: 2.8.1 - - '@smithy/credential-provider-imds@4.2.14': - dependencies: - '@smithy/node-config-provider': 4.3.14 - '@smithy/property-provider': 4.2.14 - '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - tslib: 2.8.1 - - '@smithy/eventstream-codec@4.2.14': + '@smithy/core@3.24.3': dependencies: '@aws-crypto/crc32': 5.2.0 - '@smithy/types': 4.14.1 - '@smithy/util-hex-encoding': 4.2.2 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@smithy/eventstream-serde-browser@4.2.14': + '@smithy/credential-provider-imds@4.3.3': dependencies: - '@smithy/eventstream-serde-universal': 4.2.14 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@smithy/eventstream-serde-config-resolver@4.3.14': + '@smithy/eventstream-serde-browser@4.3.3': dependencies: - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/eventstream-serde-node@4.2.14': + '@smithy/eventstream-serde-config-resolver@4.4.3': dependencies: - '@smithy/eventstream-serde-universal': 4.2.14 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/eventstream-serde-universal@4.2.14': + '@smithy/eventstream-serde-node@4.3.3': dependencies: - '@smithy/eventstream-codec': 4.2.14 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/fetch-http-handler@5.3.17': + '@smithy/fetch-http-handler@5.4.3': dependencies: - '@smithy/protocol-http': 5.3.14 - '@smithy/querystring-builder': 4.2.14 - '@smithy/types': 4.14.1 - '@smithy/util-base64': 4.3.2 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 tslib: 2.8.1 - '@smithy/hash-blob-browser@4.2.15': + '@smithy/hash-blob-browser@4.3.3': dependencies: - '@smithy/chunked-blob-reader': 5.2.2 - '@smithy/chunked-blob-reader-native': 4.2.3 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/hash-node@4.2.14': + '@smithy/hash-node@4.3.3': dependencies: - '@smithy/types': 4.14.1 - '@smithy/util-buffer-from': 4.2.2 - '@smithy/util-utf8': 4.2.2 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/hash-stream-node@4.2.14': + '@smithy/hash-stream-node@4.3.3': dependencies: - '@smithy/types': 4.14.1 - '@smithy/util-utf8': 4.2.2 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/invalid-dependency@4.2.14': + '@smithy/invalid-dependency@4.3.3': dependencies: - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 tslib: 2.8.1 '@smithy/is-array-buffer@2.2.0': dependencies: tslib: 2.8.1 - '@smithy/is-array-buffer@4.2.2': + '@smithy/md5-js@4.3.3': + dependencies: + '@smithy/core': 3.24.3 + tslib: 2.8.1 + + '@smithy/middleware-content-length@4.3.3': + dependencies: + '@smithy/core': 3.24.3 + tslib: 2.8.1 + + '@smithy/middleware-endpoint@4.5.3': + dependencies: + '@smithy/core': 3.24.3 + tslib: 2.8.1 + + '@smithy/middleware-retry@4.6.3': + dependencies: + '@smithy/core': 3.24.3 + tslib: 2.8.1 + + '@smithy/middleware-serde@4.3.3': + dependencies: + '@smithy/core': 3.24.3 + tslib: 2.8.1 + + '@smithy/middleware-stack@4.3.3': + dependencies: + '@smithy/core': 3.24.3 + tslib: 2.8.1 + + '@smithy/node-config-provider@4.4.3': + dependencies: + '@smithy/core': 3.24.3 + tslib: 2.8.1 + + '@smithy/node-http-handler@4.7.3': + dependencies: + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@smithy/protocol-http@5.4.3': + dependencies: + '@smithy/core': 3.24.3 + tslib: 2.8.1 + + '@smithy/signature-v4@5.4.3': + dependencies: + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@smithy/smithy-client@4.13.3': + dependencies: + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@smithy/types@4.14.2': dependencies: tslib: 2.8.1 - '@smithy/md5-js@4.2.14': + '@smithy/url-parser@4.3.3': dependencies: - '@smithy/types': 4.14.1 - '@smithy/util-utf8': 4.2.2 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/middleware-content-length@4.2.14': + '@smithy/util-base64@4.4.3': dependencies: - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/middleware-endpoint@4.4.32': + '@smithy/util-body-length-browser@4.3.3': dependencies: - '@smithy/core': 3.23.17 - '@smithy/middleware-serde': 4.2.20 - '@smithy/node-config-provider': 4.3.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 - '@smithy/url-parser': 4.2.14 - '@smithy/util-middleware': 4.2.14 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/middleware-retry@4.5.7': - dependencies: - '@smithy/core': 3.23.17 - '@smithy/node-config-provider': 4.3.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/service-error-classification': 4.3.1 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-retry': 4.3.6 - '@smithy/uuid': 1.1.2 - tslib: 2.8.1 - - '@smithy/middleware-serde@4.2.20': - dependencies: - '@smithy/core': 3.23.17 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/middleware-stack@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/node-config-provider@4.3.14': - dependencies: - '@smithy/property-provider': 4.2.14 - '@smithy/shared-ini-file-loader': 4.4.9 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/node-http-handler@4.6.1': - dependencies: - '@smithy/protocol-http': 5.3.14 - '@smithy/querystring-builder': 4.2.14 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/property-provider@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/protocol-http@5.3.14': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/querystring-builder@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - '@smithy/util-uri-escape': 4.2.2 - tslib: 2.8.1 - - '@smithy/querystring-parser@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/service-error-classification@4.3.1': - dependencies: - '@smithy/types': 4.14.1 - - '@smithy/shared-ini-file-loader@4.4.9': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/signature-v4@5.3.14': - dependencies: - '@smithy/is-array-buffer': 4.2.2 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-hex-encoding': 4.2.2 - '@smithy/util-middleware': 4.2.14 - '@smithy/util-uri-escape': 4.2.2 - '@smithy/util-utf8': 4.2.2 - tslib: 2.8.1 - - '@smithy/smithy-client@4.12.13': - dependencies: - '@smithy/core': 3.23.17 - '@smithy/middleware-endpoint': 4.4.32 - '@smithy/middleware-stack': 4.2.14 - '@smithy/protocol-http': 5.3.14 - '@smithy/types': 4.14.1 - '@smithy/util-stream': 4.5.25 - tslib: 2.8.1 - - '@smithy/types@4.14.1': - dependencies: - tslib: 2.8.1 - - '@smithy/url-parser@4.2.14': - dependencies: - '@smithy/querystring-parser': 4.2.14 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/util-base64@4.3.2': - dependencies: - '@smithy/util-buffer-from': 4.2.2 - '@smithy/util-utf8': 4.2.2 - tslib: 2.8.1 - - '@smithy/util-body-length-browser@4.2.2': - dependencies: - tslib: 2.8.1 - - '@smithy/util-body-length-node@4.2.3': + '@smithy/util-body-length-node@4.3.3': dependencies: + '@smithy/core': 3.24.3 tslib: 2.8.1 '@smithy/util-buffer-from@2.2.0': @@ -8245,66 +8004,34 @@ snapshots: '@smithy/is-array-buffer': 2.2.0 tslib: 2.8.1 - '@smithy/util-buffer-from@4.2.2': + '@smithy/util-defaults-mode-browser@4.4.3': dependencies: - '@smithy/is-array-buffer': 4.2.2 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/util-config-provider@4.2.2': + '@smithy/util-defaults-mode-node@4.3.3': dependencies: + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/util-defaults-mode-browser@4.3.49': + '@smithy/util-endpoints@3.5.3': dependencies: - '@smithy/property-provider': 4.2.14 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/util-defaults-mode-node@4.2.54': + '@smithy/util-middleware@4.3.3': dependencies: - '@smithy/config-resolver': 4.4.17 - '@smithy/credential-provider-imds': 4.2.14 - '@smithy/node-config-provider': 4.3.14 - '@smithy/property-provider': 4.2.14 - '@smithy/smithy-client': 4.12.13 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/util-endpoints@3.4.2': + '@smithy/util-retry@4.4.3': dependencies: - '@smithy/node-config-provider': 4.3.14 - '@smithy/types': 4.14.1 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/util-hex-encoding@4.2.2': - dependencies: - tslib: 2.8.1 - - '@smithy/util-middleware@4.2.14': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/util-retry@4.3.6': - dependencies: - '@smithy/service-error-classification': 4.3.1 - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/util-stream@4.5.25': - dependencies: - '@smithy/fetch-http-handler': 5.3.17 - '@smithy/node-http-handler': 4.6.1 - '@smithy/types': 4.14.1 - '@smithy/util-base64': 4.3.2 - '@smithy/util-buffer-from': 4.2.2 - '@smithy/util-hex-encoding': 4.2.2 - '@smithy/util-utf8': 4.2.2 - tslib: 2.8.1 - - '@smithy/util-uri-escape@4.2.2': + '@smithy/util-stream@4.6.3': dependencies: + '@smithy/core': 3.24.3 tslib: 2.8.1 '@smithy/util-utf8@2.3.0': @@ -8312,18 +8039,14 @@ snapshots: '@smithy/util-buffer-from': 2.2.0 tslib: 2.8.1 - '@smithy/util-utf8@4.2.2': + '@smithy/util-utf8@4.3.3': dependencies: - '@smithy/util-buffer-from': 4.2.2 + '@smithy/core': 3.24.3 tslib: 2.8.1 - '@smithy/util-waiter@4.3.0': - dependencies: - '@smithy/types': 4.14.1 - tslib: 2.8.1 - - '@smithy/uuid@1.1.2': + '@smithy/util-waiter@4.4.3': dependencies: + '@smithy/core': 3.24.3 tslib: 2.8.1 '@so-ric/colorspace@1.1.6': @@ -8331,6 +8054,8 @@ snapshots: color: 5.0.3 text-hex: 1.0.0 + '@stablelib/base64@1.0.1': {} + '@standard-schema/spec@1.1.0': {} '@swc/helpers@0.5.15': @@ -8340,7 +8065,7 @@ snapshots: '@tailwindcss/node@4.3.0': dependencies: '@jridgewell/remapping': 2.3.5 - enhanced-resolve: 5.21.2 + enhanced-resolve: 5.21.6 jiti: 2.7.0 lightningcss: 1.32.0 magic-string: 0.30.21 @@ -8416,14 +8141,14 @@ snapshots: '@tediousjs/connection-string@1.1.0': {} - '@tybys/wasm-util@0.10.1': + '@tybys/wasm-util@0.10.2': dependencies: tslib: 2.8.1 optional: true '@types/better-sqlite3@7.6.13': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/chai@5.2.3': dependencies: @@ -8459,9 +8184,9 @@ snapshots: '@types/estree-jsx@1.0.5': dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 - '@types/estree@1.0.8': {} + '@types/estree@1.0.9': {} '@types/hast@3.0.4': dependencies: @@ -8477,14 +8202,14 @@ snapshots: '@types/mssql@12.3.0(@azure/core-client@1.10.1)': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 tarn: 3.0.2 tedious: 19.2.1(@azure/core-client@1.10.1) transitivePeerDependencies: - '@azure/core-client' - supports-color - '@types/node@24.12.2': + '@types/node@24.12.4': dependencies: undici-types: 7.16.0 @@ -8492,21 +8217,21 @@ snapshots: '@types/pg@8.20.0': dependencies: - '@types/node': 24.12.2 - pg-protocol: 1.13.0 + '@types/node': 24.12.4 + pg-protocol: 1.14.0 pg-types: 2.2.0 - '@types/react-dom@19.2.3(@types/react@19.2.14)': + '@types/react-dom@19.2.3(@types/react@19.2.15)': dependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - '@types/react@19.2.14': + '@types/react@19.2.15': dependencies: csstype: 3.2.3 '@types/readable-stream@4.0.23': dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 '@types/triple-beam@1.3.5': {} @@ -8526,68 +8251,68 @@ snapshots: '@vercel/oidc@3.2.0': {} - '@vitest/coverage-v8@4.1.6(vitest@4.1.6)': + '@vitest/coverage-v8@4.1.7(vitest@4.1.7)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.6 + '@vitest/utils': 4.1.7 ast-v8-to-istanbul: 1.0.0 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 - magicast: 0.5.2 + magicast: 0.5.3 obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.6(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.6)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)) + vitest: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)) - '@vitest/expect@4.1.6': + '@vitest/expect@4.1.7': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.6 - '@vitest/utils': 4.1.6 + '@vitest/spy': 4.1.7 + '@vitest/utils': 4.1.7 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.6(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0))': + '@vitest/mocker@4.1.7(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0))': dependencies: - '@vitest/spy': 4.1.6 + '@vitest/spy': 4.1.7 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0) + vite: 8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0) - '@vitest/pretty-format@4.1.6': + '@vitest/pretty-format@4.1.7': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.6': + '@vitest/runner@4.1.7': dependencies: - '@vitest/utils': 4.1.6 + '@vitest/utils': 4.1.7 pathe: 2.0.3 - '@vitest/snapshot@4.1.6': + '@vitest/snapshot@4.1.7': dependencies: - '@vitest/pretty-format': 4.1.6 - '@vitest/utils': 4.1.6 + '@vitest/pretty-format': 4.1.7 + '@vitest/utils': 4.1.7 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.6': {} + '@vitest/spy@4.1.7': {} - '@vitest/utils@4.1.6': + '@vitest/utils@4.1.7': dependencies: - '@vitest/pretty-format': 4.1.6 + '@vitest/pretty-format': 4.1.7 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 - '@xyflow/react@12.10.2(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + '@xyflow/react@12.10.2(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@xyflow/system': 0.0.76 classcat: 5.0.5 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - zustand: 4.5.7(@types/react@19.2.14)(react@19.2.6) + zustand: 4.5.7(@types/react@19.2.15)(react@19.2.6) transitivePeerDependencies: - '@types/react' - immer @@ -8619,6 +8344,12 @@ snapshots: acorn@8.16.0: {} + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + agent-base@7.1.4: {} agent-base@9.0.0: {} @@ -8633,12 +8364,12 @@ snapshots: clean-stack: 5.3.0 indent-string: 5.0.0 - ai@6.0.180(zod@4.4.3): + ai@6.0.188(zod@4.4.3): dependencies: - '@ai-sdk/gateway': 3.0.114(zod@4.4.3) + '@ai-sdk/gateway': 3.0.118(zod@4.4.3) '@ai-sdk/provider': 3.0.10 '@ai-sdk/provider-utils': 4.0.27(zod@4.4.3) - '@opentelemetry/api': 1.9.0 + '@opentelemetry/api': 1.9.1 zod: 4.4.3 ajv-formats@3.0.1(ajv@8.20.0): @@ -8720,13 +8451,15 @@ snapshots: aws-ssl-profiles@1.1.2: {} - axios@1.15.2: + axios@1.16.1: dependencies: follow-redirects: 1.16.0 form-data: 4.0.5 + https-proxy-agent: 5.0.1 proxy-from-env: 2.1.0 transitivePeerDependencies: - debug + - supports-color bail@2.0.2: {} @@ -8736,7 +8469,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.10.29: {} + baseline-browser-mapping@2.10.31: {} before-after-hook@4.0.0: {} @@ -8780,9 +8513,9 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.7.2 on-finished: 2.4.1 - qs: 6.15.1 + qs: 6.15.2 raw-body: 3.0.2 - type-is: 2.0.1 + type-is: 2.1.0 transitivePeerDependencies: - supports-color @@ -8833,7 +8566,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001792: {} + caniuse-lite@1.0.30001793: {} ccount@2.0.1: {} @@ -8917,7 +8650,7 @@ snapshots: cliui@9.0.1: dependencies: string-width: 7.2.0 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrap-ansi: 9.0.2 clsx@2.1.1: {} @@ -8999,7 +8732,7 @@ snapshots: conventional-commits-filter: 5.0.0 handlebars: 4.7.9 meow: 13.2.0 - semver: 7.7.4 + semver: 7.8.0 conventional-commits-filter@5.0.0: {} @@ -9168,7 +8901,7 @@ snapshots: dependencies: once: 1.4.0 - enhanced-resolve@5.21.2: + enhanced-resolve@5.21.6: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -9262,7 +8995,7 @@ snapshots: estree-util-attach-comments@3.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 estree-util-build-jsx@3.0.1: dependencies: @@ -9275,7 +9008,7 @@ snapshots: estree-util-scope@1.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 devlop: 1.1.0 estree-util-to-js@2.0.0: @@ -9286,7 +9019,7 @@ snapshots: estree-util-value-to-estree@3.5.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 estree-util-visit@2.0.0: dependencies: @@ -9295,7 +9028,7 @@ snapshots: estree-walker@3.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 etag@1.8.1: {} @@ -9356,7 +9089,7 @@ snapshots: expect-type@1.3.0: {} - express-rate-limit@8.4.1(express@5.2.1): + express-rate-limit@8.5.2(express@5.2.1): dependencies: express: 5.2.1 ip-address: 10.1.1 @@ -9383,13 +9116,13 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.15.1 + qs: 6.15.2 range-parser: 1.2.1 router: 2.2.0 send: 1.2.1 serve-static: 2.2.1 statuses: 2.0.2 - type-is: 2.0.1 + type-is: 2.1.0 vary: 1.1.2 transitivePeerDependencies: - supports-color @@ -9400,6 +9133,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-sha256@1.3.0: {} + fast-string-truncated-width@3.0.3: {} fast-string-width@3.0.2: @@ -9408,7 +9143,7 @@ snapshots: fast-uri@3.1.2: {} - fast-wrap-ansi@0.2.0: + fast-wrap-ansi@0.2.2: dependencies: fast-string-width: 3.0.2 @@ -9416,12 +9151,20 @@ snapshots: dependencies: path-expression-matcher: 1.5.0 - fast-xml-parser@5.7.2: + fast-xml-parser@5.7.3: dependencies: '@nodable/entities': 2.1.0 fast-xml-builder: 1.1.7 path-expression-matcher: 1.5.0 - strnum: 2.2.3 + strnum: 2.3.0 + + fast-xml-parser@5.8.0: + dependencies: + '@nodable/entities': 2.1.0 + fast-xml-builder: 1.1.7 + path-expression-matcher: 1.5.0 + strnum: 2.3.0 + xml-naming: 0.1.0 fastest-levenshtein@1.0.16: {} @@ -9440,7 +9183,7 @@ snapshots: node-domexception: 1.0.0 web-streams-polyfill: 3.3.3 - fflate@0.8.2: {} + fflate@0.8.3: {} figures@2.0.0: dependencies: @@ -9500,10 +9243,10 @@ snapshots: forwarded@0.2.0: {} - framer-motion@12.38.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + framer-motion@12.40.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: - motion-dom: 12.38.0 - motion-utils: 12.36.0 + motion-dom: 12.40.0 + motion-utils: 12.39.0 tslib: 2.8.1 optionalDependencies: react: 19.2.6 @@ -9524,7 +9267,7 @@ snapshots: fsevents@2.3.3: optional: true - fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@1.14.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3): + fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3): dependencies: '@orama/orama': 3.1.18 estree-util-value-to-estree: 3.5.0 @@ -9538,7 +9281,7 @@ snapshots: remark-gfm: 4.0.1 remark-rehype: 11.1.2 scroll-into-view-if-needed: 3.1.0 - shiki: 4.0.2 + shiki: 4.1.0 tinyglobby: 0.2.16 unified: 11.0.5 unist-util-visit: 5.1.0 @@ -9548,23 +9291,23 @@ snapshots: '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - '@types/react': 19.2.14 - lucide-react: 1.14.0(react@19.2.6) - next: 16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/react': 19.2.15 + lucide-react: 1.16.0(react@19.2.6) + next: 16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) zod: 4.4.3 transitivePeerDependencies: - supports-color - fumadocs-mdx@15.0.4(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.14)(fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@1.14.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)): + fumadocs-mdx@15.0.7(@types/mdast@4.0.4)(@types/mdx@2.0.13)(@types/react@19.2.15)(fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)(rolldown@1.0.2)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)): dependencies: '@mdx-js/mdx': 3.1.1 '@standard-schema/spec': 1.1.0 chokidar: 5.0.0 esbuild: 0.28.0 estree-util-value-to-estree: 3.5.0 - fumadocs-core: 16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@1.14.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3) + fumadocs-core: 16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3) js-yaml: 4.1.1 mdast-util-mdx: 3.0.0 picocolors: 1.1.1 @@ -9579,43 +9322,44 @@ snapshots: optionalDependencies: '@types/mdast': 4.0.4 '@types/mdx': 2.0.13 - '@types/react': 19.2.14 - next: 16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/react': 19.2.15 + next: 16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: 19.2.6 - vite: 8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0) + rolldown: 1.0.2 + vite: 8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0) transitivePeerDependencies: - supports-color - fumadocs-ui@16.8.10(@tailwindcss/oxide@4.3.0)(@types/mdx@2.0.13)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@1.14.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tailwindcss@4.3.0): + fumadocs-ui@16.8.10(@tailwindcss/oxide@4.3.0)(@types/mdx@2.0.13)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tailwindcss@4.3.0): dependencies: '@fumadocs/tailwind': 0.0.5(@tailwindcss/oxide@4.3.0)(tailwindcss@4.3.0) - '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-direction': 1.1.1(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@radix-ui/react-slot': 1.2.4(@types/react@19.2.14)(react@19.2.6) - '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-direction': 1.1.1(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@radix-ui/react-slot': 1.2.4(@types/react@19.2.15)(react@19.2.6) + '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) class-variance-authority: 0.7.1 - fumadocs-core: 16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.14)(lucide-react@1.14.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3) - lucide-react: 1.14.0(react@19.2.6) - motion: 12.38.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + fumadocs-core: 16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3) + lucide-react: 1.16.0(react@19.2.6) + motion: 12.40.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) next-themes: 0.4.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - react-remove-scroll: 2.7.2(@types/react@19.2.14)(react@19.2.6) + react-remove-scroll: 2.7.2(@types/react@19.2.15)(react@19.2.6) rehype-raw: 7.0.0 scroll-into-view-if-needed: 3.1.0 - shiki: 4.0.2 + shiki: 4.1.0 tailwind-merge: 3.6.0 unist-util-visit: 5.1.0 optionalDependencies: '@types/mdx': 2.0.13 - '@types/react': 19.2.14 - next: 16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/react': 19.2.15 + next: 16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) transitivePeerDependencies: - '@emotion/is-prop-valid' - '@tailwindcss/oxide' @@ -9650,7 +9394,7 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.5.0: {} + get-east-asian-width@1.6.0: {} get-intrinsic@1.3.0: dependencies: @@ -9782,7 +9526,7 @@ snapshots: hast-util-to-estree@3.1.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 comma-separated-tokens: 2.0.3 @@ -9817,7 +9561,7 @@ snapshots: hast-util-to-jsx-runtime@2.3.6: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/hast': 3.0.4 '@types/unist': 3.0.3 comma-separated-tokens: 2.0.3 @@ -9873,7 +9617,7 @@ snapshots: hosted-git-info@9.0.3: dependencies: - lru-cache: 11.3.6 + lru-cache: 11.5.0 html-entities@2.6.0: {} @@ -9903,6 +9647,13 @@ snapshots: transitivePeerDependencies: - supports-color + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 @@ -9960,11 +9711,11 @@ snapshots: ini@5.0.0: {} - ink-testing-library@4.0.0(@types/react@19.2.14): + ink-testing-library@4.0.0(@types/react@19.2.15): optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - ink@7.0.2(@types/react@19.2.14)(react@19.2.6): + ink@7.0.3(@types/react@19.2.15)(react@19.2.6): dependencies: '@alcalzone/ansi-tokenize': 0.3.0 ansi-escapes: 7.3.0 @@ -9993,7 +9744,7 @@ snapshots: ws: 8.20.1 yoga-layout: 3.2.1 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 transitivePeerDependencies: - bufferutil - utf-8-validate @@ -10023,7 +9774,7 @@ snapshots: is-fullwidth-code-point@5.1.0: dependencies: - get-east-asian-width: 1.5.0 + get-east-asian-width: 1.6.0 is-hexadecimal@2.0.1: {} @@ -10088,7 +9839,7 @@ snapshots: jiti@2.7.0: {} - jose@6.2.2: {} + jose@6.2.3: {} js-md4@0.3.2: {} @@ -10138,7 +9889,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.7.4 + semver: 7.8.0 jwa@2.0.1: dependencies: @@ -10151,14 +9902,14 @@ snapshots: jwa: 2.0.1 safe-buffer: 5.2.1 - knip@6.12.2(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): + knip@6.14.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): dependencies: fdir: 6.5.0(picomatch@4.0.4) formatly: 0.3.0 get-tsconfig: 4.14.0 jiti: 2.7.0 minimist: 1.2.8 - oxc-parser: 0.128.0 + oxc-parser: 0.130.0 oxc-resolver: 11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) picomatch: 4.0.4 smol-toml: 1.6.1 @@ -10284,11 +10035,11 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.3.6: {} + lru-cache@11.5.0: {} lru.min@1.1.4: {} - lucide-react@1.14.0(react@19.2.6): + lucide-react@1.16.0(react@19.2.6): dependencies: react: 19.2.6 @@ -10296,7 +10047,7 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - magicast@0.5.2: + magicast@0.5.3: dependencies: '@babel/parser': 7.29.3 '@babel/types': 7.29.0 @@ -10310,7 +10061,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.7.4 + semver: 7.8.0 markdown-extensions@2.0.0: {} @@ -10581,7 +10332,7 @@ snapshots: micromark-extension-mdx-expression@3.0.1: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 devlop: 1.1.0 micromark-factory-mdx-expression: 2.0.3 micromark-factory-space: 2.0.1 @@ -10592,7 +10343,7 @@ snapshots: micromark-extension-mdx-jsx@3.0.2: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 micromark-factory-mdx-expression: 2.0.3 @@ -10609,7 +10360,7 @@ snapshots: micromark-extension-mdxjs-esm@3.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 micromark-util-character: 2.1.1 @@ -10645,7 +10396,7 @@ snapshots: micromark-factory-mdx-expression@2.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 devlop: 1.1.0 micromark-factory-space: 2.0.1 micromark-util-character: 2.1.1 @@ -10709,7 +10460,7 @@ snapshots: micromark-util-events-to-acorn@2.0.3: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/unist': 3.0.3 devlop: 1.1.0 estree-util-visit: 2.0.0 @@ -10811,15 +10562,15 @@ snapshots: moment@2.30.1: {} - motion-dom@12.38.0: + motion-dom@12.40.0: dependencies: - motion-utils: 12.36.0 + motion-utils: 12.39.0 - motion-utils@12.36.0: {} + motion-utils@12.39.0: {} - motion@12.38.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + motion@12.40.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: - framer-motion: 12.38.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + framer-motion: 12.40.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) tslib: 2.8.1 optionalDependencies: react: 19.2.6 @@ -10827,7 +10578,7 @@ snapshots: ms@2.1.3: {} - mssql@12.5.2(@azure/core-client@1.10.1): + mssql@12.5.4(@azure/core-client@1.10.1): dependencies: '@tediousjs/connection-string': 1.1.0 commander: 11.1.0 @@ -10838,9 +10589,9 @@ snapshots: - '@azure/core-client' - supports-color - mysql2@3.22.3(@types/node@24.12.2): + mysql2@3.22.3(@types/node@24.12.4): dependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 aws-ssl-profiles: 1.1.2 denque: 2.1.0 generate-function: 2.3.1 @@ -10860,7 +10611,7 @@ snapshots: dependencies: lru.min: 1.1.4 - nanoid@3.3.11: {} + nanoid@3.3.12: {} napi-build-utils@2.0.0: {} @@ -10877,12 +10628,12 @@ snapshots: react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - next@16.2.6(@opentelemetry/api@1.9.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: '@next/env': 16.2.6 '@swc/helpers': 0.5.15 - baseline-browser-mapping: 2.10.29 - caniuse-lite: 1.0.30001792 + baseline-browser-mapping: 2.10.31 + caniuse-lite: 1.0.30001793 postcss: 8.5.10 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) @@ -10896,15 +10647,15 @@ snapshots: '@next/swc-linux-x64-musl': 16.2.6 '@next/swc-win32-arm64-msvc': 16.2.6 '@next/swc-win32-x64-msvc': 16.2.6 - '@opentelemetry/api': 1.9.0 + '@opentelemetry/api': 1.9.1 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros - node-abi@3.89.0: + node-abi@3.92.0: dependencies: - semver: 7.7.4 + semver: 7.8.0 node-domexception@1.0.0: {} @@ -10924,16 +10675,16 @@ snapshots: normalize-package-data@6.0.2: dependencies: hosted-git-info: 7.0.2 - semver: 7.7.4 + semver: 7.8.0 validate-npm-package-license: 3.0.4 normalize-package-data@8.0.0: dependencies: hosted-git-info: 9.0.3 - semver: 7.7.4 + semver: 7.8.0 validate-npm-package-license: 3.0.4 - normalize-url@9.0.0: {} + normalize-url@9.0.1: {} npm-run-path@4.0.1: dependencies: @@ -10948,7 +10699,7 @@ snapshots: path-key: 4.0.0 unicorn-magic: 0.3.0 - npm@11.14.1: {} + npm@11.15.0: {} oauth4webapi@3.8.6: {} @@ -10998,35 +10749,35 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - openai@6.37.0(ws@8.20.1)(zod@4.4.3): + openai@6.38.0(ws@8.20.1)(zod@4.4.3): optionalDependencies: ws: 8.20.1 zod: 4.4.3 - oxc-parser@0.128.0: + oxc-parser@0.130.0: dependencies: - '@oxc-project/types': 0.128.0 + '@oxc-project/types': 0.130.0 optionalDependencies: - '@oxc-parser/binding-android-arm-eabi': 0.128.0 - '@oxc-parser/binding-android-arm64': 0.128.0 - '@oxc-parser/binding-darwin-arm64': 0.128.0 - '@oxc-parser/binding-darwin-x64': 0.128.0 - '@oxc-parser/binding-freebsd-x64': 0.128.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.128.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.128.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.128.0 - '@oxc-parser/binding-linux-arm64-musl': 0.128.0 - '@oxc-parser/binding-linux-ppc64-gnu': 0.128.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.128.0 - '@oxc-parser/binding-linux-riscv64-musl': 0.128.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.128.0 - '@oxc-parser/binding-linux-x64-gnu': 0.128.0 - '@oxc-parser/binding-linux-x64-musl': 0.128.0 - '@oxc-parser/binding-openharmony-arm64': 0.128.0 - '@oxc-parser/binding-wasm32-wasi': 0.128.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.128.0 - '@oxc-parser/binding-win32-ia32-msvc': 0.128.0 - '@oxc-parser/binding-win32-x64-msvc': 0.128.0 + '@oxc-parser/binding-android-arm-eabi': 0.130.0 + '@oxc-parser/binding-android-arm64': 0.130.0 + '@oxc-parser/binding-darwin-arm64': 0.130.0 + '@oxc-parser/binding-darwin-x64': 0.130.0 + '@oxc-parser/binding-freebsd-x64': 0.130.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.130.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.130.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.130.0 + '@oxc-parser/binding-linux-arm64-musl': 0.130.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.130.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.130.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.130.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.130.0 + '@oxc-parser/binding-linux-x64-gnu': 0.130.0 + '@oxc-parser/binding-linux-x64-musl': 0.130.0 + '@oxc-parser/binding-openharmony-arm64': 0.130.0 + '@oxc-parser/binding-wasm32-wasi': 0.130.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.130.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.130.0 + '@oxc-parser/binding-win32-x64-msvc': 0.130.0 oxc-resolver@11.19.1(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0): optionalDependencies: @@ -11156,18 +10907,18 @@ snapshots: pegjs@0.10.0: {} - pg-cloudflare@1.3.0: + pg-cloudflare@1.4.0: optional: true - pg-connection-string@2.12.0: {} + pg-connection-string@2.13.0: {} pg-int8@1.0.1: {} - pg-pool@3.13.0(pg@8.20.0): + pg-pool@3.14.0(pg@8.21.0): dependencies: - pg: 8.20.0 + pg: 8.21.0 - pg-protocol@1.13.0: {} + pg-protocol@1.14.0: {} pg-types@2.2.0: dependencies: @@ -11177,15 +10928,15 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 - pg@8.20.0: + pg@8.21.0: dependencies: - pg-connection-string: 2.12.0 - pg-pool: 3.13.0(pg@8.20.0) - pg-protocol: 1.13.0 + pg-connection-string: 2.13.0 + pg-pool: 3.14.0(pg@8.21.0) + pg-protocol: 1.14.0 pg-types: 2.2.0 pgpass: 1.0.5 optionalDependencies: - pg-cloudflare: 1.3.0 + pg-cloudflare: 1.4.0 pgpass@1.0.5: dependencies: @@ -11208,7 +10959,7 @@ snapshots: postcss@8.5.10: dependencies: - nanoid: 3.3.11 + nanoid: 3.3.12 picocolors: 1.1.1 source-map-js: 1.2.1 @@ -11222,7 +10973,9 @@ snapshots: dependencies: xtend: 4.0.2 - posthog-node@5.0.0: {} + posthog-node@5.34.9: + dependencies: + '@posthog/core': 1.29.7 prebuild-install@7.1.3: dependencies: @@ -11232,7 +10985,7 @@ snapshots: minimist: 1.2.8 mkdirp-classic: 0.5.3 napi-build-utils: 2.0.0 - node-abi: 3.89.0 + node-abi: 3.92.0 pump: 3.0.4 rc: 1.2.8 simple-get: 4.0.1 @@ -11263,7 +11016,7 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 - qs@6.15.1: + qs@6.15.2: dependencies: side-channel: 1.1.0 @@ -11293,32 +11046,32 @@ snapshots: react: 19.2.6 scheduler: 0.27.0 - react-remove-scroll-bar@2.3.8(@types/react@19.2.14)(react@19.2.6): + react-remove-scroll-bar@2.3.8(@types/react@19.2.15)(react@19.2.6): dependencies: react: 19.2.6 - react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.6) + react-style-singleton: 2.2.3(@types/react@19.2.15)(react@19.2.6) tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - react-remove-scroll@2.7.2(@types/react@19.2.14)(react@19.2.6): + react-remove-scroll@2.7.2(@types/react@19.2.15)(react@19.2.6): dependencies: react: 19.2.6 - react-remove-scroll-bar: 2.3.8(@types/react@19.2.14)(react@19.2.6) - react-style-singleton: 2.2.3(@types/react@19.2.14)(react@19.2.6) + react-remove-scroll-bar: 2.3.8(@types/react@19.2.15)(react@19.2.6) + react-style-singleton: 2.2.3(@types/react@19.2.15)(react@19.2.6) tslib: 2.8.1 - use-callback-ref: 1.3.3(@types/react@19.2.14)(react@19.2.6) - use-sidecar: 1.1.3(@types/react@19.2.14)(react@19.2.6) + use-callback-ref: 1.3.3(@types/react@19.2.15)(react@19.2.6) + use-sidecar: 1.1.3(@types/react@19.2.15)(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.6): + react-style-singleton@2.2.3(@types/react@19.2.15)(react@19.2.6): dependencies: get-nonce: 1.0.1 react: 19.2.6 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 react@19.2.6: {} @@ -11378,7 +11131,7 @@ snapshots: recma-build-jsx@1.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 estree-util-build-jsx: 3.0.1 vfile: 6.0.3 @@ -11393,14 +11146,14 @@ snapshots: recma-parse@1.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 esast-util-from-js: 2.0.1 unified: 11.0.5 vfile: 6.0.3 recma-stringify@1.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 estree-util-to-js: 2.0.0 unified: 11.0.5 vfile: 6.0.3 @@ -11427,7 +11180,7 @@ snapshots: rehype-recma@1.0.0: dependencies: - '@types/estree': 1.0.8 + '@types/estree': 1.0.9 '@types/hast': 3.0.4 hast-util-to-estree: 3.1.3 transitivePeerDependencies: @@ -11505,26 +11258,26 @@ snapshots: transitivePeerDependencies: - supports-color - rolldown@1.0.0-rc.17: + rolldown@1.0.2: dependencies: - '@oxc-project/types': 0.127.0 - '@rolldown/pluginutils': 1.0.0-rc.17 + '@oxc-project/types': 0.132.0 + '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.0-rc.17 - '@rolldown/binding-darwin-arm64': 1.0.0-rc.17 - '@rolldown/binding-darwin-x64': 1.0.0-rc.17 - '@rolldown/binding-freebsd-x64': 1.0.0-rc.17 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.0-rc.17 - '@rolldown/binding-linux-arm64-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-arm64-musl': 1.0.0-rc.17 - '@rolldown/binding-linux-ppc64-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-s390x-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-x64-gnu': 1.0.0-rc.17 - '@rolldown/binding-linux-x64-musl': 1.0.0-rc.17 - '@rolldown/binding-openharmony-arm64': 1.0.0-rc.17 - '@rolldown/binding-wasm32-wasi': 1.0.0-rc.17 - '@rolldown/binding-win32-arm64-msvc': 1.0.0-rc.17 - '@rolldown/binding-win32-x64-msvc': 1.0.0-rc.17 + '@rolldown/binding-android-arm64': 1.0.2 + '@rolldown/binding-darwin-arm64': 1.0.2 + '@rolldown/binding-darwin-x64': 1.0.2 + '@rolldown/binding-freebsd-x64': 1.0.2 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.2 + '@rolldown/binding-linux-arm64-gnu': 1.0.2 + '@rolldown/binding-linux-arm64-musl': 1.0.2 + '@rolldown/binding-linux-ppc64-gnu': 1.0.2 + '@rolldown/binding-linux-s390x-gnu': 1.0.2 + '@rolldown/binding-linux-x64-gnu': 1.0.2 + '@rolldown/binding-linux-x64-musl': 1.0.2 + '@rolldown/binding-openharmony-arm64': 1.0.2 + '@rolldown/binding-wasm32-wasi': 1.0.2 + '@rolldown/binding-win32-arm64-msvc': 1.0.2 + '@rolldown/binding-win32-x64-msvc': 1.0.2 router@2.2.0: dependencies: @@ -11579,7 +11332,7 @@ snapshots: p-reduce: 3.0.0 read-package-up: 12.0.0 resolve-from: 5.0.0 - semver: 7.7.4 + semver: 7.8.0 signale: 1.4.0 yargs: 18.0.0 transitivePeerDependencies: @@ -11588,7 +11341,7 @@ snapshots: semver-regex@4.0.5: {} - semver@7.7.4: {} + semver@7.8.0: {} send@1.2.1: dependencies: @@ -11621,7 +11374,7 @@ snapshots: dependencies: '@img/colour': 1.1.0 detect-libc: 2.1.2 - semver: 7.7.4 + semver: 7.8.0 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.5 '@img/sharp-darwin-x64': 0.34.5 @@ -11655,14 +11408,14 @@ snapshots: shebang-regex@3.0.0: {} - shiki@4.0.2: + shiki@4.1.0: dependencies: - '@shikijs/core': 4.0.2 - '@shikijs/engine-javascript': 4.0.2 - '@shikijs/engine-oniguruma': 4.0.2 - '@shikijs/langs': 4.0.2 - '@shikijs/themes': 4.0.2 - '@shikijs/types': 4.0.2 + '@shikijs/core': 4.1.0 + '@shikijs/engine-javascript': 4.1.0 + '@shikijs/engine-oniguruma': 4.1.0 + '@shikijs/langs': 4.1.0 + '@shikijs/themes': 4.1.0 + '@shikijs/types': 4.1.0 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -11739,27 +11492,27 @@ snapshots: smol-toml@1.6.1: {} - snowflake-sdk@2.4.1(asn1.js@5.4.1): + snowflake-sdk@2.4.2(asn1.js@5.4.1): dependencies: '@aws-crypto/sha256-js': 5.2.0 '@aws-sdk/client-s3': 3.1045.0 '@aws-sdk/client-sts': 3.1045.0 - '@aws-sdk/credential-provider-node': 3.972.39 + '@aws-sdk/credential-provider-node': 3.972.43 '@aws-sdk/ec2-metadata-service': 3.1045.0 '@azure/identity': 4.13.1 '@azure/storage-blob': 12.26.0 - '@smithy/node-http-handler': 4.6.1 - '@smithy/protocol-http': 5.3.14 - '@smithy/signature-v4': 5.3.14 + '@smithy/node-http-handler': 4.7.3 + '@smithy/protocol-http': 5.4.3 + '@smithy/signature-v4': 5.4.3 '@techteamer/ocsp': 1.0.1 asn1.js: 5.4.1 asn1.js-rfc2560: 5.0.1(asn1.js@5.4.1) asn1.js-rfc5280: 3.0.0 - axios: 1.15.2 + axios: 1.16.1 big-integer: 1.6.52 bignumber.js: 9.3.1 expand-tilde: 2.0.2 - fast-xml-parser: 5.7.2 + fast-xml-parser: 5.8.0 fastest-levenshtein: 1.0.16 generic-pool: 3.9.0 google-auth-library: 10.6.2 @@ -11774,7 +11527,6 @@ snapshots: toml: 3.0.0 winston: 3.19.0 transitivePeerDependencies: - - aws-crt - debug - supports-color @@ -11820,6 +11572,11 @@ snapshots: stackback@0.0.2: {} + standardwebhooks@1.0.0: + dependencies: + '@stablelib/base64': 1.0.1 + fast-sha256: 1.3.0 + statuses@2.0.2: {} std-env@4.1.0: {} @@ -11844,13 +11601,13 @@ snapshots: string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.5.0 - strip-ansi: 7.1.2 + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 string-width@8.2.1: dependencies: - get-east-asian-width: 1.5.0 - strip-ansi: 7.1.2 + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 string_decoder@1.1.1: dependencies: @@ -11869,7 +11626,7 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.2: + strip-ansi@7.2.0: dependencies: ansi-regex: 6.2.2 @@ -11885,7 +11642,7 @@ snapshots: strip-json-comments@5.0.3: {} - strnum@2.2.3: {} + strnum@2.3.0: {} stubs@3.0.0: {} @@ -11952,7 +11709,7 @@ snapshots: '@azure/identity': 4.13.1 '@azure/keyvault-keys': 4.10.0(@azure/core-client@1.10.1) '@js-joda/core': 5.7.0 - '@types/node': 24.12.2 + '@types/node': 24.12.4 bl: 6.1.6 iconv-lite: 0.7.2 js-md4: 0.3.2 @@ -12003,8 +11760,6 @@ snapshots: tinybench@2.9.0: {} - tinyexec@1.1.1: {} - tinyexec@1.1.2: {} tinyglobby@0.2.16: @@ -12050,9 +11805,9 @@ snapshots: dependencies: tagged-tag: 1.0.0 - type-is@2.0.1: + type-is@2.1.0: dependencies: - content-type: 1.0.5 + content-type: 2.0.0 media-typer: 1.1.0 mime-types: 3.0.2 @@ -12131,20 +11886,20 @@ snapshots: url-join@5.0.0: {} - use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.6): + use-callback-ref@1.3.3(@types/react@19.2.15)(react@19.2.6): dependencies: react: 19.2.6 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 - use-sidecar@1.1.3(@types/react@19.2.14)(react@19.2.6): + use-sidecar@1.1.3(@types/react@19.2.15)(react@19.2.6): dependencies: detect-node-es: 1.1.0 react: 19.2.6 tslib: 2.8.1 optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 use-sync-external-store@1.6.0(react@19.2.6): dependencies: @@ -12174,29 +11929,29 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 - vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0): + vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0): dependencies: lightningcss: 1.32.0 picomatch: 4.0.4 postcss: 8.5.10 - rolldown: 1.0.0-rc.17 + rolldown: 1.0.2 tinyglobby: 0.2.16 optionalDependencies: - '@types/node': 24.12.2 + '@types/node': 24.12.4 esbuild: 0.28.0 fsevents: 2.3.3 jiti: 2.7.0 yaml: 2.9.0 - vitest@4.1.6(@opentelemetry/api@1.9.0)(@types/node@24.12.2)(@vitest/coverage-v8@4.1.6)(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)): + vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)): dependencies: - '@vitest/expect': 4.1.6 - '@vitest/mocker': 4.1.6(vite@8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.6 - '@vitest/runner': 4.1.6 - '@vitest/snapshot': 4.1.6 - '@vitest/spy': 4.1.6 - '@vitest/utils': 4.1.6 + '@vitest/expect': 4.1.7 + '@vitest/mocker': 4.1.7(vite@8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.7 + '@vitest/runner': 4.1.7 + '@vitest/snapshot': 4.1.7 + '@vitest/spy': 4.1.7 + '@vitest/utils': 4.1.7 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -12205,15 +11960,15 @@ snapshots: picomatch: 4.0.4 std-env: 4.1.0 tinybench: 2.9.0 - tinyexec: 1.1.1 + tinyexec: 1.1.2 tinyglobby: 0.2.16 tinyrainbow: 3.1.0 - vite: 8.0.10(@types/node@24.12.2)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0) + vite: 8.0.14(@types/node@24.12.4)(esbuild@0.28.0)(jiti@2.7.0)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: - '@opentelemetry/api': 1.9.0 - '@types/node': 24.12.2 - '@vitest/coverage-v8': 4.1.6(vitest@4.1.6) + '@opentelemetry/api': 1.9.1 + '@types/node': 24.12.4 + '@vitest/coverage-v8': 4.1.7(vitest@4.1.7) transitivePeerDependencies: - msw @@ -12264,7 +12019,7 @@ snapshots: dependencies: ansi-styles: 6.2.3 string-width: 8.2.1 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrap-ansi@7.0.0: dependencies: @@ -12276,7 +12031,7 @@ snapshots: dependencies: ansi-styles: 6.2.3 string-width: 7.2.0 - strip-ansi: 7.1.2 + strip-ansi: 7.2.0 wrappy@1.0.2: {} @@ -12286,6 +12041,8 @@ snapshots: dependencies: is-wsl: 3.1.1 + xml-naming@0.1.0: {} + xtend@4.0.2: {} y18n@5.0.8: {} @@ -12327,11 +12084,11 @@ snapshots: zod@4.4.3: {} - zustand@4.5.7(@types/react@19.2.14)(react@19.2.6): + zustand@4.5.7(@types/react@19.2.15)(react@19.2.6): dependencies: use-sync-external-store: 1.6.0(react@19.2.6) optionalDependencies: - '@types/react': 19.2.14 + '@types/react': 19.2.15 react: 19.2.6 zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 04eacb8f..ae7b5b37 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -23,3 +23,4 @@ allowBuilds: better-sqlite3: true esbuild: true sharp: true +minimumReleaseAge: 10080 diff --git a/pyproject.toml b/pyproject.toml index 67d2acbb..0395de17 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,10 +13,10 @@ Issues = "https://github.com/kaelio/ktx/issues" [dependency-groups] dev = [ - "pre-commit>=4.6.0", - "pytest>=9.0.2", - "pytest-cov>=7.1.0", - "ruff>=0.8.4", + "pre-commit>=4.6.0", + "pytest>=9.0.2", + "pytest-cov>=7.1.0", + "ruff>=0.8.4", ] [tool.uv] @@ -32,14 +32,14 @@ torch = { index = "pytorch-cpu" } [tool.uv.workspace] members = [ - "python/ktx-sl", - "python/ktx-daemon", + "python/ktx-sl", + "python/ktx-daemon", ] [tool.pytest.ini_options] addopts = ["--import-mode=importlib"] pythonpath = ["python/ktx-sl/tests"] testpaths = [ - "python/ktx-sl/tests", - "python/ktx-daemon/tests", + "python/ktx-sl/tests", + "python/ktx-daemon/tests", ] diff --git a/python/ktx-daemon/pyproject.toml b/python/ktx-daemon/pyproject.toml index 0c6c95e4..3cc4d2d2 100644 --- a/python/ktx-daemon/pyproject.toml +++ b/python/ktx-daemon/pyproject.toml @@ -6,18 +6,18 @@ readme = "README.md" requires-python = ">=3.13" license = "Apache-2.0" dependencies = [ - "fastapi>=0.115.0", - "ktx-sl", - "lkml>=1.3.7", - "numpy>=2.2.6", - "orjson>=3.11.4", - "pandas>=2.2.3", - "posthog>=7.0.0", - "psycopg[binary]>=3.2.0", - "pydantic>=2.9.0", - "requests>=2.32.0", - "sqlglot>=26", - "uvicorn[standard]>=0.32.0", + "fastapi>=0.136.3", + "ktx-sl", + "lkml>=1.3.7", + "numpy>=2.4.6", + "orjson>=3.11.9", + "pandas>=3.0.3", + "posthog>=7.16.1", + "psycopg[binary]>=3.3.4", + "pydantic>=2.13.4", + "requests>=2.34.2", + "sqlglot>=30", + "uvicorn[standard]>=0.48.0", ] [project.scripts] @@ -25,8 +25,8 @@ ktx-daemon = "ktx_daemon.__main__:main" [project.optional-dependencies] local-embeddings = [ - "sentence-transformers>=5.1.1", - "torch>=2.2.0", + "sentence-transformers>=5.1.1", + "torch>=2.2.0", ] [project.urls] @@ -43,8 +43,8 @@ packages = ["src/ktx_daemon"] [dependency-groups] dev = [ - "httpx>=0.28.1", - "pytest>=9.0.2", + "httpx>=0.28.1", + "pytest>=9.0.2", ] [tool.uv.sources] diff --git a/python/ktx-sl/pyproject.toml b/python/ktx-sl/pyproject.toml index 02cfd06a..6207390f 100644 --- a/python/ktx-sl/pyproject.toml +++ b/python/ktx-sl/pyproject.toml @@ -6,9 +6,9 @@ readme = "README.md" requires-python = ">=3.13" license = "Apache-2.0" dependencies = [ - "sqlglot>=26", - "pydantic>=2", - "pyyaml>=6", + "sqlglot>=30", + "pydantic>=2", + "pyyaml>=6", ] [project.urls] @@ -18,13 +18,13 @@ Issues = "https://github.com/kaelio/ktx/issues" [project.optional-dependencies] dev = [ - "pytest>=8", - "pytest-cov", - "ruff", - "pre-commit", + "pytest>=8", + "pytest-cov", + "ruff", + "pre-commit", ] tpch = [ - "duckdb>=1.0", + "duckdb>=1.0", ] [tool.pytest.ini_options] @@ -40,9 +40,9 @@ branch = true show_missing = true skip_empty = true exclude_lines = [ - "pragma: no cover", - "if __name__ == .__main__.", - "if TYPE_CHECKING:", + "pragma: no cover", + "if __name__ == .__main__.", + "if TYPE_CHECKING:", ] [build-system] @@ -54,6 +54,6 @@ packages = ["semantic_layer"] [dependency-groups] dev = [ - "pytest>=9.0.2", - "pytest-cov>=7.1.0", + "pytest>=9.0.2", + "pytest-cov>=7.1.0", ] diff --git a/scripts/upgrade-dependencies.mjs b/scripts/upgrade-dependencies.mjs new file mode 100644 index 00000000..5ec4996e --- /dev/null +++ b/scripts/upgrade-dependencies.mjs @@ -0,0 +1,111 @@ +#!/usr/bin/env node + +import { execFile as execFileCallback } from 'node:child_process'; +import { readFile as fsReadFile } from 'node:fs/promises'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { promisify } from 'node:util'; + +const execFileAsync = promisify(execFileCallback); +const npmCheckUpdatesRejectArgs = ['--reject', 'fumadocs-core,fumadocs-ui']; + +function ktxRootDir() { + return resolve(dirname(fileURLToPath(import.meta.url)), '..'); +} + +function failureText(error) { + const stdout = typeof error?.stdout === 'string' ? error.stdout.trim() : ''; + const stderr = typeof error?.stderr === 'string' ? error.stderr.trim() : ''; + const message = error instanceof Error ? error.message.trim() : String(error); + return [stderr, stdout, message].filter((line) => line.length > 0).join('\n') || 'Command failed'; +} + +function commandText(command, args) { + return [command, ...args].join(' '); +} + +function pythonDependencyUpdatePhases() { + const manifests = ['pyproject.toml', 'python/ktx-sl/pyproject.toml', 'python/ktx-daemon/pyproject.toml']; + return manifests.map((manifest) => ({ + name: `Python dependency constraints: ${manifest}`, + command: 'uvx', + args: ['dependency-check-updates', '--manifest', manifest, '-u'], + retry: commandText('uvx', ['dependency-check-updates', '--manifest', manifest, '-u']), + })); +} + +async function pnpmMinimumReleaseAgeCooldown(rootDir, readFile) { + let workspaceConfig; + try { + workspaceConfig = await readFile(resolve(rootDir, 'pnpm-workspace.yaml'), 'utf8'); + } catch (error) { + if (error?.code === 'ENOENT') { + return []; + } + throw error; + } + + const match = workspaceConfig.match(/^\s*minimumReleaseAge:\s*(\d+)\s*$/m); + if (!match) { + return []; + } + return ['--cooldown', `${match[1]}m`]; +} + +export async function runDependencyUpgrade(options = {}) { + const rootDir = options.rootDir ?? ktxRootDir(); + const execFile = options.execFile ?? execFileAsync; + const readFile = options.readFile ?? fsReadFile; + const log = options.log ?? ((line) => process.stdout.write(`${line}\n`)); + const npmCheckUpdatesCooldownArgs = await pnpmMinimumReleaseAgeCooldown(rootDir, readFile); + const phases = [ + { + name: 'TypeScript dependency constraints', + command: 'pnpm', + args: ['dlx', 'npm-check-updates', '-u', '--deep', ...npmCheckUpdatesRejectArgs, ...npmCheckUpdatesCooldownArgs], + retry: commandText('pnpm', [ + 'dlx', + 'npm-check-updates', + '-u', + '--deep', + ...npmCheckUpdatesRejectArgs, + ...npmCheckUpdatesCooldownArgs, + ]), + }, + ...pythonDependencyUpdatePhases(), + { + name: 'TypeScript lockfile', + command: 'pnpm', + args: ['install'], + retry: 'pnpm install', + }, + { + name: 'Python lockfile', + command: 'uv', + args: ['lock', '--upgrade'], + retry: 'uv lock --upgrade', + }, + ]; + + for (const phase of phases) { + log(`RUN ${phase.name}: ${commandText(phase.command, phase.args)}`); + try { + await execFile(phase.command, phase.args, { cwd: rootDir, maxBuffer: 1024 * 1024 * 64 }); + log(`PASS ${phase.name}`); + } catch (error) { + log(`FAIL ${phase.name}: ${failureText(error)}`); + log(`Retry: ${phase.retry}`); + return { ok: false, failedPhase: phase }; + } + } + + log('Dependency manifests and lockfiles were updated. Run `pnpm run check` before committing.'); + return { ok: true }; +} + +if (import.meta.url === pathToFileURL(process.argv[1]).href) { + const result = await runDependencyUpgrade(); + if (!result.ok) { + process.exitCode = 1; + } +} diff --git a/scripts/upgrade-dependencies.test.mjs b/scripts/upgrade-dependencies.test.mjs new file mode 100644 index 00000000..6f42bf7d --- /dev/null +++ b/scripts/upgrade-dependencies.test.mjs @@ -0,0 +1,123 @@ +import assert from 'node:assert/strict'; +import { readFile } from 'node:fs/promises'; +import { test } from 'node:test'; +import { runDependencyUpgrade } from './upgrade-dependencies.mjs'; + +test('runDependencyUpgrade updates TypeScript and Python manifests before regenerating lockfiles', async () => { + const calls = []; + const logs = []; + + const result = await runDependencyUpgrade({ + rootDir: '/workspace/ktx', + readFile: async (path) => { + assert.equal(path, '/workspace/ktx/pnpm-workspace.yaml'); + return 'packages: []\nminimumReleaseAge: 10080\n'; + }, + execFile: async (command, args, options) => { + calls.push({ command, args, cwd: options.cwd }); + return { stdout: '', stderr: '' }; + }, + log: (line) => logs.push(line), + }); + + assert.equal(result.ok, true); + assert.deepEqual( + calls.map((call) => [call.command, call.args]), + [ + [ + 'pnpm', + [ + 'dlx', + 'npm-check-updates', + '-u', + '--deep', + '--reject', + 'fumadocs-core,fumadocs-ui', + '--cooldown', + '10080m', + ], + ], + ['uvx', ['dependency-check-updates', '--manifest', 'pyproject.toml', '-u']], + ['uvx', ['dependency-check-updates', '--manifest', 'python/ktx-sl/pyproject.toml', '-u']], + ['uvx', ['dependency-check-updates', '--manifest', 'python/ktx-daemon/pyproject.toml', '-u']], + ['pnpm', ['install']], + ['uv', ['lock', '--upgrade']], + ], + ); + assert.equal(calls.every((call) => call.cwd === '/workspace/ktx'), true); + assert.equal(logs.some((line) => line.includes('PASS Python dependency constraints')), true); +}); + +test('runDependencyUpgrade stops at the failed phase and prints a retry command', async () => { + const calls = []; + const logs = []; + + const result = await runDependencyUpgrade({ + rootDir: '/workspace/ktx', + readFile: async () => 'packages: []\n', + execFile: async (command, args) => { + calls.push({ command, args }); + if (command === 'uvx' && args.includes('python/ktx-sl/pyproject.toml')) { + const error = new Error('dependency-check-updates failed'); + error.stdout = 'checking Python dependencies'; + error.stderr = 'could not read pyproject.toml'; + throw error; + } + return { stdout: '', stderr: '' }; + }, + log: (line) => logs.push(line), + }); + + assert.equal(result.ok, false); + assert.equal(result.failedPhase.name, 'Python dependency constraints: python/ktx-sl/pyproject.toml'); + assert.equal(result.failedPhase.retry, 'uvx dependency-check-updates --manifest python/ktx-sl/pyproject.toml -u'); + assert.deepEqual( + calls.map((call) => [call.command, call.args]), + [ + ['pnpm', ['dlx', 'npm-check-updates', '-u', '--deep', '--reject', 'fumadocs-core,fumadocs-ui']], + ['uvx', ['dependency-check-updates', '--manifest', 'pyproject.toml', '-u']], + ['uvx', ['dependency-check-updates', '--manifest', 'python/ktx-sl/pyproject.toml', '-u']], + ], + ); + assert.equal(logs.some((line) => line.includes('FAIL Python dependency constraints')), true); + assert.equal(logs.some((line) => line.includes('could not read pyproject.toml')), true); + assert.equal(logs.some((line) => line.includes('checking Python dependencies')), true); + assert.equal( + logs.some((line) => line.includes('Retry: uvx dependency-check-updates --manifest python/ktx-sl/pyproject.toml -u')), + true, + ); +}); + +test('runDependencyUpgrade ignores missing pnpm minimum release age config', async () => { + const calls = []; + + const result = await runDependencyUpgrade({ + rootDir: '/workspace/ktx', + readFile: async () => { + throw Object.assign(new Error('missing'), { code: 'ENOENT' }); + }, + execFile: async (command, args) => { + calls.push({ command, args }); + return { stdout: '', stderr: '' }; + }, + log: () => undefined, + }); + + assert.equal(result.ok, true); + assert.deepEqual(calls[0], { + command: 'pnpm', + args: ['dlx', 'npm-check-updates', '-u', '--deep', '--reject', 'fumadocs-core,fumadocs-ui'], + }); + assert.equal( + calls + .filter((call) => call.command === 'uvx') + .every((call) => call.args.includes('--manifest') && !call.args.includes('-d')), + true, + ); +}); + +test('package scripts expose the full dependency upgrade command', async () => { + const packageJson = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')); + + assert.equal(packageJson.scripts['deps:upgrade'], 'node scripts/upgrade-dependencies.mjs'); +}); diff --git a/tombi.toml b/tombi.toml new file mode 100644 index 00000000..bf3b3519 --- /dev/null +++ b/tombi.toml @@ -0,0 +1,5 @@ +[[schemas]] +path = "tombi://www.schemastore.org/pyproject.json" +include = ["**/pyproject.toml"] +format.rules.array-values-order.enabled = false +format.rules.table-keys-order.enabled = false diff --git a/uv.lock b/uv.lock index 25a8fab6..e72fc85a 100644 --- a/uv.lock +++ b/uv.lock @@ -2,21 +2,21 @@ version = 1 revision = 3 requires-python = ">=3.13" resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version < '3.14' and sys_platform == 'win32'", - "python_full_version < '3.14' and sys_platform == 'emscripten'", - "python_full_version < '3.14' and sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version >= '3.14' and sys_platform == 'darwin'", - "python_full_version < '3.14' and sys_platform == 'darwin'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.14' and sys_platform == 'darwin'", + "python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version < '3.14' and sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.14' and sys_platform == 'darwin'", ] [manifest] members = [ - "ktx-daemon", - "ktx-sl", - "ktx-workspace", + "ktx-daemon", + "ktx-sl", + "ktx-workspace", ] [[package]] @@ -25,7 +25,7 @@ version = "0.0.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, ] [[package]] @@ -34,7 +34,7 @@ version = "0.7.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] [[package]] @@ -42,11 +42,11 @@ name = "anyio" version = "4.13.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "idna" }, + { name = "idna" }, ] sdist = { url = "https://files.pythonhosted.org/packages/19/14/2c5dd9f512b66549ae92767a9c7b330ae88e1932ca57876909410251fe13/anyio-4.13.0.tar.gz", hash = "sha256:334b70e641fd2221c1505b3890c69882fe4a2df910cba14d97019b90b24439dc", size = 231622, upload-time = "2026-03-24T12:59:09.671Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" }, + { url = "https://files.pythonhosted.org/packages/da/42/e921fccf5015463e32a3cf6ee7f980a6ed0f395ceeaa45060b61d86486c2/anyio-4.13.0-py3-none-any.whl", hash = "sha256:08b310f9e24a9594186fd75b4f73f4a4152069e3853f1ed8bfbf58369f4ad708", size = 114353, upload-time = "2026-03-24T12:59:08.246Z" }, ] [[package]] @@ -55,16 +55,16 @@ version = "2.2.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/47/d7/5bbeb12c44d7c4f2fb5b56abce497eb5ed9f34d85701de869acedd602619/backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba", size = 17001, upload-time = "2022-10-05T19:19:32.061Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8", size = 15148, upload-time = "2022-10-05T19:19:30.546Z" }, + { url = "https://files.pythonhosted.org/packages/df/73/b6e24bd22e6720ca8ee9a85a0c4a2971af8497d8f3193fa05390cbd46e09/backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8", size = 15148, upload-time = "2022-10-05T19:19:30.546Z" }, ] [[package]] name = "certifi" -version = "2026.4.22" +version = "2026.5.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/25/ee/6caf7a40c36a1220410afe15a1cc64993a1f864871f698c0f93acb72842a/certifi-2026.4.22.tar.gz", hash = "sha256:8d455352a37b71bf76a79caa83a3d6c25afee4a385d632127b6afb3963f1c580", size = 137077, upload-time = "2026-04-22T11:26:11.191Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/ce/ee2ecad540810a79593028e88299baeae54d346cc7a0d94b6199988b89b1/certifi-2026.5.20.tar.gz", hash = "sha256:69dea482ab64caa7b9f6aba1c6bf48bb6a5448d1c0f1b17ab42ad8c763a5344d", size = 135422, upload-time = "2026-05-20T11:46:50.073Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/22/30/7cd8fdcdfbc5b869528b079bfb76dcdf6056b1a2097a662e5e8c04f42965/certifi-2026.4.22-py3-none-any.whl", hash = "sha256:3cb2210c8f88ba2318d29b0388d1023c8492ff72ecdde4ebdaddbb13a31b1c4a", size = 135707, upload-time = "2026-04-22T11:26:09.372Z" }, + { url = "https://files.pythonhosted.org/packages/59/8c/57e832b7af6d7c5abe66eb3fbe3a3a32f4d11ea23a1aa7131371035be991/certifi-2026.5.20-py3-none-any.whl", hash = "sha256:3c52e209ba0a4ad7aebe60436a4ab349c39e1e602e8c134221e546902ad25897", size = 134134, upload-time = "2026-05-20T11:46:48.578Z" }, ] [[package]] @@ -73,7 +73,7 @@ version = "3.5.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, + { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" }, ] [[package]] @@ -82,67 +82,67 @@ version = "3.4.7" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e7/a1/67fe25fac3c7642725500a3f6cfe5821ad557c3abb11c9d20d12c7008d3e/charset_normalizer-3.4.7.tar.gz", hash = "sha256:ae89db9e5f98a11a4bf50407d4363e7b09b31e55bc117b4f7d80aab97ba009e5", size = 144271, upload-time = "2026-04-02T09:28:39.342Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" }, - { url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" }, - { url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" }, - { url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" }, - { url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" }, - { url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" }, - { url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" }, - { url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" }, - { url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" }, - { url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" }, - { url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" }, - { url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" }, - { url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" }, - { url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" }, - { url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" }, - { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" }, - { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" }, - { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" }, - { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" }, - { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" }, - { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" }, - { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" }, - { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" }, - { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" }, - { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" }, - { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" }, - { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" }, - { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" }, - { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" }, - { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" }, - { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" }, - { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" }, - { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" }, - { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" }, - { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" }, - { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" }, - { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" }, - { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" }, - { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" }, - { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" }, - { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" }, - { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" }, - { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" }, - { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" }, - { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" }, - { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" }, - { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" }, + { url = "https://files.pythonhosted.org/packages/c1/3b/66777e39d3ae1ddc77ee606be4ec6d8cbd4c801f65e5a1b6f2b11b8346dd/charset_normalizer-3.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:f496c9c3cc02230093d8330875c4c3cdfc3b73612a5fd921c65d39cbcef08063", size = 309627, upload-time = "2026-04-02T09:26:45.198Z" }, + { url = "https://files.pythonhosted.org/packages/2e/4e/b7f84e617b4854ade48a1b7915c8ccfadeba444d2a18c291f696e37f0d3b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea948db76d31190bf08bd371623927ee1339d5f2a0b4b1b4a4439a65298703c", size = 207008, upload-time = "2026-04-02T09:26:46.824Z" }, + { url = "https://files.pythonhosted.org/packages/c4/bb/ec73c0257c9e11b268f018f068f5d00aa0ef8c8b09f7753ebd5f2880e248/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a277ab8928b9f299723bc1a2dabb1265911b1a76341f90a510368ca44ad9ab66", size = 228303, upload-time = "2026-04-02T09:26:48.397Z" }, + { url = "https://files.pythonhosted.org/packages/85/fb/32d1f5033484494619f701e719429c69b766bfc4dbc61aa9e9c8c166528b/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3bec022aec2c514d9cf199522a802bd007cd588ab17ab2525f20f9c34d067c18", size = 224282, upload-time = "2026-04-02T09:26:49.684Z" }, + { url = "https://files.pythonhosted.org/packages/fa/07/330e3a0dda4c404d6da83b327270906e9654a24f6c546dc886a0eb0ffb23/charset_normalizer-3.4.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e044c39e41b92c845bc815e5ae4230804e8e7bc29e399b0437d64222d92809dd", size = 215595, upload-time = "2026-04-02T09:26:50.915Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7c/fc890655786e423f02556e0216d4b8c6bcb6bdfa890160dc66bf52dee468/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:f495a1652cf3fbab2eb0639776dad966c2fb874d79d87ca07f9d5f059b8bd215", size = 201986, upload-time = "2026-04-02T09:26:52.197Z" }, + { url = "https://files.pythonhosted.org/packages/d8/97/bfb18b3db2aed3b90cf54dc292ad79fdd5ad65c4eae454099475cbeadd0d/charset_normalizer-3.4.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e712b419df8ba5e42b226c510472b37bd57b38e897d3eca5e8cfd410a29fa859", size = 211711, upload-time = "2026-04-02T09:26:53.49Z" }, + { url = "https://files.pythonhosted.org/packages/6f/a5/a581c13798546a7fd557c82614a5c65a13df2157e9ad6373166d2a3e645d/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7804338df6fcc08105c7745f1502ba68d900f45fd770d5bdd5288ddccb8a42d8", size = 210036, upload-time = "2026-04-02T09:26:54.975Z" }, + { url = "https://files.pythonhosted.org/packages/8c/bf/b3ab5bcb478e4193d517644b0fb2bf5497fbceeaa7a1bc0f4d5b50953861/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:481551899c856c704d58119b5025793fa6730adda3571971af568f66d2424bb5", size = 202998, upload-time = "2026-04-02T09:26:56.303Z" }, + { url = "https://files.pythonhosted.org/packages/e7/4e/23efd79b65d314fa320ec6017b4b5834d5c12a58ba4610aa353af2e2f577/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f59099f9b66f0d7145115e6f80dd8b1d847176df89b234a5a6b3f00437aa0832", size = 230056, upload-time = "2026-04-02T09:26:57.554Z" }, + { url = "https://files.pythonhosted.org/packages/b9/9f/1e1941bc3f0e01df116e68dc37a55c4d249df5e6fa77f008841aef68264f/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:f59ad4c0e8f6bba240a9bb85504faa1ab438237199d4cce5f622761507b8f6a6", size = 211537, upload-time = "2026-04-02T09:26:58.843Z" }, + { url = "https://files.pythonhosted.org/packages/80/0f/088cbb3020d44428964a6c97fe1edfb1b9550396bf6d278330281e8b709c/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:3dedcc22d73ec993f42055eff4fcfed9318d1eeb9a6606c55892a26964964e48", size = 226176, upload-time = "2026-04-02T09:27:00.437Z" }, + { url = "https://files.pythonhosted.org/packages/6a/9f/130394f9bbe06f4f63e22641d32fc9b202b7e251c9aef4db044324dac493/charset_normalizer-3.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:64f02c6841d7d83f832cd97ccf8eb8a906d06eb95d5276069175c696b024b60a", size = 217723, upload-time = "2026-04-02T09:27:02.021Z" }, + { url = "https://files.pythonhosted.org/packages/73/55/c469897448a06e49f8fa03f6caae97074fde823f432a98f979cc42b90e69/charset_normalizer-3.4.7-cp313-cp313-win32.whl", hash = "sha256:4042d5c8f957e15221d423ba781e85d553722fc4113f523f2feb7b188cc34c5e", size = 148085, upload-time = "2026-04-02T09:27:03.192Z" }, + { url = "https://files.pythonhosted.org/packages/5d/78/1b74c5bbb3f99b77a1715c91b3e0b5bdb6fe302d95ace4f5b1bec37b0167/charset_normalizer-3.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:3946fa46a0cf3e4c8cb1cc52f56bb536310d34f25f01ca9b6c16afa767dab110", size = 158819, upload-time = "2026-04-02T09:27:04.454Z" }, + { url = "https://files.pythonhosted.org/packages/68/86/46bd42279d323deb8687c4a5a811fd548cb7d1de10cf6535d099877a9a9f/charset_normalizer-3.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:80d04837f55fc81da168b98de4f4b797ef007fc8a79ab71c6ec9bc4dd662b15b", size = 147915, upload-time = "2026-04-02T09:27:05.971Z" }, + { url = "https://files.pythonhosted.org/packages/97/c8/c67cb8c70e19ef1960b97b22ed2a1567711de46c4ddf19799923adc836c2/charset_normalizer-3.4.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:c36c333c39be2dbca264d7803333c896ab8fa7d4d6f0ab7edb7dfd7aea6e98c0", size = 309234, upload-time = "2026-04-02T09:27:07.194Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/c091fdee33f20de70d6c8b522743b6f831a2f1cd3ff86de4c6a827c48a76/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1c2aed2e5e41f24ea8ef1590b8e848a79b56f3a5564a65ceec43c9d692dc7d8a", size = 208042, upload-time = "2026-04-02T09:27:08.749Z" }, + { url = "https://files.pythonhosted.org/packages/87/1c/ab2ce611b984d2fd5d86a5a8a19c1ae26acac6bad967da4967562c75114d/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:54523e136b8948060c0fa0bc7b1b50c32c186f2fceee897a495406bb6e311d2b", size = 228706, upload-time = "2026-04-02T09:27:09.951Z" }, + { url = "https://files.pythonhosted.org/packages/a8/29/2b1d2cb00bf085f59d29eb773ce58ec2d325430f8c216804a0a5cd83cbca/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:715479b9a2802ecac752a3b0efa2b0b60285cf962ee38414211abdfccc233b41", size = 224727, upload-time = "2026-04-02T09:27:11.175Z" }, + { url = "https://files.pythonhosted.org/packages/47/5c/032c2d5a07fe4d4855fea851209cca2b6f03ebeb6d4e3afdb3358386a684/charset_normalizer-3.4.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd6c2a1c7573c64738d716488d2cdd3c00e340e4835707d8fdb8dc1a66ef164e", size = 215882, upload-time = "2026-04-02T09:27:12.446Z" }, + { url = "https://files.pythonhosted.org/packages/2c/c2/356065d5a8b78ed04499cae5f339f091946a6a74f91e03476c33f0ab7100/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:c45e9440fb78f8ddabcf714b68f936737a121355bf59f3907f4e17721b9d1aae", size = 200860, upload-time = "2026-04-02T09:27:13.721Z" }, + { url = "https://files.pythonhosted.org/packages/0c/cd/a32a84217ced5039f53b29f460962abb2d4420def55afabe45b1c3c7483d/charset_normalizer-3.4.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3534e7dcbdcf757da6b85a0bbf5b6868786d5982dd959b065e65481644817a18", size = 211564, upload-time = "2026-04-02T09:27:15.272Z" }, + { url = "https://files.pythonhosted.org/packages/44/86/58e6f13ce26cc3b8f4a36b94a0f22ae2f00a72534520f4ae6857c4b81f89/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e8ac484bf18ce6975760921bb6148041faa8fef0547200386ea0b52b5d27bf7b", size = 211276, upload-time = "2026-04-02T09:27:16.834Z" }, + { url = "https://files.pythonhosted.org/packages/8f/fe/d17c32dc72e17e155e06883efa84514ca375f8a528ba2546bee73fc4df81/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a5fe03b42827c13cdccd08e6c0247b6a6d4b5e3cdc53fd1749f5896adcdc2356", size = 201238, upload-time = "2026-04-02T09:27:18.229Z" }, + { url = "https://files.pythonhosted.org/packages/6a/29/f33daa50b06525a237451cdb6c69da366c381a3dadcd833fa5676bc468b3/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2d6eb928e13016cea4f1f21d1e10c1cebd5a421bc57ddf5b1142ae3f86824fab", size = 230189, upload-time = "2026-04-02T09:27:19.445Z" }, + { url = "https://files.pythonhosted.org/packages/b6/6e/52c84015394a6a0bdcd435210a7e944c5f94ea1055f5cc5d56c5fe368e7b/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e74327fb75de8986940def6e8dee4f127cc9752bee7355bb323cc5b2659b6d46", size = 211352, upload-time = "2026-04-02T09:27:20.79Z" }, + { url = "https://files.pythonhosted.org/packages/8c/d7/4353be581b373033fb9198bf1da3cf8f09c1082561e8e922aa7b39bf9fe8/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d6038d37043bced98a66e68d3aa2b6a35505dc01328cd65217cefe82f25def44", size = 227024, upload-time = "2026-04-02T09:27:22.063Z" }, + { url = "https://files.pythonhosted.org/packages/30/45/99d18aa925bd1740098ccd3060e238e21115fffbfdcb8f3ece837d0ace6c/charset_normalizer-3.4.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7579e913a5339fb8fa133f6bbcfd8e6749696206cf05acdbdca71a1b436d8e72", size = 217869, upload-time = "2026-04-02T09:27:23.486Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/5ee478aa53f4bb7996482153d4bfe1b89e0f087f0ab6b294fcf92d595873/charset_normalizer-3.4.7-cp314-cp314-win32.whl", hash = "sha256:5b77459df20e08151cd6f8b9ef8ef1f961ef73d85c21a555c7eed5b79410ec10", size = 148541, upload-time = "2026-04-02T09:27:25.146Z" }, + { url = "https://files.pythonhosted.org/packages/48/77/72dcb0921b2ce86420b2d79d454c7022bf5be40202a2a07906b9f2a35c97/charset_normalizer-3.4.7-cp314-cp314-win_amd64.whl", hash = "sha256:92a0a01ead5e668468e952e4238cccd7c537364eb7d851ab144ab6627dbbe12f", size = 159634, upload-time = "2026-04-02T09:27:26.642Z" }, + { url = "https://files.pythonhosted.org/packages/c6/a3/c2369911cd72f02386e4e340770f6e158c7980267da16af8f668217abaa0/charset_normalizer-3.4.7-cp314-cp314-win_arm64.whl", hash = "sha256:67f6279d125ca0046a7fd386d01b311c6363844deac3e5b069b514ba3e63c246", size = 148384, upload-time = "2026-04-02T09:27:28.271Z" }, + { url = "https://files.pythonhosted.org/packages/94/09/7e8a7f73d24dba1f0035fbbf014d2c36828fc1bf9c88f84093e57d315935/charset_normalizer-3.4.7-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:effc3f449787117233702311a1b7d8f59cba9ced946ba727bdc329ec69028e24", size = 330133, upload-time = "2026-04-02T09:27:29.474Z" }, + { url = "https://files.pythonhosted.org/packages/8d/da/96975ddb11f8e977f706f45cddd8540fd8242f71ecdb5d18a80723dcf62c/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fbccdc05410c9ee21bbf16a35f4c1d16123dcdeb8a1d38f33654fa21d0234f79", size = 216257, upload-time = "2026-04-02T09:27:30.793Z" }, + { url = "https://files.pythonhosted.org/packages/e5/e8/1d63bf8ef2d388e95c64b2098f45f84758f6d102a087552da1485912637b/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:733784b6d6def852c814bce5f318d25da2ee65dd4839a0718641c696e09a2960", size = 234851, upload-time = "2026-04-02T09:27:32.44Z" }, + { url = "https://files.pythonhosted.org/packages/9b/40/e5ff04233e70da2681fa43969ad6f66ca5611d7e669be0246c4c7aaf6dc8/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a89c23ef8d2c6b27fd200a42aa4ac72786e7c60d40efdc76e6011260b6e949c4", size = 233393, upload-time = "2026-04-02T09:27:34.03Z" }, + { url = "https://files.pythonhosted.org/packages/be/c1/06c6c49d5a5450f76899992f1ee40b41d076aee9279b49cf9974d2f313d5/charset_normalizer-3.4.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6c114670c45346afedc0d947faf3c7f701051d2518b943679c8ff88befe14f8e", size = 223251, upload-time = "2026-04-02T09:27:35.369Z" }, + { url = "https://files.pythonhosted.org/packages/2b/9f/f2ff16fb050946169e3e1f82134d107e5d4ae72647ec8a1b1446c148480f/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:a180c5e59792af262bf263b21a3c49353f25945d8d9f70628e73de370d55e1e1", size = 206609, upload-time = "2026-04-02T09:27:36.661Z" }, + { url = "https://files.pythonhosted.org/packages/69/d5/a527c0cd8d64d2eab7459784fb4169a0ac76e5a6fc5237337982fd61347e/charset_normalizer-3.4.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3c9a494bc5ec77d43cea229c4f6db1e4d8fe7e1bbffa8b6f0f0032430ff8ab44", size = 220014, upload-time = "2026-04-02T09:27:38.019Z" }, + { url = "https://files.pythonhosted.org/packages/7e/80/8a7b8104a3e203074dc9aa2c613d4b726c0e136bad1cc734594b02867972/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8d828b6667a32a728a1ad1d93957cdf37489c57b97ae6c4de2860fa749b8fc1e", size = 218979, upload-time = "2026-04-02T09:27:39.37Z" }, + { url = "https://files.pythonhosted.org/packages/02/9a/b759b503d507f375b2b5c153e4d2ee0a75aa215b7f2489cf314f4541f2c0/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cf1493cd8607bec4d8a7b9b004e699fcf8f9103a9284cc94962cb73d20f9d4a3", size = 209238, upload-time = "2026-04-02T09:27:40.722Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/0f3f5d47b86bdb79256e7290b26ac847a2832d9a4033f7eb2cd4bcf4bb5b/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0c96c3b819b5c3e9e165495db84d41914d6894d55181d2d108cc1a69bfc9cce0", size = 236110, upload-time = "2026-04-02T09:27:42.33Z" }, + { url = "https://files.pythonhosted.org/packages/96/23/bce28734eb3ed2c91dcf93abeb8a5cf393a7b2749725030bb630e554fdd8/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:752a45dc4a6934060b3b0dab47e04edc3326575f82be64bc4fc293914566503e", size = 219824, upload-time = "2026-04-02T09:27:43.924Z" }, + { url = "https://files.pythonhosted.org/packages/2c/6f/6e897c6984cc4d41af319b077f2f600fc8214eb2fe2d6bcb79141b882400/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:8778f0c7a52e56f75d12dae53ae320fae900a8b9b4164b981b9c5ce059cd1fcb", size = 233103, upload-time = "2026-04-02T09:27:45.348Z" }, + { url = "https://files.pythonhosted.org/packages/76/22/ef7bd0fe480a0ae9b656189ec00744b60933f68b4f42a7bb06589f6f576a/charset_normalizer-3.4.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ce3412fbe1e31eb81ea42f4169ed94861c56e643189e1e75f0041f3fe7020abe", size = 225194, upload-time = "2026-04-02T09:27:46.706Z" }, + { url = "https://files.pythonhosted.org/packages/c5/a7/0e0ab3e0b5bc1219bd80a6a0d4d72ca74d9250cb2382b7c699c147e06017/charset_normalizer-3.4.7-cp314-cp314t-win32.whl", hash = "sha256:c03a41a8784091e67a39648f70c5f97b5b6a37f216896d44d2cdcb82615339a0", size = 159827, upload-time = "2026-04-02T09:27:48.053Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1d/29d32e0fb40864b1f878c7f5a0b343ae676c6e2b271a2d55cc3a152391da/charset_normalizer-3.4.7-cp314-cp314t-win_amd64.whl", hash = "sha256:03853ed82eeebbce3c2abfdbc98c96dc205f32a79627688ac9a27370ea61a49c", size = 174168, upload-time = "2026-04-02T09:27:49.795Z" }, + { url = "https://files.pythonhosted.org/packages/de/32/d92444ad05c7a6e41fb2036749777c163baf7a0301a040cb672d6b2b1ae9/charset_normalizer-3.4.7-cp314-cp314t-win_arm64.whl", hash = "sha256:c35abb8bfff0185efac5878da64c45dafd2b37fb0383add1be155a763c1f083d", size = 153018, upload-time = "2026-04-02T09:27:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/db/8f/61959034484a4a7c527811f4721e75d02d653a35afb0b6054474d8185d4c/charset_normalizer-3.4.7-py3-none-any.whl", hash = "sha256:3dce51d0f5e7951f8bb4900c257dad282f49190fdbebecd4ba99bcc41fef404d", size = 61958, upload-time = "2026-04-02T09:28:37.794Z" }, ] [[package]] name = "click" -version = "8.3.3" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/63/f9e1ea081ce35720d8b92acde70daaedace594dc93b693c869e0d5910718/click-8.3.3.tar.gz", hash = "sha256:398329ad4837b2ff7cbe1dd166a4c0f8900c3ca3a218de04466f38f6497f18a2", size = 328061, upload-time = "2026-04-22T15:11:27.506Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9b/98/518d8e5081007684232226f475082b30087d0f585e8457db087298259f49/click-8.4.1.tar.gz", hash = "sha256:918b5633eddf6b41c32d4f454bf0de810065c74e3f7dbf8ee5452f8be88d3e96", size = 353007, upload-time = "2026-05-22T04:08:37.769Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ae/44/c1221527f6a71a01ec6fbad7fa78f1d50dfa02217385cf0fa3eec7087d59/click-8.3.3-py3-none-any.whl", hash = "sha256:a2bf429bb3033c89fa4936ffb35d5cb471e3719e1f3c8a7c3fff0b8314305613", size = 110502, upload-time = "2026-04-22T15:11:25.044Z" }, + { url = "https://files.pythonhosted.org/packages/c7/0d/67e5b4109ea4a837e80daa87c2c696711955e40449a97e8926672534def2/click-8.4.1-py3-none-any.whl", hash = "sha256:482be17c6991b8c19c5429a1e995d9b0efdbb63172824c41f99965dc0ade8ec2", size = 116639, upload-time = "2026-05-22T04:08:35.26Z" }, ] [[package]] @@ -151,76 +151,76 @@ version = "0.4.6" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "coverage" -version = "7.13.5" +version = "7.14.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/e0/70553e3000e345daff267cec284ce4cbf3fc141b6da229ac52775b5428f1/coverage-7.13.5.tar.gz", hash = "sha256:c81f6515c4c40141f83f502b07bbfa5c240ba25bbe73da7b33f1e5b6120ff179", size = 915967, upload-time = "2026-03-17T10:33:18.341Z" } +sdist = { url = "https://files.pythonhosted.org/packages/54/fd/0ab2772530e946e1be1abd0bc09e647ec9b02e88f0867857601fefca8953/coverage-7.14.1.tar.gz", hash = "sha256:30c08f7d90415aa98b3c990385dea2939b0da55f38515e5b369b83655f8523be", size = 920132, upload-time = "2026-05-26T20:41:36.783Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/74/8c/74fedc9663dcf168b0a059d4ea756ecae4da77a489048f94b5f512a8d0b3/coverage-7.13.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ec4af212df513e399cf11610cc27063f1586419e814755ab362e50a85ea69c1", size = 219576, upload-time = "2026-03-17T10:31:09.045Z" }, - { url = "https://files.pythonhosted.org/packages/0c/c9/44fb661c55062f0818a6ffd2685c67aa30816200d5f2817543717d4b92eb/coverage-7.13.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:941617e518602e2d64942c88ec8499f7fbd49d3f6c4327d3a71d43a1973032f3", size = 219942, upload-time = "2026-03-17T10:31:10.708Z" }, - { url = "https://files.pythonhosted.org/packages/5f/13/93419671cee82b780bab7ea96b67c8ef448f5f295f36bf5031154ec9a790/coverage-7.13.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:da305e9937617ee95c2e39d8ff9f040e0487cbf1ac174f777ed5eddd7a7c1f26", size = 250935, upload-time = "2026-03-17T10:31:12.392Z" }, - { url = "https://files.pythonhosted.org/packages/ac/68/1666e3a4462f8202d836920114fa7a5ee9275d1fa45366d336c551a162dd/coverage-7.13.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:78e696e1cc714e57e8b25760b33a8b1026b7048d270140d25dafe1b0a1ee05a3", size = 253541, upload-time = "2026-03-17T10:31:14.247Z" }, - { url = "https://files.pythonhosted.org/packages/4e/5e/3ee3b835647be646dcf3c65a7c6c18f87c27326a858f72ab22c12730773d/coverage-7.13.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:02ca0eed225b2ff301c474aeeeae27d26e2537942aa0f87491d3e147e784a82b", size = 254780, upload-time = "2026-03-17T10:31:16.193Z" }, - { url = "https://files.pythonhosted.org/packages/44/b3/cb5bd1a04cfcc49ede6cd8409d80bee17661167686741e041abc7ee1b9a9/coverage-7.13.5-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:04690832cbea4e4663d9149e05dba142546ca05cb1848816760e7f58285c970a", size = 256912, upload-time = "2026-03-17T10:31:17.89Z" }, - { url = "https://files.pythonhosted.org/packages/1b/66/c1dceb7b9714473800b075f5c8a84f4588f887a90eb8645282031676e242/coverage-7.13.5-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0590e44dd2745c696a778f7bab6aa95256de2cbc8b8cff4f7db8ff09813d6969", size = 251165, upload-time = "2026-03-17T10:31:19.605Z" }, - { url = "https://files.pythonhosted.org/packages/b7/62/5502b73b97aa2e53ea22a39cf8649ff44827bef76d90bf638777daa27a9d/coverage-7.13.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d7cfad2d6d81dd298ab6b89fe72c3b7b05ec7544bdda3b707ddaecff8d25c161", size = 252908, upload-time = "2026-03-17T10:31:21.312Z" }, - { url = "https://files.pythonhosted.org/packages/7d/37/7792c2d69854397ca77a55c4646e5897c467928b0e27f2d235d83b5d08c6/coverage-7.13.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:e092b9499de38ae0fbfbc603a74660eb6ff3e869e507b50d85a13b6db9863e15", size = 250873, upload-time = "2026-03-17T10:31:23.565Z" }, - { url = "https://files.pythonhosted.org/packages/a3/23/bc866fb6163be52a8a9e5d708ba0d3b1283c12158cefca0a8bbb6e247a43/coverage-7.13.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:48c39bc4a04d983a54a705a6389512883d4a3b9862991b3617d547940e9f52b1", size = 255030, upload-time = "2026-03-17T10:31:25.58Z" }, - { url = "https://files.pythonhosted.org/packages/7d/8b/ef67e1c222ef49860701d346b8bbb70881bef283bd5f6cbba68a39a086c7/coverage-7.13.5-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:2d3807015f138ffea1ed9afeeb8624fd781703f2858b62a8dd8da5a0994c57b6", size = 250694, upload-time = "2026-03-17T10:31:27.316Z" }, - { url = "https://files.pythonhosted.org/packages/46/0d/866d1f74f0acddbb906db212e096dee77a8e2158ca5e6bb44729f9d93298/coverage-7.13.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee2aa19e03161671ec964004fb74b2257805d9710bf14a5c704558b9d8dbaf17", size = 252469, upload-time = "2026-03-17T10:31:29.472Z" }, - { url = "https://files.pythonhosted.org/packages/7a/f5/be742fec31118f02ce42b21c6af187ad6a344fed546b56ca60caacc6a9a0/coverage-7.13.5-cp313-cp313-win32.whl", hash = "sha256:ce1998c0483007608c8382f4ff50164bfc5bd07a2246dd272aa4043b75e61e85", size = 222112, upload-time = "2026-03-17T10:31:31.526Z" }, - { url = "https://files.pythonhosted.org/packages/66/40/7732d648ab9d069a46e686043241f01206348e2bbf128daea85be4d6414b/coverage-7.13.5-cp313-cp313-win_amd64.whl", hash = "sha256:631efb83f01569670a5e866ceb80fe483e7c159fac6f167e6571522636104a0b", size = 222923, upload-time = "2026-03-17T10:31:33.633Z" }, - { url = "https://files.pythonhosted.org/packages/48/af/fea819c12a095781f6ccd504890aaddaf88b8fab263c4940e82c7b770124/coverage-7.13.5-cp313-cp313-win_arm64.whl", hash = "sha256:f4cd16206ad171cbc2470dbea9103cf9a7607d5fe8c242fdf1edf36174020664", size = 221540, upload-time = "2026-03-17T10:31:35.445Z" }, - { url = "https://files.pythonhosted.org/packages/23/d2/17879af479df7fbbd44bd528a31692a48f6b25055d16482fdf5cdb633805/coverage-7.13.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0428cbef5783ad91fe240f673cc1f76b25e74bbfe1a13115e4aa30d3f538162d", size = 220262, upload-time = "2026-03-17T10:31:37.184Z" }, - { url = "https://files.pythonhosted.org/packages/5b/4c/d20e554f988c8f91d6a02c5118f9abbbf73a8768a3048cb4962230d5743f/coverage-7.13.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e0b216a19534b2427cc201a26c25da4a48633f29a487c61258643e89d28200c0", size = 220617, upload-time = "2026-03-17T10:31:39.245Z" }, - { url = "https://files.pythonhosted.org/packages/29/9c/f9f5277b95184f764b24e7231e166dfdb5780a46d408a2ac665969416d61/coverage-7.13.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:972a9cd27894afe4bc2b1480107054e062df08e671df7c2f18c205e805ccd806", size = 261912, upload-time = "2026-03-17T10:31:41.324Z" }, - { url = "https://files.pythonhosted.org/packages/d5/f6/7f1ab39393eeb50cfe4747ae8ef0e4fc564b989225aa1152e13a180d74f8/coverage-7.13.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4b59148601efcd2bac8c4dbf1f0ad6391693ccf7a74b8205781751637076aee3", size = 263987, upload-time = "2026-03-17T10:31:43.724Z" }, - { url = "https://files.pythonhosted.org/packages/a0/d7/62c084fb489ed9c6fbdf57e006752e7c516ea46fd690e5ed8b8617c7d52e/coverage-7.13.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:505d7083c8b0c87a8fa8c07370c285847c1f77739b22e299ad75a6af6c32c5c9", size = 266416, upload-time = "2026-03-17T10:31:45.769Z" }, - { url = "https://files.pythonhosted.org/packages/a9/f6/df63d8660e1a0bff6125947afda112a0502736f470d62ca68b288ea762d8/coverage-7.13.5-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:60365289c3741e4db327e7baff2a4aaacf22f788e80fa4683393891b70a89fbd", size = 267558, upload-time = "2026-03-17T10:31:48.293Z" }, - { url = "https://files.pythonhosted.org/packages/5b/02/353ca81d36779bd108f6d384425f7139ac3c58c750dcfaafe5d0bee6436b/coverage-7.13.5-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1b88c69c8ef5d4b6fe7dea66d6636056a0f6a7527c440e890cf9259011f5e606", size = 261163, upload-time = "2026-03-17T10:31:50.125Z" }, - { url = "https://files.pythonhosted.org/packages/2c/16/2e79106d5749bcaf3aee6d309123548e3276517cd7851faa8da213bc61bf/coverage-7.13.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5b13955d31d1633cf9376908089b7cebe7d15ddad7aeaabcbe969a595a97e95e", size = 263981, upload-time = "2026-03-17T10:31:51.961Z" }, - { url = "https://files.pythonhosted.org/packages/29/c7/c29e0c59ffa6942030ae6f50b88ae49988e7e8da06de7ecdbf49c6d4feae/coverage-7.13.5-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:f70c9ab2595c56f81a89620e22899eea8b212a4041bd728ac6f4a28bf5d3ddd0", size = 261604, upload-time = "2026-03-17T10:31:53.872Z" }, - { url = "https://files.pythonhosted.org/packages/40/48/097cdc3db342f34006a308ab41c3a7c11c3f0d84750d340f45d88a782e00/coverage-7.13.5-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:084b84a8c63e8d6fc7e3931b316a9bcafca1458d753c539db82d31ed20091a87", size = 265321, upload-time = "2026-03-17T10:31:55.997Z" }, - { url = "https://files.pythonhosted.org/packages/bb/1f/4994af354689e14fd03a75f8ec85a9a68d94e0188bbdab3fc1516b55e512/coverage-7.13.5-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ad14385487393e386e2ea988b09d62dd42c397662ac2dabc3832d71253eee479", size = 260502, upload-time = "2026-03-17T10:31:58.308Z" }, - { url = "https://files.pythonhosted.org/packages/22/c6/9bb9ef55903e628033560885f5c31aa227e46878118b63ab15dc7ba87797/coverage-7.13.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:7f2c47b36fe7709a6e83bfadf4eefb90bd25fbe4014d715224c4316f808e59a2", size = 262688, upload-time = "2026-03-17T10:32:00.141Z" }, - { url = "https://files.pythonhosted.org/packages/14/4f/f5df9007e50b15e53e01edea486814783a7f019893733d9e4d6caad75557/coverage-7.13.5-cp313-cp313t-win32.whl", hash = "sha256:67e9bc5449801fad0e5dff329499fb090ba4c5800b86805c80617b4e29809b2a", size = 222788, upload-time = "2026-03-17T10:32:02.246Z" }, - { url = "https://files.pythonhosted.org/packages/e1/98/aa7fccaa97d0f3192bec013c4e6fd6d294a6ed44b640e6bb61f479e00ed5/coverage-7.13.5-cp313-cp313t-win_amd64.whl", hash = "sha256:da86cdcf10d2519e10cabb8ac2de03da1bcb6e4853790b7fbd48523332e3a819", size = 223851, upload-time = "2026-03-17T10:32:04.416Z" }, - { url = "https://files.pythonhosted.org/packages/3d/8b/e5c469f7352651e5f013198e9e21f97510b23de957dd06a84071683b4b60/coverage-7.13.5-cp313-cp313t-win_arm64.whl", hash = "sha256:0ecf12ecb326fe2c339d93fc131816f3a7367d223db37817208905c89bded911", size = 222104, upload-time = "2026-03-17T10:32:06.65Z" }, - { url = "https://files.pythonhosted.org/packages/8e/77/39703f0d1d4b478bfd30191d3c14f53caf596fac00efb3f8f6ee23646439/coverage-7.13.5-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fbabfaceaeb587e16f7008f7795cd80d20ec548dc7f94fbb0d4ec2e038ce563f", size = 219621, upload-time = "2026-03-17T10:32:08.589Z" }, - { url = "https://files.pythonhosted.org/packages/e2/3e/51dff36d99ae14639a133d9b164d63e628532e2974d8b1edb99dd1ebc733/coverage-7.13.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9bb2a28101a443669a423b665939381084412b81c3f8c0fcfbac57f4e30b5b8e", size = 219953, upload-time = "2026-03-17T10:32:10.507Z" }, - { url = "https://files.pythonhosted.org/packages/6a/6c/1f1917b01eb647c2f2adc9962bd66c79eb978951cab61bdc1acab3290c07/coverage-7.13.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bd3a2fbc1c6cccb3c5106140d87cc6a8715110373ef42b63cf5aea29df8c217a", size = 250992, upload-time = "2026-03-17T10:32:12.41Z" }, - { url = "https://files.pythonhosted.org/packages/22/e5/06b1f88f42a5a99df42ce61208bdec3bddb3d261412874280a19796fc09c/coverage-7.13.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6c36ddb64ed9d7e496028d1d00dfec3e428e0aabf4006583bb1839958d280510", size = 253503, upload-time = "2026-03-17T10:32:14.449Z" }, - { url = "https://files.pythonhosted.org/packages/80/28/2a148a51e5907e504fa7b85490277734e6771d8844ebcc48764a15e28155/coverage-7.13.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:380e8e9084d8eb38db3a9176a1a4f3c0082c3806fa0dc882d1d87abc3c789247", size = 254852, upload-time = "2026-03-17T10:32:16.56Z" }, - { url = "https://files.pythonhosted.org/packages/61/77/50e8d3d85cc0b7ebe09f30f151d670e302c7ff4a1bf6243f71dd8b0981fa/coverage-7.13.5-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e808af52a0513762df4d945ea164a24b37f2f518cbe97e03deaa0ee66139b4d6", size = 257161, upload-time = "2026-03-17T10:32:19.004Z" }, - { url = "https://files.pythonhosted.org/packages/3b/c4/b5fd1d4b7bf8d0e75d997afd3925c59ba629fc8616f1b3aae7605132e256/coverage-7.13.5-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e301d30dd7e95ae068671d746ba8c34e945a82682e62918e41b2679acd2051a0", size = 251021, upload-time = "2026-03-17T10:32:21.344Z" }, - { url = "https://files.pythonhosted.org/packages/f8/66/6ea21f910e92d69ef0b1c3346ea5922a51bad4446c9126db2ae96ee24c4c/coverage-7.13.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:800bc829053c80d240a687ceeb927a94fd108bbdc68dfbe505d0d75ab578a882", size = 252858, upload-time = "2026-03-17T10:32:23.506Z" }, - { url = "https://files.pythonhosted.org/packages/9e/ea/879c83cb5d61aa2a35fb80e72715e92672daef8191b84911a643f533840c/coverage-7.13.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:0b67af5492adb31940ee418a5a655c28e48165da5afab8c7fa6fd72a142f8740", size = 250823, upload-time = "2026-03-17T10:32:25.516Z" }, - { url = "https://files.pythonhosted.org/packages/8a/fb/616d95d3adb88b9803b275580bdeee8bd1b69a886d057652521f83d7322f/coverage-7.13.5-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:c9136ff29c3a91e25b1d1552b5308e53a1e0653a23e53b6366d7c2dcbbaf8a16", size = 255099, upload-time = "2026-03-17T10:32:27.944Z" }, - { url = "https://files.pythonhosted.org/packages/1c/93/25e6917c90ec1c9a56b0b26f6cad6408e5f13bb6b35d484a0d75c9cf000d/coverage-7.13.5-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:cff784eef7f0b8f6cb28804fbddcfa99f89efe4cc35fb5627e3ac58f91ed3ac0", size = 250638, upload-time = "2026-03-17T10:32:29.914Z" }, - { url = "https://files.pythonhosted.org/packages/fc/7b/dc1776b0464145a929deed214aef9fb1493f159b59ff3c7eeeedf91eddd0/coverage-7.13.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:68a4953be99b17ac3c23b6efbc8a38330d99680c9458927491d18700ef23ded0", size = 252295, upload-time = "2026-03-17T10:32:31.981Z" }, - { url = "https://files.pythonhosted.org/packages/ea/fb/99cbbc56a26e07762a2740713f3c8f9f3f3106e3a3dd8cc4474954bccd34/coverage-7.13.5-cp314-cp314-win32.whl", hash = "sha256:35a31f2b1578185fbe6aa2e74cea1b1d0bbf4c552774247d9160d29b80ed56cc", size = 222360, upload-time = "2026-03-17T10:32:34.233Z" }, - { url = "https://files.pythonhosted.org/packages/8d/b7/4758d4f73fb536347cc5e4ad63662f9d60ba9118cb6785e9616b2ce5d7fa/coverage-7.13.5-cp314-cp314-win_amd64.whl", hash = "sha256:2aa055ae1857258f9e0045be26a6d62bdb47a72448b62d7b55f4820f361a2633", size = 223174, upload-time = "2026-03-17T10:32:36.369Z" }, - { url = "https://files.pythonhosted.org/packages/2c/f2/24d84e1dfe70f8ac9fdf30d338239860d0d1d5da0bda528959d0ebc9da28/coverage-7.13.5-cp314-cp314-win_arm64.whl", hash = "sha256:1b11eef33edeae9d142f9b4358edb76273b3bfd30bc3df9a4f95d0e49caf94e8", size = 221739, upload-time = "2026-03-17T10:32:38.736Z" }, - { url = "https://files.pythonhosted.org/packages/60/5b/4a168591057b3668c2428bff25dd3ebc21b629d666d90bcdfa0217940e84/coverage-7.13.5-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:10a0c37f0b646eaff7cce1874c31d1f1ccb297688d4c747291f4f4c70741cc8b", size = 220351, upload-time = "2026-03-17T10:32:41.196Z" }, - { url = "https://files.pythonhosted.org/packages/f5/21/1fd5c4dbfe4a58b6b99649125635df46decdfd4a784c3cd6d410d303e370/coverage-7.13.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b5db73ba3c41c7008037fa731ad5459fc3944cb7452fc0aa9f822ad3533c583c", size = 220612, upload-time = "2026-03-17T10:32:43.204Z" }, - { url = "https://files.pythonhosted.org/packages/d6/fe/2a924b3055a5e7e4512655a9d4609781b0d62334fa0140c3e742926834e2/coverage-7.13.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:750db93a81e3e5a9831b534be7b1229df848b2e125a604fe6651e48aa070e5f9", size = 261985, upload-time = "2026-03-17T10:32:45.514Z" }, - { url = "https://files.pythonhosted.org/packages/d7/0d/c8928f2bd518c45990fe1a2ab8db42e914ef9b726c975facc4282578c3eb/coverage-7.13.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9ddb4f4a5479f2539644be484da179b653273bca1a323947d48ab107b3ed1f29", size = 264107, upload-time = "2026-03-17T10:32:47.971Z" }, - { url = "https://files.pythonhosted.org/packages/ef/ae/4ae35bbd9a0af9d820362751f0766582833c211224b38665c0f8de3d487f/coverage-7.13.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8a7a2049c14f413163e2bdabd37e41179b1d1ccb10ffc6ccc4b7a718429c607", size = 266513, upload-time = "2026-03-17T10:32:50.1Z" }, - { url = "https://files.pythonhosted.org/packages/9c/20/d326174c55af36f74eac6ae781612d9492f060ce8244b570bb9d50d9d609/coverage-7.13.5-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e1c85e0b6c05c592ea6d8768a66a254bfb3874b53774b12d4c89c481eb78cb90", size = 267650, upload-time = "2026-03-17T10:32:52.391Z" }, - { url = "https://files.pythonhosted.org/packages/7a/5e/31484d62cbd0eabd3412e30d74386ece4a0837d4f6c3040a653878bfc019/coverage-7.13.5-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:777c4d1eff1b67876139d24288aaf1817f6c03d6bae9c5cc8d27b83bcfe38fe3", size = 261089, upload-time = "2026-03-17T10:32:54.544Z" }, - { url = "https://files.pythonhosted.org/packages/e9/d8/49a72d6de146eebb0b7e48cc0f4bc2c0dd858e3d4790ab2b39a2872b62bd/coverage-7.13.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:6697e29b93707167687543480a40f0db8f356e86d9f67ddf2e37e2dfd91a9dab", size = 263982, upload-time = "2026-03-17T10:32:56.803Z" }, - { url = "https://files.pythonhosted.org/packages/06/3b/0351f1bd566e6e4dd39e978efe7958bde1d32f879e85589de147654f57bb/coverage-7.13.5-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8fdf453a942c3e4d99bd80088141c4c6960bb232c409d9c3558e2dbaa3998562", size = 261579, upload-time = "2026-03-17T10:32:59.466Z" }, - { url = "https://files.pythonhosted.org/packages/5d/ce/796a2a2f4017f554d7810f5c573449b35b1e46788424a548d4d19201b222/coverage-7.13.5-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:32ca0c0114c9834a43f045a87dcebd69d108d8ffb666957ea65aa132f50332e2", size = 265316, upload-time = "2026-03-17T10:33:01.847Z" }, - { url = "https://files.pythonhosted.org/packages/3d/16/d5ae91455541d1a78bc90abf495be600588aff8f6db5c8b0dae739fa39c9/coverage-7.13.5-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8769751c10f339021e2638cd354e13adeac54004d1941119b2c96fe5276d45ea", size = 260427, upload-time = "2026-03-17T10:33:03.945Z" }, - { url = "https://files.pythonhosted.org/packages/48/11/07f413dba62db21fb3fad5d0de013a50e073cc4e2dc4306e770360f6dfc8/coverage-7.13.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cec2d83125531bd153175354055cdb7a09987af08a9430bd173c937c6d0fba2a", size = 262745, upload-time = "2026-03-17T10:33:06.285Z" }, - { url = "https://files.pythonhosted.org/packages/91/15/d792371332eb4663115becf4bad47e047d16234b1aff687b1b18c58d60ae/coverage-7.13.5-cp314-cp314t-win32.whl", hash = "sha256:0cd9ed7a8b181775459296e402ca4fb27db1279740a24e93b3b41942ebe4b215", size = 223146, upload-time = "2026-03-17T10:33:08.756Z" }, - { url = "https://files.pythonhosted.org/packages/db/51/37221f59a111dca5e85be7dbf09696323b5b9f13ff65e0641d535ed06ea8/coverage-7.13.5-cp314-cp314t-win_amd64.whl", hash = "sha256:301e3b7dfefecaca37c9f1aa6f0049b7d4ab8dd933742b607765d757aca77d43", size = 224254, upload-time = "2026-03-17T10:33:11.174Z" }, - { url = "https://files.pythonhosted.org/packages/54/83/6acacc889de8987441aa7d5adfbdbf33d288dad28704a67e574f1df9bcbb/coverage-7.13.5-cp314-cp314t-win_arm64.whl", hash = "sha256:9dacc2ad679b292709e0f5fc1ac74a6d4d5562e424058962c7bb0c658ad25e45", size = 222276, upload-time = "2026-03-17T10:33:13.466Z" }, - { url = "https://files.pythonhosted.org/packages/9e/ee/a4cf96b8ce1e566ed238f0659ac2d3f007ed1d14b181bcb684e19561a69a/coverage-7.13.5-py3-none-any.whl", hash = "sha256:34b02417cf070e173989b3db962f7ed56d2f644307b2cf9d5a0f258e13084a61", size = 211346, upload-time = "2026-03-17T10:33:15.691Z" }, + { url = "https://files.pythonhosted.org/packages/8a/9e/5f6d56327c62b185225d145191c607e07515294a0aa6338e58805cd4a5ac/coverage-7.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:be9f2c802dcfce3f71298303aa5dad0dce440a76c52f2f60dacd8656dab78793", size = 220044, upload-time = "2026-05-26T20:39:29.902Z" }, + { url = "https://files.pythonhosted.org/packages/75/92/e82aca356744cbbc0f77a0b623e38918c1872361963413a3bab5d0340393/coverage-7.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6223a72fd0e4c7156353ec0f08a5f93623e1d3034d0e2683b9bb8ea674131b1d", size = 220412, upload-time = "2026-05-26T20:39:31.561Z" }, + { url = "https://files.pythonhosted.org/packages/27/c9/385bde0bf7ed0f4bf3a7ee5367060a86b5d218718cfd6fb943c0f836b34f/coverage-7.14.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7279d2110a28cebc738b6459ecda2771735a4c18465fbbd36b3288fe5ed92247", size = 251412, upload-time = "2026-05-26T20:39:33.337Z" }, + { url = "https://files.pythonhosted.org/packages/51/8c/23faf6a2343a0d17f960a4bd56c43bc7eb4cf312f774dd6ceebd82c7d8fc/coverage-7.14.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9eeb3fcbc13ba40dfbdb22d01d196a28e9cef9ed4c29b60061a1e0e823a9929d", size = 254008, upload-time = "2026-05-26T20:39:35.009Z" }, + { url = "https://files.pythonhosted.org/packages/42/06/36f4aa9ca8a815e6036156e80706a67828bb97bd826948244f6996dda957/coverage-7.14.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f0cfc27c539f07cf5c0a4cfe211d0b6cae039f8f40526dbaa71944e64b50a7b", size = 255241, upload-time = "2026-05-26T20:39:36.71Z" }, + { url = "https://files.pythonhosted.org/packages/ca/79/95266316352f90f6b1c6736bb413302edfde2453fb32422d3911642691b3/coverage-7.14.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:221c70f316241a78e77e607c227cefc8808d4e08f28d99c04f35694690e940be", size = 257373, upload-time = "2026-05-26T20:39:38.412Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9c/58316d1f66c488b5fca8a0eb3e98348807813efa8a0d0833b9021be27488/coverage-7.14.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:da028256b04ec30e5e0114b6f76172938c313991f0a2d3d894271315cf5d5e43", size = 251635, upload-time = "2026-05-26T20:39:40.268Z" }, + { url = "https://files.pythonhosted.org/packages/ef/5a/ca2398a568e16fed7bb713e84ba3603a7164fb65779abe645c565ec890d5/coverage-7.14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76a085d7005236a767e3426148b2c407e53ad61695c562f8a81da2d373324901", size = 253373, upload-time = "2026-05-26T20:39:42.145Z" }, + { url = "https://files.pythonhosted.org/packages/6e/2c/0396562c32deaebe7be51d865b3a41e9a87d7561acafe1a28f53b07e019a/coverage-7.14.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b553d04b5e778a8e56d57eb134aff42a92718ecba45e79c4764ecfa40efd92ff", size = 251341, upload-time = "2026-05-26T20:39:43.907Z" }, + { url = "https://files.pythonhosted.org/packages/fd/8f/a94f9221184c9cae1ee115820e3798e48b6b17777a9f19e46fb9a0c8dc74/coverage-7.14.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:46f714d2fb8ae2f4f29f23ada7f1e79b759fff5a70f94a1dac23af204c3ec9e4", size = 255497, upload-time = "2026-05-26T20:39:46.166Z" }, + { url = "https://files.pythonhosted.org/packages/71/69/505d70e47db1eaebcd002c39759707621ef184cd6b1ae084d9f41293f323/coverage-7.14.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:1896f5e19ff3f0431c7ce2172adc54890fd97f86b59ced8ca1649145d9ffe35d", size = 251159, upload-time = "2026-05-26T20:39:48.03Z" }, + { url = "https://files.pythonhosted.org/packages/e0/aa/58681c383aa33a9d2ed40a02d7a22fbf780d1fa4d575396365777828198c/coverage-7.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:62fd185ef9df3c33d1c8178c5af105f762afbad96038de9a4ae100aa6297ca33", size = 252934, upload-time = "2026-05-26T20:39:49.872Z" }, + { url = "https://files.pythonhosted.org/packages/eb/fd/11c928cd6bdffc7074bb5965c173d9ebf517fb00205e1da524b98d29ef92/coverage-7.14.1-cp313-cp313-win32.whl", hash = "sha256:ab4af6352741a604c431c6072fce5bee33bf0f20dc7a56618d6bf6bb89e9810c", size = 222584, upload-time = "2026-05-26T20:39:51.68Z" }, + { url = "https://files.pythonhosted.org/packages/6f/92/fb416fc26d340dcba19518c418d6048e913186e17243982c5e435e41fa7a/coverage-7.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:7af486dabe8954d03b087f0021540897afe084f04e16ff5579e08cc46f871416", size = 223394, upload-time = "2026-05-26T20:39:53.472Z" }, + { url = "https://files.pythonhosted.org/packages/73/c6/02d56e3867972f77d5036de924643f26c056e848f00452cafb4dbc3c29b4/coverage-7.14.1-cp313-cp313-win_arm64.whl", hash = "sha256:2224f89ffd0c5605ccce1ed7a584da162bc7c55f601ab1c946bc9de31a486b42", size = 222015, upload-time = "2026-05-26T20:39:55.374Z" }, + { url = "https://files.pythonhosted.org/packages/4d/9e/fcc77914050df73f7662fa1f00902774c79c075a8388ab334074574bf77e/coverage-7.14.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de286598cc65d2b489411174b1faec2f5a7775fb3201fd925db2a76b4030f37d", size = 220733, upload-time = "2026-05-26T20:39:57.189Z" }, + { url = "https://files.pythonhosted.org/packages/f7/67/2963cbdaf5cbadec44efa3a1e39eaa1f02df4079585f05387607a221e126/coverage-7.14.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:042c46ded7c288aeb07cf14a28b6c1e10b78fcba40171c3fa1e939377eeef0b5", size = 221086, upload-time = "2026-05-26T20:39:59.019Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c5/8701645574e11881f2f47d8930f98bc48b5d43b25eb5b4430dfc4a2f9f48/coverage-7.14.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f4ddbe407477f04c45115d1a4e5bc480f753553b534d338d4c3358b1cdd0ea52", size = 262381, upload-time = "2026-05-26T20:40:00.822Z" }, + { url = "https://files.pythonhosted.org/packages/7c/28/7a64d73598263e0c5abd5084211a8474488d31b3c552ff531c719dfcff62/coverage-7.14.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d13e6725992e2d2fd7d81d4f5241952d13740121dfd501da09201be39b2c003a", size = 264458, upload-time = "2026-05-26T20:40:02.506Z" }, + { url = "https://files.pythonhosted.org/packages/fa/d8/4969179db9f7eb4df218e69540adf829d1c835f59452513d065d15446802/coverage-7.14.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f747dc8edcfe740130f28f32f3995e955494285717e86ee25af51db2219df08a", size = 266884, upload-time = "2026-05-26T20:40:04.421Z" }, + { url = "https://files.pythonhosted.org/packages/a6/78/a45d5794dbc9bafd97afc96a4377c86c7820d78b6cf51b89bc1d4e919275/coverage-7.14.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ced2f09ef276fd58611a1ef502164ad266d2b75174e5a40cabbdb4033f9f6cf2", size = 268022, upload-time = "2026-05-26T20:40:06.298Z" }, + { url = "https://files.pythonhosted.org/packages/21/cb/4f5e354e9e3e67af96bd4e57113e6db6b22298c7168b13eec408a549903d/coverage-7.14.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b84800013769a78ccb9ef4659402e26d06867e337b61ec365f77ad008adea80e", size = 261631, upload-time = "2026-05-26T20:40:08.226Z" }, + { url = "https://files.pythonhosted.org/packages/ec/49/eced49af4cb996d5d8b7e94e736175c513e4facd3398507b89892b4326d8/coverage-7.14.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ea8cd6ca0ee9f616aaef3afc6882e32c2cbf18b00d96313ffd76af650574034d", size = 264443, upload-time = "2026-05-26T20:40:10.137Z" }, + { url = "https://files.pythonhosted.org/packages/f1/d8/5603a88a7c5913a6b54f6cb1a8c46f7b39cbb30f27cd3f492908da09b2d7/coverage-7.14.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:aa5e304a873fabddc11e484e9b6b738bd38bd7bed17b09aa84eecf5332e8b8bb", size = 262069, upload-time = "2026-05-26T20:40:11.999Z" }, + { url = "https://files.pythonhosted.org/packages/f0/59/2ae3cb79da554a06c8619d6c88ea19dd1e4aed4b834b6a83bb1fa243bdc5/coverage-7.14.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5a1c5215be81035e629d5bc756650634d0bf31991038db7a0eccb90f025ce16d", size = 265780, upload-time = "2026-05-26T20:40:13.858Z" }, + { url = "https://files.pythonhosted.org/packages/af/5f/b130c1dc999031f2648bd25317fbce505ad8d5562079b4ed81e736a84967/coverage-7.14.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:79058c47dae6788504b5effb319961bcd72d7240551464b91d474bc0ed186d69", size = 260970, upload-time = "2026-05-26T20:40:16.142Z" }, + { url = "https://files.pythonhosted.org/packages/87/d1/ec13ccddeb48ec963bdfa72a11224bac2584bd045ba13beca82f8113e9c7/coverage-7.14.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:370c5afae3fa0658e11694a32b24c2778f6bc2d17718121f94ee185e69f26b54", size = 263157, upload-time = "2026-05-26T20:40:18.382Z" }, + { url = "https://files.pythonhosted.org/packages/cf/c2/cd91ead503045161092d3845f7bb95ea2f25131ce96d3e314dd835d91b9c/coverage-7.14.1-cp313-cp313t-win32.whl", hash = "sha256:3758dd0a7f1fa57365ef2e781df0f0731d38b6e3772259d13dae4bd8a958d4b1", size = 223259, upload-time = "2026-05-26T20:40:20.381Z" }, + { url = "https://files.pythonhosted.org/packages/71/9f/1e28d97e6bd2c76b07f38b7c02870f1371255ff6717f54eca578fcbbdd0e/coverage-7.14.1-cp313-cp313t-win_amd64.whl", hash = "sha256:6ff665fb023a77386fe11685190cee1f60a7d635994a30d9b0a061533d470fce", size = 224320, upload-time = "2026-05-26T20:40:22.316Z" }, + { url = "https://files.pythonhosted.org/packages/a9/e0/d936e908f0e1efa55e52b91e01b52f1055cef5e1ab2718493390ed8e2fb8/coverage-7.14.1-cp313-cp313t-win_arm64.whl", hash = "sha256:17a5a241e5997621a956a7f402a7433ef4221e5152809b785bec79e2323799f1", size = 222577, upload-time = "2026-05-26T20:40:24.894Z" }, + { url = "https://files.pythonhosted.org/packages/d6/34/fc2f101b151af3799a101f0550b0454aa008afdc0add677394ec4aa8ea10/coverage-7.14.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d5ed429d0b8edaac649e889b4ffcedb6c80b06629a3f93050e3dddfb99235bee", size = 220091, upload-time = "2026-05-26T20:40:27.249Z" }, + { url = "https://files.pythonhosted.org/packages/3d/a7/1ebae2ab5b961b5c79bb09fe7b3ac99edb190d8be4a8c510b2cf66f46468/coverage-7.14.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8011224a62280e50dab346960c03cf47aca1a1e09e608c0fb33fd6e0cc8e9500", size = 220421, upload-time = "2026-05-26T20:40:30.084Z" }, + { url = "https://files.pythonhosted.org/packages/5e/90/92aca9cf0acc95123c96cd1eb1f08917897a7f5dee01e15738922971ec31/coverage-7.14.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:12c42ec1e14f553c4f817e989365982e646e27211f10a0f717855b94a79c8906", size = 251466, upload-time = "2026-05-26T20:40:32.542Z" }, + { url = "https://files.pythonhosted.org/packages/26/2b/78048cbe3b999f6cbf9cc0d90abba6a88a3e0863a8c1c6cbc762f3f8802f/coverage-7.14.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:06144cd511cf2624873a035c5069cf297144f6e77a73ee3d7a55b605ec5efb42", size = 253973, upload-time = "2026-05-26T20:40:34.473Z" }, + { url = "https://files.pythonhosted.org/packages/8e/21/c2e33b29d1cfde484a19d437afc343c6cd30b08d78cbbf9f5aff14e57b2b/coverage-7.14.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a311d8e1da24be5c1ccf85cbfb06315dbaa1703d5a1eab3f6432c72b837917c8", size = 255318, upload-time = "2026-05-26T20:40:38.154Z" }, + { url = "https://files.pythonhosted.org/packages/8e/ee/aad2f108d63b769121005302f16bf66db8625c88ceaba466942e09a2607e/coverage-7.14.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c79cead5b5bc584d9c71451cb984d0e3a84e0c0937379c8efcbf27c8d661b851", size = 257633, upload-time = "2026-05-26T20:40:40.164Z" }, + { url = "https://files.pythonhosted.org/packages/c2/f8/11a2c29b4fd76d9849f81d0bb812ec0017a9396df3217214e38934a8c837/coverage-7.14.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dcbf65f1f66a26cdd88c35cf68fb4729c5d1cd2e88added72420541dfb212034", size = 251488, upload-time = "2026-05-26T20:40:42.631Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b8/9a5820de4b8ac2b71d85e3b5fb49108d7469c665f0e2ad0dd7569023e305/coverage-7.14.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fd86572566fb40189a8260446158235159bc7a82dfbc87a3b39cf4fb57fcec1c", size = 253329, upload-time = "2026-05-26T20:40:45.208Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ff/f33e4823667e27548e8fd8df44217515303f9808d0ff29817db56f87d990/coverage-7.14.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:7771b601718fdde84832c3a434ca9bbf4ae9adbc49d84198b4110700c3c77c36", size = 251291, upload-time = "2026-05-26T20:40:47.502Z" }, + { url = "https://files.pythonhosted.org/packages/68/9b/489db0ebb209054766b90a9014a45f6d26eb724c02ec21311c3733b5a644/coverage-7.14.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:39b21e212c55af06fa375e3dbf90a8a8e38792f3a910c580066d23563830ddd5", size = 255564, upload-time = "2026-05-26T20:40:49.372Z" }, + { url = "https://files.pythonhosted.org/packages/27/b5/16bc2d4c2409b23c7737edb68c83bc89e345f378050549fe1d75ac7d34d5/coverage-7.14.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f2302660e32562a532b442480121aef8aa61a5bdb20b30bf0adab29f10a5a4b4", size = 251107, upload-time = "2026-05-26T20:40:51.677Z" }, + { url = "https://files.pythonhosted.org/packages/7d/0c/2629997469a00cd069d588a41c9dc887610f2775ae89d250c4791e65272a/coverage-7.14.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:03a6f93c1ec3b7f2e77b5dbcc5573a2c21f12529a5c6bbe0f16f72303cc2fa4d", size = 252764, upload-time = "2026-05-26T20:40:54.267Z" }, + { url = "https://files.pythonhosted.org/packages/d2/ee/f78d63c8f079e0d7211c7e2401fa17e311514534ba61bae03e4b287ce4ab/coverage-7.14.1-cp314-cp314-win32.whl", hash = "sha256:8a3ce026d73290f42f08dafecbd82c193a74df280461fbf97300fec51fd133ee", size = 222837, upload-time = "2026-05-26T20:40:56.496Z" }, + { url = "https://files.pythonhosted.org/packages/dc/b9/be539854f93a70dfbeec69117f33ec70dc42ff0b65b5b07ab8d40d04228e/coverage-7.14.1-cp314-cp314-win_amd64.whl", hash = "sha256:114c95ef29302423b87d159075805f4ab973254a2638a5d7d046c94887cc87d7", size = 223650, upload-time = "2026-05-26T20:40:58.351Z" }, + { url = "https://files.pythonhosted.org/packages/fe/9e/24e2842fef40f35ac82ba3a7719c8023d011bf3bf652d0675316a9d088a1/coverage-7.14.1-cp314-cp314-win_arm64.whl", hash = "sha256:a07891c3f4805442b31b71e84ba3cf29ed1aa9a428284e06deeb4b23e5b46343", size = 222218, upload-time = "2026-05-26T20:41:00.321Z" }, + { url = "https://files.pythonhosted.org/packages/0a/1d/ac0a9df5fe31c1e8bdd658074905fc12844a05c1a7e3fdb8417e97c31e23/coverage-7.14.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1101a5ebb083aecb625ebb6209d4105b58f647b093cb2dc8122d7b33f743cfe1", size = 220822, upload-time = "2026-05-26T20:41:02.281Z" }, + { url = "https://files.pythonhosted.org/packages/32/cf/f964fd9aff20323f9f1a726c97135f8a76bcd87b92dad141a456a43f3c64/coverage-7.14.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:851b9e1e4e8a4608e77c79714b2e77c0970d2ed7202a05e92ae407817481887b", size = 221084, upload-time = "2026-05-26T20:41:04.593Z" }, + { url = "https://files.pythonhosted.org/packages/d8/5e/7e5ef2aba844de2b80d678619fcf0841b42e3f37f16411226f3fe4c1016f/coverage-7.14.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d5b89cdfb2ee051b71e8c3c70bd81a9eff81100f736a269136fe1a68efe00474", size = 262454, upload-time = "2026-05-26T20:41:06.641Z" }, + { url = "https://files.pythonhosted.org/packages/64/62/75809bded87015cc4935524218a2a8ed8dd1a8498bfed30a2f4f7a4b4d34/coverage-7.14.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0177614a0370f227888b4e436a7c55686d6a9f90eb1ade2b624ba685a1686e86", size = 264578, upload-time = "2026-05-26T20:41:08.556Z" }, + { url = "https://files.pythonhosted.org/packages/f3/42/d33392dc14633525012d2d504fa1a33b05538bf535f5c1d64675e5754b78/coverage-7.14.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2d69af5dea2de76fc485a83032a630523f985198b7e25be901ec60181587b01e", size = 266981, upload-time = "2026-05-26T20:41:10.824Z" }, + { url = "https://files.pythonhosted.org/packages/2a/49/0157c4428c2aca7f1e09d5565930586fd5ae36f1655f08b0daa7cf1fcae1/coverage-7.14.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:35ab22d91de736e8966b980dc355cbcdd2c6dbbcfe275f9a2991bc8a91b3df65", size = 268112, upload-time = "2026-05-26T20:41:12.966Z" }, + { url = "https://files.pythonhosted.org/packages/96/26/86b9ce71f4092b1ed325ce1421698081df1286b833400b6836912834d6e0/coverage-7.14.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:357d4e32935c36588aaba057d734fa32428c360c9fc2e4442afbf1b646beee6e", size = 261558, upload-time = "2026-05-26T20:41:15Z" }, + { url = "https://files.pythonhosted.org/packages/20/4c/c311210c5472cf5401d8422b0d7812cdd520f24417673afabda6c323faca/coverage-7.14.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:51bd64741cc6fa065abd300ede1afe5a5291ece9c31da8b24884deda48bcc3f8", size = 264447, upload-time = "2026-05-26T20:41:17.369Z" }, + { url = "https://files.pythonhosted.org/packages/fb/71/59513f8710ed3e6b0ac0a050a5b7e977bb9c9e880354863b5d00d8809256/coverage-7.14.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:9132cd363a68a4c3daa7c8704a654b1e39d3360f6f5b8ddd470608a945236c07", size = 262048, upload-time = "2026-05-26T20:41:19.309Z" }, + { url = "https://files.pythonhosted.org/packages/84/8d/bceed32dc494f5bbf50f775cd2e78ca814953942b5ea28d3c1c3ac316f14/coverage-7.14.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:07c6290b1697b862c0478eab545eec949a0d0e4d6d03497f446d706da3b4f2de", size = 265781, upload-time = "2026-05-26T20:41:21.559Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c5/9348fe40dbfd4991aaf78df2c6c3098bfb2cc834d1fd362a64b4efef855a/coverage-7.14.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5ea0c297e27133853b4d8a3eb799bff5a2dbd9f2f41537a240d337ac9b4df890", size = 260896, upload-time = "2026-05-26T20:41:23.428Z" }, + { url = "https://files.pythonhosted.org/packages/ca/92/1ea0f03929da7cf87206b1fa24f4c8e9c158be0455481af29ec0a1f3503f/coverage-7.14.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:01b7733daad0237daa01ef80fe2dfceffc911e6a17fa7b55d14aa8214eaaaecd", size = 263214, upload-time = "2026-05-26T20:41:25.419Z" }, + { url = "https://files.pythonhosted.org/packages/f6/a9/b2493c054c0e01a643266742ab45e15744e60743f9260cd930c7142b1124/coverage-7.14.1-cp314-cp314t-win32.whl", hash = "sha256:6adc5a36984624a70bf11d7184e20fa0a49aa7c47ffab43804106a1a695ea22e", size = 223624, upload-time = "2026-05-26T20:41:27.795Z" }, + { url = "https://files.pythonhosted.org/packages/fc/bd/3e1e6a57fccd2d7c83fcdf338e93ba98eb85c6e877dd34731ac585375490/coverage-7.14.1-cp314-cp314t-win_amd64.whl", hash = "sha256:ddf799247318f34dbcd2efa8c95a8d0642674e926bb1774cf9b63dfd2a389d1c", size = 224728, upload-time = "2026-05-26T20:41:30.098Z" }, + { url = "https://files.pythonhosted.org/packages/bb/d7/31066cf1d2f0c6c797fce911bcfa01dd35642dc6da992a950256097c5860/coverage-7.14.1-cp314-cp314t-win_arm64.whl", hash = "sha256:145986fe66647eb489f18d9a997567a3fd358584c4b5a808769113abc07466af", size = 222752, upload-time = "2026-05-26T20:41:32.123Z" }, + { url = "https://files.pythonhosted.org/packages/8a/3c/1a983b9a745d7f83d53f057bcc5bf79ba6a2bbc08266b3f0c7d6fe630c9b/coverage-7.14.1-py3-none-any.whl", hash = "sha256:a252f21c27e38347e60111a3266b03827422a7d5525951aceee313aa68bab1d2", size = 211815, upload-time = "2026-05-26T20:41:34.078Z" }, ] [[package]] @@ -229,7 +229,7 @@ version = "0.4.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, ] [[package]] @@ -238,45 +238,45 @@ version = "1.9.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, ] [[package]] name = "duckdb" -version = "1.5.2" +version = "1.5.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0c/66/744b4931b799a42f8cb9bc7a6f169e7b8e51195b62b246db407fd90bf15f/duckdb-1.5.2.tar.gz", hash = "sha256:638da0d5102b6cb6f7d47f83d0600708ac1d3cb46c5e9aaabc845f9ba4d69246", size = 18017166, upload-time = "2026-04-13T11:30:09.065Z" } +sdist = { url = "https://files.pythonhosted.org/packages/69/00/d579dcb2a536b6ea3a2563cdad6844f77d81a9b2d4b22a858097f2468acf/duckdb-1.5.3.tar.gz", hash = "sha256:df39428eb130faa35ae96fd35245bdeae6ecf43936250b116b5fead568eb9f16", size = 18026640, upload-time = "2026-05-20T11:55:31.901Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/98/f2/e3d742808f138d374be4bb516fade3d1f33749b813650810ab7885cdc363/duckdb-1.5.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:4420b3f47027a7849d0e1815532007f377fa95ee5810b47ea717d35525c12f79", size = 30064879, upload-time = "2026-04-13T11:29:30.763Z" }, - { url = "https://files.pythonhosted.org/packages/72/0d/f3dc1cf97e1267ca15e4307d456f96ce583961f0703fd75e62b2ad8d64fa/duckdb-1.5.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:bb42e6ed543902e14eae647850da24103a89f0bc2587dec5601b1c1f213bd2ed", size = 15969327, upload-time = "2026-04-13T11:29:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e0/d5418def53ae4e05a63075705ff44ed5af5a1a5932627eb2b600c5df1c93/duckdb-1.5.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:98c0535cd6d901f61a5ea3c2e26a1fd28482953d794deb183daf568e3aa5dda6", size = 14225107, upload-time = "2026-04-13T11:29:35.882Z" }, - { url = "https://files.pythonhosted.org/packages/16/a7/15aaa59dbecc35e9711980fcdbf525b32a52470b32d18ef678193a146213/duckdb-1.5.2-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:486c862bf7f163c0110b6d85b3e5c031d224a671cca468f12ebb1d3a348f6b39", size = 19313433, upload-time = "2026-04-13T11:29:38.367Z" }, - { url = "https://files.pythonhosted.org/packages/bd/21/d903cc63a5140c822b7b62b373a87dc557e60c29b321dfb435061c5e67cf/duckdb-1.5.2-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:70631c847ca918ee710ec874241b00cf9d2e5be90762cbb2a0389f17823c08f7", size = 21429837, upload-time = "2026-04-13T11:29:41.135Z" }, - { url = "https://files.pythonhosted.org/packages/e3/0a/b770d1f60c70597302130d6247f418549b7094251a02348fbaf1c7e147ae/duckdb-1.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:52a21823f3fbb52f0f0e5425e20b07391ad882464b955879499b5ff0b45a376b", size = 13107699, upload-time = "2026-04-13T11:29:43.905Z" }, - { url = "https://files.pythonhosted.org/packages/d9/cf/e200fe431d700962d1a908d2ce89f53ccee1cc8db260174ae663ba09686b/duckdb-1.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:411ad438bd4140f189a10e7f515781335962c5d18bd07837dc6d202e3985253d", size = 13927646, upload-time = "2026-04-13T11:29:46.598Z" }, - { url = "https://files.pythonhosted.org/packages/83/a1/f6286c67726cc1ea60a6e3c0d9fbc66527dde24ae089a51bbe298b13ca78/duckdb-1.5.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:6b0fe75c148000f060aa1a27b293cacc0ea08cc1cad724fbf2143d56070a3785", size = 30078598, upload-time = "2026-04-13T11:29:49.828Z" }, - { url = "https://files.pythonhosted.org/packages/de/6a/59febb02f21a4a5c6b0b0099ef7c965fdd5e61e4904cf813809bb792e35f/duckdb-1.5.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:35579b8e3a064b5eaf15b0eafc558056a13f79a0a62e34cc4baf57119daecfec", size = 15975120, upload-time = "2026-04-13T11:29:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/09/70/ce750854d37bb5a45cccbb2c3cb04df4af56aea8fc30a2499bb643b4a9c0/duckdb-1.5.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ea58ff5b0880593a280cf5511734b17711b32ee1f58b47d726e8600848358160", size = 14227762, upload-time = "2026-04-13T11:29:55.564Z" }, - { url = "https://files.pythonhosted.org/packages/28/dc/ad45ac3c0b6c4687dc649e8f6cf01af1c8b0443932a39b2abb4ebcb3babd/duckdb-1.5.2-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef461bca07313412dc09961c4a4757a851f56b95ac01c58fac6007632b7b94f2", size = 19315668, upload-time = "2026-04-13T11:29:58.427Z" }, - { url = "https://files.pythonhosted.org/packages/cc/b1/1464f468d2e5813f5808de95df9d3113a645a5bfa2ffcaecbc542ddae272/duckdb-1.5.2-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:be37680ddb380015cb37318e378c53511c45c4f0d8fac5599d22b7d092b9217a", size = 21434056, upload-time = "2026-04-13T11:30:01.238Z" }, - { url = "https://files.pythonhosted.org/packages/ce/32/6673607e024722473fa7aafdd29c0e3dd231dd528f6cd8b5797fbeeb229d/duckdb-1.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:0b291786014df1133f8f18b9df4d004484613146e858d71a21791e0fcca16cf4", size = 13633667, upload-time = "2026-04-13T11:30:04.05Z" }, - { url = "https://files.pythonhosted.org/packages/7a/e3/9d34173ec068631faea3ea6e73050700729363e7e33306a9a3218e5cdc61/duckdb-1.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:c9f3e0b71b8a50fccfb42794899285d9d318ce2503782b9dd54868e5ecd0ad31", size = 14402513, upload-time = "2026-04-13T11:30:06.609Z" }, + { url = "https://files.pythonhosted.org/packages/cc/9c/a528eb09d8be51954c485864bd06753e616939a080cbc3dd4417e8c94a57/duckdb-1.5.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e75a6122c12579a99848517f6f00a4e342aebda3590c30fe9b5cc5f39d5e6afc", size = 32626254, upload-time = "2026-05-20T11:54:53.65Z" }, + { url = "https://files.pythonhosted.org/packages/ec/3c/1534c0a6db347c05eb7d0f6ecfb7aefbe74cbff398e4892a8fd1903a20e8/duckdb-1.5.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fd3963c1cb9d9567777f4a898a9dbe388a2fe9724681801b1e7d6d93eecf1b76", size = 17300917, upload-time = "2026-05-20T11:54:56.628Z" }, + { url = "https://files.pythonhosted.org/packages/23/fa/beafb91e6e152d2161c4a9cbc472334c87607eb61ad7104b5a7fa8d8d7b1/duckdb-1.5.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3d5db8c0b55e072cf437948ebb5d7e23d7b9d03d905fa5f9145583e65aa447f7", size = 15449411, upload-time = "2026-05-20T11:54:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/50/0a/49b6fe04e2fcd63729eb607dadd44818dde77342a4f5ce086c6c92f1dd4d/duckdb-1.5.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ce80aed7a538422129a57eaca9141e3afb51f8bf562b1908b1576c9725b5b22", size = 19333120, upload-time = "2026-05-20T11:55:01.727Z" }, + { url = "https://files.pythonhosted.org/packages/63/4c/0907c3f76adb9dd90e67610b31e0304a35814e65c4c41a354a262c09b885/duckdb-1.5.3-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:787df63824f07bf18022dbc3b8ca4b2bfab0ebe616464f55c6e8cd0f59ea762e", size = 21453266, upload-time = "2026-05-20T11:55:04.5Z" }, + { url = "https://files.pythonhosted.org/packages/6d/9c/d2f23a7803ddbbd9413f7572ecf66a15120ed5ced7ce5c73e698c1406b76/duckdb-1.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:bb5bb5dcdd09d62ee60f0ddbbef918e71cce304ffe28428b1131949d39ffaabf", size = 13118640, upload-time = "2026-05-20T11:55:07.389Z" }, + { url = "https://files.pythonhosted.org/packages/27/d5/7ba2316415bcdab6edd765bbbe35c2ca8a3800f2fe695cd70e3cdb997f09/duckdb-1.5.3-cp313-cp313-win_arm64.whl", hash = "sha256:2fa17ecdd5d3db122836cb71bb93601c2106a3be883c17dffddc02fbf3fa7888", size = 13926409, upload-time = "2026-05-20T11:55:10.166Z" }, + { url = "https://files.pythonhosted.org/packages/a5/c2/d4b6f8a5e4d3bc25773be6da76a99d9661ebbf3552c007c460d2dd59dbf8/duckdb-1.5.3-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:4bfa9a4dadf71e83e2c4eaca2f9421c82a54defecc1b0b4c0be95e2389dec4fe", size = 32636685, upload-time = "2026-05-20T11:55:13.158Z" }, + { url = "https://files.pythonhosted.org/packages/42/58/e835c8298979d29db7a62cb5acc29e9b57aeaca7cdde2fcd3ac980f5cb18/duckdb-1.5.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:aea7baf67ad7e1829ac76f67d7dcbd7fb1f57c3eb179d55ac30952df4709ae30", size = 17308134, upload-time = "2026-05-20T11:55:16.194Z" }, + { url = "https://files.pythonhosted.org/packages/c9/46/617b51363f5613418c8b224b3cce16b58e6dde80904566bec232579c1d4e/duckdb-1.5.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b0b4f088a65d77e1217ce5d7eff889e63fedc44281200d899ff47c84d8ff836", size = 15449891, upload-time = "2026-05-20T11:55:18.687Z" }, + { url = "https://files.pythonhosted.org/packages/b3/72/354146656e8d9ba3853d3a5ee80a481b8c5f70edfc3d5ae80a8c4479c967/duckdb-1.5.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe8d0c1f6a120aa03fa6e0d03897c71a1842e6cf7afd31d181348391f7108fe1", size = 19338499, upload-time = "2026-05-20T11:55:21.34Z" }, + { url = "https://files.pythonhosted.org/packages/56/8f/65fc623b51448f2bfba1a9ec6ab3debb4664c0876c0113a5e782600b53ac/duckdb-1.5.3-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0405eae18ec6e8210a471c97dbfe87a7e4d605274b7fe572a1f276e92158f13", size = 21455828, upload-time = "2026-05-20T11:55:23.847Z" }, + { url = "https://files.pythonhosted.org/packages/2b/db/d0274cbe9f5fe219f77c0bdf900ac77103569e83c102a4225ce04cbc607d/duckdb-1.5.3-cp314-cp314-win_amd64.whl", hash = "sha256:33ae08b3e818d7613d8936744b67718c2062c2f530376895bfd89efb51b81538", size = 13640011, upload-time = "2026-05-20T11:55:26.276Z" }, + { url = "https://files.pythonhosted.org/packages/07/5d/8f1899b8bef291caf953992fcd6c24df9f29387a35645e58c2504a5ca473/duckdb-1.5.3-cp314-cp314-win_arm64.whl", hash = "sha256:746433e49bbc667b4df283153415fbe37e9083e0eff6c3cd6e54de7536869cd4", size = 14411554, upload-time = "2026-05-20T11:55:29.037Z" }, ] [[package]] name = "fastapi" -version = "0.136.1" +version = "0.136.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "annotated-doc" }, - { name = "pydantic" }, - { name = "starlette" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, + { name = "annotated-doc" }, + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5d/45/c130091c2dfa061bbfe3150f2a5091ef1adf149f2a8d2ae769ecaf6e99a2/fastapi-0.136.1.tar.gz", hash = "sha256:7af665ad7acfa0a3baf8983d393b6b471b9da10ede59c60045f49fbc89a0fa7f", size = 397448, upload-time = "2026-04-23T16:49:44.046Z" } +sdist = { url = "https://files.pythonhosted.org/packages/81/2d/ff8d91d7b564d464629a0fd50a4489c97fcb836ac230bf3a7269232a9b1f/fastapi-0.136.3.tar.gz", hash = "sha256:e487fae93ad408e6f47641ee4dfe389864fd7bec92e547ea8498fc13f43e83ab", size = 396410, upload-time = "2026-05-23T18:53:15.192Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/ff/2e4eca3ade2c22fe1dea7043b8ee9dabe47753349eb1b56a202de8af6349/fastapi-0.136.1-py3-none-any.whl", hash = "sha256:a6e9d7eeada96c93a4d69cb03836b44fa34e2854accb7244a1ece36cd4781c3f", size = 117683, upload-time = "2026-04-23T16:49:42.437Z" }, + { url = "https://files.pythonhosted.org/packages/e0/82/45359b62a067409bd929ae8a56b8ed13e5a8c8a61194b3c236920999ab83/fastapi-0.136.3-py3-none-any.whl", hash = "sha256:3d2a69bdf04b7e9f3afa292c3bc7a98816bbfafa10bc9b45f3f3700d2f761620", size = 117481, upload-time = "2026-05-23T18:53:16.924Z" }, ] [[package]] @@ -285,16 +285,16 @@ version = "3.29.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b5/fe/997687a931ab51049acce6fa1f23e8f01216374ea81374ddee763c493db5/filelock-3.29.0.tar.gz", hash = "sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90", size = 57571, upload-time = "2026-04-19T15:39:10.068Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl", hash = "sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258", size = 39812, upload-time = "2026-04-19T15:39:08.752Z" }, + { url = "https://files.pythonhosted.org/packages/81/47/dd9a212ef6e343a6857485ffe25bba537304f1913bdbed446a23f7f592e1/filelock-3.29.0-py3-none-any.whl", hash = "sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258", size = 39812, upload-time = "2026-04-19T15:39:08.752Z" }, ] [[package]] name = "fsspec" -version = "2026.3.0" +version = "2026.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e1/cf/b50ddf667c15276a9ab15a70ef5f257564de271957933ffea49d2cdbcdfb/fsspec-2026.3.0.tar.gz", hash = "sha256:1ee6a0e28677557f8c2f994e3eea77db6392b4de9cd1f5d7a9e87a0ae9d01b41", size = 313547, upload-time = "2026-03-27T19:11:14.892Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d5/8d/1c51c094345df128ca4a990d633fe1a0ff28726c9e6b3c41ba65087bba1d/fsspec-2026.4.0.tar.gz", hash = "sha256:301d8ac70ae90ef3ad05dcf94d6c3754a097f9b5fe4667d2787aa359ec7df7e4", size = 312760, upload-time = "2026-04-29T20:42:38.635Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/1f/5f4a3cd9e4440e9d9bc78ad0a91a1c8d46b4d429d5239ebe6793c9fe5c41/fsspec-2026.3.0-py3-none-any.whl", hash = "sha256:d2ceafaad1b3457968ed14efa28798162f1638dbb5d2a6868a2db002a5ee39a4", size = 202595, upload-time = "2026-03-27T19:11:13.595Z" }, + { url = "https://files.pythonhosted.org/packages/d5/0c/043d5e551459da400957a1395e0febbf771446ff34291afcbe3d8be2a279/fsspec-2026.4.0-py3-none-any.whl", hash = "sha256:11ef7bb35dab8a394fde6e608221d5cf3e8499401c249bebaeaad760a1a8dec2", size = 203402, upload-time = "2026-04-29T20:42:36.842Z" }, ] [[package]] @@ -303,39 +303,39 @@ version = "0.16.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] [[package]] name = "hf-xet" -version = "1.4.3" +version = "1.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/53/92/ec9ad04d0b5728dca387a45af7bc98fbb0d73b2118759f5f6038b61a57e8/hf_xet-1.4.3.tar.gz", hash = "sha256:8ddedb73c8c08928c793df2f3401ec26f95be7f7e516a7bee2fbb546f6676113", size = 670477, upload-time = "2026-03-31T22:40:07.874Z" } +sdist = { url = "https://files.pythonhosted.org/packages/74/d8/5c06fc76461418326a7decf8367480c35be11a41fd938633929c60a9ec6b/hf_xet-1.5.0.tar.gz", hash = "sha256:e0fb0a34d9f406eed88233e829a67ec016bec5af19e480eac65a233ea289a948", size = 837196, upload-time = "2026-05-06T06:18:15.583Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/72/43/724d307b34e353da0abd476e02f72f735cdd2bc86082dee1b32ea0bfee1d/hf_xet-1.4.3-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:7551659ba4f1e1074e9623996f28c3873682530aee0a846b7f2f066239228144", size = 3800935, upload-time = "2026-03-31T22:39:49.618Z" }, - { url = "https://files.pythonhosted.org/packages/2b/d2/8bee5996b699262edb87dbb54118d287c0e1b2fc78af7cdc41857ba5e3c4/hf_xet-1.4.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:bee693ada985e7045997f05f081d0e12c4c08bd7626dc397f8a7c487e6c04f7f", size = 3558942, upload-time = "2026-03-31T22:39:47.938Z" }, - { url = "https://files.pythonhosted.org/packages/c3/a1/e993d09cbe251196fb60812b09a58901c468127b7259d2bf0f68bf6088eb/hf_xet-1.4.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:21644b404bb0100fe3857892f752c4d09642586fd988e61501c95bbf44b393a3", size = 4207657, upload-time = "2026-03-31T22:39:39.69Z" }, - { url = "https://files.pythonhosted.org/packages/64/44/9eb6d21e5c34c63e5e399803a6932fa983cabdf47c0ecbcfe7ea97684b8c/hf_xet-1.4.3-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:987f09cfe418237812896a6736b81b1af02a3a6dcb4b4944425c4c4fca7a7cf8", size = 3986765, upload-time = "2026-03-31T22:39:37.936Z" }, - { url = "https://files.pythonhosted.org/packages/ea/7b/8ad6f16fdb82f5f7284a34b5ec48645bd575bdcd2f6f0d1644775909c486/hf_xet-1.4.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:60cf7fc43a99da0a853345cf86d23738c03983ee5249613a6305d3e57a5dca74", size = 4188162, upload-time = "2026-03-31T22:39:58.382Z" }, - { url = "https://files.pythonhosted.org/packages/1b/c4/39d6e136cbeea9ca5a23aad4b33024319222adbdc059ebcda5fc7d9d5ff4/hf_xet-1.4.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2815a49a7a59f3e2edf0cf113ae88e8cb2ca2a221bf353fb60c609584f4884d4", size = 4424525, upload-time = "2026-03-31T22:40:00.225Z" }, - { url = "https://files.pythonhosted.org/packages/46/f2/adc32dae6bdbc367853118b9878139ac869419a4ae7ba07185dc31251b76/hf_xet-1.4.3-cp313-cp313t-win_amd64.whl", hash = "sha256:42ee323265f1e6a81b0e11094564fb7f7e0ec75b5105ffd91ae63f403a11931b", size = 3671610, upload-time = "2026-03-31T22:40:10.42Z" }, - { url = "https://files.pythonhosted.org/packages/e2/19/25d897dcc3f81953e0c2cde9ec186c7a0fee413eb0c9a7a9130d87d94d3a/hf_xet-1.4.3-cp313-cp313t-win_arm64.whl", hash = "sha256:27c976ba60079fb8217f485b9c5c7fcd21c90b0367753805f87cb9f3cdc4418a", size = 3528529, upload-time = "2026-03-31T22:40:09.106Z" }, - { url = "https://files.pythonhosted.org/packages/ec/36/3e8f85ca9fe09b8de2b2e10c63b3b3353d7dda88a0b3d426dffbe7b8313b/hf_xet-1.4.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:5251d5ece3a81815bae9abab41cf7ddb7bcb8f56411bce0827f4a3071c92fdc6", size = 3801019, upload-time = "2026-03-31T22:39:56.651Z" }, - { url = "https://files.pythonhosted.org/packages/b5/9c/defb6cb1de28bccb7bd8d95f6e60f72a3d3fa4cb3d0329c26fb9a488bfe7/hf_xet-1.4.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1feb0f3abeacee143367c326a128a2e2b60868ec12a36c225afb1d6c5a05e6d2", size = 3558746, upload-time = "2026-03-31T22:39:54.766Z" }, - { url = "https://files.pythonhosted.org/packages/c1/bd/8d001191893178ff8e826e46ad5299446e62b93cd164e17b0ffea08832ec/hf_xet-1.4.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8b301fc150290ca90b4fccd079829b84bb4786747584ae08b94b4577d82fb791", size = 4207692, upload-time = "2026-03-31T22:39:46.246Z" }, - { url = "https://files.pythonhosted.org/packages/ce/48/6790b402803250e9936435613d3a78b9aaeee7973439f0918848dde58309/hf_xet-1.4.3-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:d972fbe95ddc0d3c0fc49b31a8a69f47db35c1e3699bf316421705741aab6653", size = 3986281, upload-time = "2026-03-31T22:39:44.648Z" }, - { url = "https://files.pythonhosted.org/packages/51/56/ea62552fe53db652a9099eda600b032d75554d0e86c12a73824bfedef88b/hf_xet-1.4.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c5b48db1ee344a805a1b9bd2cda9b6b65fe77ed3787bd6e87ad5521141d317cd", size = 4187414, upload-time = "2026-03-31T22:40:04.951Z" }, - { url = "https://files.pythonhosted.org/packages/7d/f5/bc1456d4638061bea997e6d2db60a1a613d7b200e0755965ec312dc1ef79/hf_xet-1.4.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:22bdc1f5fb8b15bf2831440b91d1c9bbceeb7e10c81a12e8d75889996a5c9da8", size = 4424368, upload-time = "2026-03-31T22:40:06.347Z" }, - { url = "https://files.pythonhosted.org/packages/e4/76/ab597bae87e1f06d18d3ecb8ed7f0d3c9a37037fc32ce76233d369273c64/hf_xet-1.4.3-cp314-cp314t-win_amd64.whl", hash = "sha256:0392c79b7cf48418cd61478c1a925246cf10639f4cd9d94368d8ca1e8df9ea07", size = 3672280, upload-time = "2026-03-31T22:40:16.401Z" }, - { url = "https://files.pythonhosted.org/packages/62/05/2e462d34e23a09a74d73785dbed71cc5dbad82a72eee2ad60a72a554155d/hf_xet-1.4.3-cp314-cp314t-win_arm64.whl", hash = "sha256:681c92a07796325778a79d76c67011764ecc9042a8c3579332b61b63ae512075", size = 3528945, upload-time = "2026-03-31T22:40:14.995Z" }, - { url = "https://files.pythonhosted.org/packages/ac/9f/9c23e4a447b8f83120798f9279d0297a4d1360bdbf59ef49ebec78fe2545/hf_xet-1.4.3-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:d0da85329eaf196e03e90b84c2d0aca53bd4573d097a75f99609e80775f98025", size = 3805048, upload-time = "2026-03-31T22:39:53.105Z" }, - { url = "https://files.pythonhosted.org/packages/0b/f8/7aacb8e5f4a7899d39c787b5984e912e6c18b11be136ef13947d7a66d265/hf_xet-1.4.3-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:e23717ce4186b265f69afa66e6f0069fe7efbf331546f5c313d00e123dc84583", size = 3562178, upload-time = "2026-03-31T22:39:51.295Z" }, - { url = "https://files.pythonhosted.org/packages/df/9a/a24b26dc8a65f0ecc0fe5be981a19e61e7ca963b85e062c083f3a9100529/hf_xet-1.4.3-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fc360b70c815bf340ed56c7b8c63aacf11762a4b099b2fe2c9bd6d6068668c08", size = 4212320, upload-time = "2026-03-31T22:39:42.922Z" }, - { url = "https://files.pythonhosted.org/packages/53/60/46d493db155d2ee2801b71fb1b0fd67696359047fdd8caee2c914cc50c79/hf_xet-1.4.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:39f2d2e9654cd9b4319885733993807aab6de9dfbd34c42f0b78338d6617421f", size = 3991546, upload-time = "2026-03-31T22:39:41.335Z" }, - { url = "https://files.pythonhosted.org/packages/bc/f5/067363e1c96c6b17256910830d1b54099d06287e10f4ec6ec4e7e08371fc/hf_xet-1.4.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:49ad8a8cead2b56051aa84d7fce3e1335efe68df3cf6c058f22a65513885baac", size = 4193200, upload-time = "2026-03-31T22:40:01.936Z" }, - { url = "https://files.pythonhosted.org/packages/42/4b/53951592882d9c23080c7644542fda34a3813104e9e11fa1a7d82d419cb8/hf_xet-1.4.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7716d62015477a70ea272d2d68cd7cad140f61c52ee452e133e139abfe2c17ba", size = 4429392, upload-time = "2026-03-31T22:40:03.492Z" }, - { url = "https://files.pythonhosted.org/packages/8a/21/75a6c175b4e79662ad8e62f46a40ce341d8d6b206b06b4320d07d55b188c/hf_xet-1.4.3-cp37-abi3-win_amd64.whl", hash = "sha256:6b591fcad34e272a5b02607485e4f2a1334aebf1bc6d16ce8eb1eb8978ac2021", size = 3677359, upload-time = "2026-03-31T22:40:13.619Z" }, - { url = "https://files.pythonhosted.org/packages/8a/7c/44314ecd0e89f8b2b51c9d9e5e7a60a9c1c82024ac471d415860557d3cd8/hf_xet-1.4.3-cp37-abi3-win_arm64.whl", hash = "sha256:7c2c7e20bcfcc946dc67187c203463f5e932e395845d098cc2a93f5b67ca0b47", size = 3533664, upload-time = "2026-03-31T22:40:12.152Z" }, + { url = "https://files.pythonhosted.org/packages/68/9b/6912c99070915a4f28119e3c5b52a9abd1eec0ad5cb293b8c967a0c6f5a2/hf_xet-1.5.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:7d70fe2ce97b9db73b9c9b9c81fe3693640aec83416a966c446afea54acfae3c", size = 4023383, upload-time = "2026-05-06T06:17:53.947Z" }, + { url = "https://files.pythonhosted.org/packages/0f/6d/9563cfde59b5d8128a9c7ec972a087f4c782e4f7bac5a85234edfd5d5e49/hf_xet-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:73a0dae8c71de3b0633a45c73f4a4a5ed09e94b43441d82981a781d4f12baa42", size = 3792751, upload-time = "2026-05-06T06:17:51.791Z" }, + { url = "https://files.pythonhosted.org/packages/07/a5/ed5a0cf35b49a0571af5a8f53416dad1877a718c021c9937c3a53cb45781/hf_xet-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a60290ec57e9b71767fba7c3645ddafdd0759974b540441510c629c6db6db24a", size = 4456058, upload-time = "2026-05-06T06:17:40.735Z" }, + { url = "https://files.pythonhosted.org/packages/60/fb/3ae8bf2a7a37a4197d0195d7247fd25b3952e15cb8a599e285dfaa6f52b3/hf_xet-1.5.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:e5de0f6deada0dada870bb376a11bcd1f08abf3a968a6d118f33e72d1b1eb480", size = 4250783, upload-time = "2026-05-06T06:17:38.412Z" }, + { url = "https://files.pythonhosted.org/packages/a2/9b/8bae40d4d91525085137196e84eb0ed49cf65b5e96e5c3ecdadd8bd0fac2/hf_xet-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c799d49f1a5544a0ef7591c0ee75e0d6b93d6f56dc7a4979f59f7518d2872216", size = 4445594, upload-time = "2026-05-06T06:18:04.219Z" }, + { url = "https://files.pythonhosted.org/packages/13/59/c74efbbd4e8728172b2cc72a2bc014d2947a4b7bdced932fbd3f5da1a4e5/hf_xet-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2baea1b0b989e5c152fe81425f7745ddc8901280ba3d97c98d8cdece7b706c60", size = 4663995, upload-time = "2026-05-06T06:18:06.1Z" }, + { url = "https://files.pythonhosted.org/packages/73/32/8e1e0410af64cda9b139d1dcebdc993a8ff9c8c7c0e2696ae356d75ccc0d/hf_xet-1.5.0-cp313-cp313t-win_amd64.whl", hash = "sha256:526345b3ed45f374f6317349df489167606736c876241ba984105afe7fd4839d", size = 3966608, upload-time = "2026-05-06T06:18:19.74Z" }, + { url = "https://files.pythonhosted.org/packages/fc/34/a8febc8f4edbea8b3e21b02ebc8b628679b84ba7e45cde624a7736b51500/hf_xet-1.5.0-cp313-cp313t-win_arm64.whl", hash = "sha256:786d28e2eb8315d5035544b9d137b4a842d600c434bb91bf7d0d953cce906ad4", size = 3796946, upload-time = "2026-05-06T06:18:17.568Z" }, + { url = "https://files.pythonhosted.org/packages/2a/20/8fc8996afe5815fa1a6be8e9e5c02f24500f409d599e905800d498a4e14d/hf_xet-1.5.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:872d5601e6deea30d15865ede55d29eac6daf5a534ab417b99b6ef6b076dd96c", size = 4023495, upload-time = "2026-05-06T06:18:01.94Z" }, + { url = "https://files.pythonhosted.org/packages/32/6a/93d84463c00cecb561a7508aa6303e35ee2894294eac14245526924415fe/hf_xet-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9929561f5abf4581c8ea79587881dfef6b8abb2a0d8a51915936fc2a614f4e73", size = 3792731, upload-time = "2026-05-06T06:18:00.021Z" }, + { url = "https://files.pythonhosted.org/packages/9d/5a/8ec8e0c863b382d00b3c2e2af6ded6b06371be617144a625903a6d562f4b/hf_xet-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f7b7bbae318e583a86fb21e5a4a175d6721d628a2874f4bd022d0e660c32a682", size = 4456738, upload-time = "2026-05-06T06:17:49.574Z" }, + { url = "https://files.pythonhosted.org/packages/c5/ca/f7effa1a67717da2bcc6b6c28f71c6ca648c77acaec4e2c32f40cbe16d85/hf_xet-1.5.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:cf7b2dc6f31a4ea754bb50f74cde482dcf5d366d184076d8530b9872787f3761", size = 4251622, upload-time = "2026-05-06T06:17:47.096Z" }, + { url = "https://files.pythonhosted.org/packages/65/f2/19247dba3e231cf77dec59ddfb878f00057635ff773d099c9b59d37812c3/hf_xet-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8dbcbab554c9ef158ef2c991545c3e970ddd8cc7acdcd0a78c5a41095dab4ded", size = 4445667, upload-time = "2026-05-06T06:18:11.983Z" }, + { url = "https://files.pythonhosted.org/packages/7f/64/6f116801a3bcfb6f59f5c251f48cadc47ea54026441c4a385079286a94fa/hf_xet-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5906bf7718d3636dc13402914736abe723492cb730f744834f5f5b67d3a12702", size = 4664619, upload-time = "2026-05-06T06:18:13.771Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e8/069542d37946ed08669b127e1496fa99e78196d71de8d41eda5e9f1b7a58/hf_xet-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:5f3dc2248fc01cc0a00cd392ab497f1ca373fcbc7e3f2da1f452480b384e839e", size = 3966802, upload-time = "2026-05-06T06:18:28.162Z" }, + { url = "https://files.pythonhosted.org/packages/f9/91/fc6fdec27b14d04e88c386ac0a0129732b53fa23f7c4a78f4b83a039c567/hf_xet-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:b285cea1b5bab46b758772716ba8d6854a1a0310fed1c249d678a8b38601e5a0", size = 3797168, upload-time = "2026-05-06T06:18:26.287Z" }, + { url = "https://files.pythonhosted.org/packages/3d/fb/69ff198a82cae7eb1a69fb84d93b3a3e4816564d76817fe541ddc96874eb/hf_xet-1.5.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:dad0dc84e941b8ba3c860659fe1fdc35c049d47cce293f003287757e971a8f56", size = 4030814, upload-time = "2026-05-06T06:17:57.933Z" }, + { url = "https://files.pythonhosted.org/packages/9b/ff/edcc2b40162bef3ff78e14ab637e5f3b89243d6aee72f5949d3bb6a5af83/hf_xet-1.5.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:fd6e5a9b0fdac4ed03ed45ef79254a655b1aaab514a02202617fbf643f5fdf7a", size = 3798444, upload-time = "2026-05-06T06:17:55.79Z" }, + { url = "https://files.pythonhosted.org/packages/49/4d/103f76b04310e5e57656696cc184690d20c466af0bca3ca88f8c8ea5d4f3/hf_xet-1.5.0-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3531b1823a0e6d77d80f9ed15ca0e00f0d115094f8ac033d5cae88f4564cc949", size = 4465986, upload-time = "2026-05-06T06:17:44.886Z" }, + { url = "https://files.pythonhosted.org/packages/c4/a2/546f47f464737b3edbab6f8ddb57f2599b93d2cbb66f06abb475ccb48651/hf_xet-1.5.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:9a0ee58cd18d5ea799f7ed11290bbccbe56bdd8b1d97ca74b9cc49a3945d7a3b", size = 4259865, upload-time = "2026-05-06T06:17:42.639Z" }, + { url = "https://files.pythonhosted.org/packages/95/7f/1be593c1f28613be2e196473481cd81bfc5910795e30a34e8f744f6cac4f/hf_xet-1.5.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1e60df5a42e9bed8628b6416af2cba4cba57ae9f02de226a06b020d98e1aab18", size = 4459835, upload-time = "2026-05-06T06:18:08.026Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b2/703569fc881f3284487e68cda7b42179978480da3c438042a6bbbb4a671c/hf_xet-1.5.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:4b35549ce62601b84da4ff9b24d970032ace3d4430f52d91bcbb26c901d6c690", size = 4672414, upload-time = "2026-05-06T06:18:09.864Z" }, + { url = "https://files.pythonhosted.org/packages/af/37/1b6def445c567286b50aa3b33828158e135b1be44938dde59f11382a500c/hf_xet-1.5.0-cp37-abi3-win_amd64.whl", hash = "sha256:2806c7c17b4d23f8d88f7c4814f838c3b6150773fe339c20af23e1cfaf2797e4", size = 3977238, upload-time = "2026-05-06T06:18:23.621Z" }, + { url = "https://files.pythonhosted.org/packages/62/94/3b66b148778ee100dcfd69c2ca22b57b41b44d3063ceec934f209e9184ce/hf_xet-1.5.0-cp37-abi3-win_arm64.whl", hash = "sha256:b6c9df403040248c76d808d3e047d64db2d923bae593eb244c41e425cf6cd7be", size = 3806916, upload-time = "2026-05-06T06:18:21.7Z" }, ] [[package]] @@ -343,34 +343,41 @@ name = "httpcore" version = "1.0.9" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "certifi" }, - { name = "h11" }, + { name = "certifi" }, + { name = "h11" }, ] sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, ] [[package]] name = "httptools" -version = "0.7.1" +version = "0.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961, upload-time = "2025-10-10T03:55:08.559Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/e5/d471fcb0e14523fe1c3f4ba58ca52480e7bd70ad7109a3846bc75892f7fb/httptools-0.8.0.tar.gz", hash = "sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999", size = 271342, upload-time = "2026-05-25T22:17:48.841Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889, upload-time = "2025-10-10T03:54:47.089Z" }, - { url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180, upload-time = "2025-10-10T03:54:48.052Z" }, - { url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596, upload-time = "2025-10-10T03:54:48.919Z" }, - { url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268, upload-time = "2025-10-10T03:54:49.993Z" }, - { url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517, upload-time = "2025-10-10T03:54:51.066Z" }, - { url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337, upload-time = "2025-10-10T03:54:52.196Z" }, - { url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743, upload-time = "2025-10-10T03:54:53.448Z" }, - { url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619, upload-time = "2025-10-10T03:54:54.321Z" }, - { url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714, upload-time = "2025-10-10T03:54:55.163Z" }, - { url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909, upload-time = "2025-10-10T03:54:56.056Z" }, - { url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831, upload-time = "2025-10-10T03:54:57.219Z" }, - { url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631, upload-time = "2025-10-10T03:54:58.219Z" }, - { url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910, upload-time = "2025-10-10T03:54:59.366Z" }, - { url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205, upload-time = "2025-10-10T03:55:00.389Z" }, + { url = "https://files.pythonhosted.org/packages/5e/e5/8cfcabc5546e8022f168be28bcdaa128a240a0befdd03b59d558b4f18bd6/httptools-0.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:614ceea8ea606848bece2338ac03b3ce5324bcb4be8dc7d377ed708012fa4db8", size = 205148, upload-time = "2026-05-25T22:17:16.333Z" }, + { url = "https://files.pythonhosted.org/packages/2a/0e/0fb14848c19a686c8062ff9067c1a48793e3224b47bc5b201535b6036fce/httptools-0.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2d689918c15a013c65ef52d9fd495d766893ab831a2c8d89f2ac5940a5df847c", size = 111368, upload-time = "2026-05-25T22:17:17.586Z" }, + { url = "https://files.pythonhosted.org/packages/2e/1b/46f1cecf06b9bbde8e4b8c88034ac7908989e5ff7a3a388ef38392949c1f/httptools-0.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:eb3028cca2fc0a6d720e52ef61d8ebb62fcbfeb1de56874546d858d3f25a26b7", size = 486447, upload-time = "2026-05-25T22:17:18.564Z" }, + { url = "https://files.pythonhosted.org/packages/77/00/258bfc0837221f81d9725c45f9b948a6a6b2994a147a4fb66e85100c668f/httptools-0.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:88bdd940f2b5d487b4d032c6afa5489a7dc4694410d43de3c38c4fb3af0dc45d", size = 482448, upload-time = "2026-05-25T22:17:19.912Z" }, + { url = "https://files.pythonhosted.org/packages/04/ab/d1cef3b5523f4d272a70f42a776c3169a2dddfe3a54de4b2ce4a36341528/httptools-0.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6a43c9dd399758ccc0531acb0a3c4a6c299ee893ee9400e9c893b7bdcfae0681", size = 464460, upload-time = "2026-05-25T22:17:20.882Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/5d1d072442277bb2b3434e0e60690b8e8c23840ef7de8b6ea54040a536d3/httptools-0.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0770728beb05094c809b98e814edff5fef69d26ad7d21185f2f6d5884a0ba683", size = 471312, upload-time = "2026-05-25T22:17:22.085Z" }, + { url = "https://files.pythonhosted.org/packages/0d/66/b96623b27e51a68199ef4efdda0613cced9233fe3062ac74e50749c5ad37/httptools-0.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:7685df791fad561384bfb139e77fde27a1ffd93134e016f95a0db424ffbf77b1", size = 90117, upload-time = "2026-05-25T22:17:23.074Z" }, + { url = "https://files.pythonhosted.org/packages/1a/12/fa3fbf5f9517b273edea2dc982aa82a8c634091e67c590792b729017bc6f/httptools-0.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:de242a49b5d18e0a8776e654e9f6bf6d89f3875a5c35b425a0e7ce940feb3fd6", size = 206183, upload-time = "2026-05-25T22:17:24.004Z" }, + { url = "https://files.pythonhosted.org/packages/30/fc/5e7c4cb443370f2090a3aba0453a07384d29ff66b7435bb90e77e1037599/httptools-0.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:159e9ab5f701ccd42e555a12f1ad8ff69702910fc1c996cf2bb66e5fcb7a231b", size = 112079, upload-time = "2026-05-25T22:17:25.216Z" }, + { url = "https://files.pythonhosted.org/packages/ba/53/771bd891eb0f236f32145d6a1775777ec85745f3cc983a1f23d1a3b8ddfe/httptools-0.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c4a9f1707e4823d54dfec6c33fa3697d302aed536ed352a7ebb5a061ddb869d0", size = 481596, upload-time = "2026-05-25T22:17:26.186Z" }, + { url = "https://files.pythonhosted.org/packages/62/42/94e15bc68ce3d423243c45d7f1b0c7561f13844f97dc52ae23182fb65628/httptools-0.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d76ad7b951387e3632c8716a9bb03ac5b45c5f16119aa409db0459520887944e", size = 480865, upload-time = "2026-05-25T22:17:27.542Z" }, + { url = "https://files.pythonhosted.org/packages/1c/7c/fe2980fc03723272e30f135b62360b075f513dfe7cc73aef36c7f04012bd/httptools-0.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a3b7387147361c3fd47a0bde763c5c91b5b4cd4dc9989b8ece84ff436c99843b", size = 463189, upload-time = "2026-05-25T22:17:28.546Z" }, + { url = "https://files.pythonhosted.org/packages/15/1b/47fc5fff68acd1bfa20b4734059c9a06cadb88119dcd5258b5b0d21d91c8/httptools-0.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f256d6ce930c52ca1cb2a960b7da03548c454e7d28b06059ad41bfe789036ce0", size = 466610, upload-time = "2026-05-25T22:17:29.816Z" }, + { url = "https://files.pythonhosted.org/packages/60/bd/07b13c93ffd9bec9546e0d43f8e19378dd696dbd278511406bc07371ef1f/httptools-0.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:19d1ee275bb59ba2643ba9a3a1e51cc0c788caf2b8df506368e03f56fdd08527", size = 92705, upload-time = "2026-05-25T22:17:31.133Z" }, + { url = "https://files.pythonhosted.org/packages/fd/c4/121648f68ce066d7bd762d6b6d97e620847642d38d54f3d90ff11d947629/httptools-0.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:de1ed58a974e75d56560acc7e7fed01a454994429456f65209789992e41f2568", size = 215023, upload-time = "2026-05-25T22:17:32.401Z" }, + { url = "https://files.pythonhosted.org/packages/b9/b0/312a062ae741ae3e8baa8c8bf20be81b2e67337b259ab4349bebc7b6142e/httptools-0.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e93c227b595c6926c1acee96891dd9da4be338cfbe82e5cd3bb9d8dd7dc4ac0b", size = 117405, upload-time = "2026-05-25T22:17:33.742Z" }, + { url = "https://files.pythonhosted.org/packages/fc/37/fccd705f795386bb05bf413012fecff2a33e5aa8c2f069096de3e9fd8702/httptools-0.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2a021c3a8e65cc125390d72f59b968afca3bdcaff25bd67965e0a055a14946ca", size = 558497, upload-time = "2026-05-25T22:17:34.732Z" }, + { url = "https://files.pythonhosted.org/packages/bd/39/f172e8003576de35f5ba77ff417cf0e34429d35dc014deef15afa337a72c/httptools-0.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:48774d39cbb70e2b1f71f88852a3087ae1d3a1eb80482bb48c13067ab080c14f", size = 571585, upload-time = "2026-05-25T22:17:35.813Z" }, + { url = "https://files.pythonhosted.org/packages/3e/b9/f5564760af99f3dbbf3f9104dc00e5da27e96cf433c6bdcf77617f70bf3f/httptools-0.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:88eead8ec8680a9f146c655bc88445a325bd7921cfd8194c7337e9467282427d", size = 543297, upload-time = "2026-05-25T22:17:37.08Z" }, + { url = "https://files.pythonhosted.org/packages/99/67/8d9f2c313618e161b82f3873188e7196126da1d6e29688df40eb3997c77a/httptools-0.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2c032fa028f46871ec7e1fc59fc15e8023eab3e6bbe6ece786a1611719a5d081", size = 539535, upload-time = "2026-05-25T22:17:38.032Z" }, + { url = "https://files.pythonhosted.org/packages/48/63/b906c01e53f50d432c0defe43ce52764a111dc1bdd028bafbeb54dcfd008/httptools-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:384c17174464c8e873398b7af24f0b1f44d992c820328413951a625323155d77", size = 108209, upload-time = "2026-05-25T22:17:39.473Z" }, ] [[package]] @@ -378,34 +385,35 @@ name = "httpx" version = "0.28.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio" }, - { name = "certifi" }, - { name = "httpcore" }, - { name = "idna" }, + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] [[package]] name = "huggingface-hub" -version = "1.12.0" +version = "1.16.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "filelock" }, - { name = "fsspec" }, - { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, - { name = "httpx" }, - { name = "packaging" }, - { name = "pyyaml" }, - { name = "tqdm" }, - { name = "typer" }, - { name = "typing-extensions" }, + { name = "click" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" }, + { name = "httpx" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "tqdm" }, + { name = "typer" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/56/52/1b54cb569509c725a32c1315261ac9fd0e6b91bbbf74d86fca10d3376164/huggingface_hub-1.12.0.tar.gz", hash = "sha256:7c3fe85e24b652334e5d456d7a812cd9a071e75630fac4365d9165ab5e4a34b6", size = 763091, upload-time = "2026-04-24T13:32:08.674Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/11/9b6e439cb2417c479c3da108b38363232a1554721de9f8ef4836cb07422b/huggingface_hub-1.16.4.tar.gz", hash = "sha256:023bacd155f837d3fa56379ac8e23dababe6d6d87b04f8dacc258a44a38abe01", size = 792585, upload-time = "2026-05-26T17:19:09.971Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/2b/ef03ddb96bd1123503c2bd6932001020292deea649e9bf4caa2cb65a85bf/huggingface_hub-1.12.0-py3-none-any.whl", hash = "sha256:d74939969585ee35748bd66de09baf84099d461bda7287cd9043bfb99b0e424d", size = 646806, upload-time = "2026-04-24T13:32:06.717Z" }, + { url = "https://files.pythonhosted.org/packages/da/86/e05d58ea272089151ba9f6fcc7b44a97aa2533d5a5bce46611220c23c6d6/huggingface_hub-1.16.4-py3-none-any.whl", hash = "sha256:994ec184c3330952d7b5f131ea0b1a6ba1047bd05461f5dec191f8fc1099fbd7", size = 668190, upload-time = "2026-05-26T17:19:08.228Z" }, ] [[package]] @@ -414,16 +422,16 @@ version = "2.6.19" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/52/63/51723b5f116cc04b061cb6f5a561790abf249d25931d515cd375e063e0f4/identify-2.6.19.tar.gz", hash = "sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842", size = 99567, upload-time = "2026-04-17T18:39:50.265Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl", hash = "sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a", size = 99397, upload-time = "2026-04-17T18:39:49.221Z" }, + { url = "https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl", hash = "sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a", size = 99397, upload-time = "2026-04-17T18:39:49.221Z" }, ] [[package]] name = "idna" -version = "3.15" +version = "3.16" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/77/7b3966d0b9d1d31a36ddf1746926a11dface89a83409bf1483f0237aa758/idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc", size = 199245, upload-time = "2026-05-12T22:45:57.011Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/88/bcf9709822fe69d02c2a6a77956c98ce6ea8ca8767a9aadcedc7eb6a2390/idna-3.16.tar.gz", hash = "sha256:d7a6da03db833450fca25d2358ac9ff06cd624577a4aea3a596d5c0f77b8e03d", size = 203770, upload-time = "2026-05-22T00:16:18.781Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/23/408243171aa9aaba178d3e2559159c24c1171a641aa83b67bdd3394ead8e/idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8", size = 72340, upload-time = "2026-05-12T22:45:55.733Z" }, + { url = "https://files.pythonhosted.org/packages/94/16/70255075a9859a0e3adb789b68ceb0e210dec03934245fd98d248226572f/idna-3.16-py3-none-any.whl", hash = "sha256:cc246e3a3f89580c3a951b5ad298ca4638078b2cdd4f115654332b5c26daded5", size = 74165, upload-time = "2026-05-22T00:16:16.698Z" }, ] [[package]] @@ -432,7 +440,7 @@ version = "2.3.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, ] [[package]] @@ -440,11 +448,11 @@ name = "jinja2" version = "3.1.6" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "markupsafe" }, + { name = "markupsafe" }, ] sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, ] [[package]] @@ -453,7 +461,7 @@ version = "1.5.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/41/f2/d34e8b3a08a9cc79a50b2208a93dce981fe615b64d5a4d4abee421d898df/joblib-1.5.3.tar.gz", hash = "sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3", size = 331603, upload-time = "2025-12-15T08:41:46.427Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" }, + { url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" }, ] [[package]] @@ -461,56 +469,56 @@ name = "ktx-daemon" version = "0.6.0" source = { editable = "python/ktx-daemon" } dependencies = [ - { name = "fastapi" }, - { name = "ktx-sl" }, - { name = "lkml" }, - { name = "numpy" }, - { name = "orjson" }, - { name = "pandas" }, - { name = "posthog" }, - { name = "psycopg", extra = ["binary"] }, - { name = "pydantic" }, - { name = "requests" }, - { name = "sqlglot" }, - { name = "uvicorn", extra = ["standard"] }, + { name = "fastapi" }, + { name = "ktx-sl" }, + { name = "lkml" }, + { name = "numpy" }, + { name = "orjson" }, + { name = "pandas" }, + { name = "posthog" }, + { name = "psycopg", extra = ["binary"] }, + { name = "pydantic" }, + { name = "requests" }, + { name = "sqlglot" }, + { name = "uvicorn", extra = ["standard"] }, ] [package.optional-dependencies] local-embeddings = [ - { name = "sentence-transformers" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin'" }, + { name = "sentence-transformers" }, + { name = "torch", version = "2.12.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, + { name = "torch", version = "2.12.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin'" }, ] [package.dev-dependencies] dev = [ - { name = "httpx" }, - { name = "pytest" }, + { name = "httpx" }, + { name = "pytest" }, ] [package.metadata] requires-dist = [ - { name = "fastapi", specifier = ">=0.115.0" }, - { name = "ktx-sl", editable = "python/ktx-sl" }, - { name = "lkml", specifier = ">=1.3.7" }, - { name = "numpy", specifier = ">=2.2.6" }, - { name = "orjson", specifier = ">=3.11.4" }, - { name = "pandas", specifier = ">=2.2.3" }, - { name = "posthog", specifier = ">=7.0.0" }, - { name = "psycopg", extras = ["binary"], specifier = ">=3.2.0" }, - { name = "pydantic", specifier = ">=2.9.0" }, - { name = "requests", specifier = ">=2.32.0" }, - { name = "sentence-transformers", marker = "extra == 'local-embeddings'", specifier = ">=5.1.1" }, - { name = "sqlglot", specifier = ">=26" }, - { name = "torch", marker = "extra == 'local-embeddings'", specifier = ">=2.2.0", index = "https://download.pytorch.org/whl/cpu" }, - { name = "uvicorn", extras = ["standard"], specifier = ">=0.32.0" }, + { name = "fastapi", specifier = ">=0.136.3" }, + { name = "ktx-sl", editable = "python/ktx-sl" }, + { name = "lkml", specifier = ">=1.3.7" }, + { name = "numpy", specifier = ">=2.4.6" }, + { name = "orjson", specifier = ">=3.11.9" }, + { name = "pandas", specifier = ">=3.0.3" }, + { name = "posthog", specifier = ">=7.16.1" }, + { name = "psycopg", extras = ["binary"], specifier = ">=3.3.4" }, + { name = "pydantic", specifier = ">=2.13.4" }, + { name = "requests", specifier = ">=2.34.2" }, + { name = "sentence-transformers", marker = "extra == 'local-embeddings'", specifier = ">=5.1.1" }, + { name = "sqlglot", specifier = ">=30" }, + { name = "torch", marker = "extra == 'local-embeddings'", specifier = ">=2.2.0", index = "https://download.pytorch.org/whl/cpu" }, + { name = "uvicorn", extras = ["standard"], specifier = ">=0.48.0" }, ] provides-extras = ["local-embeddings"] [package.metadata.requires-dev] dev = [ - { name = "httpx", specifier = ">=0.28.1" }, - { name = "pytest", specifier = ">=9.0.2" }, + { name = "httpx", specifier = ">=0.28.1" }, + { name = "pytest", specifier = ">=9.0.2" }, ] [[package]] @@ -518,45 +526,45 @@ name = "ktx-sl" version = "0.6.0" source = { editable = "python/ktx-sl" } dependencies = [ - { name = "pydantic" }, - { name = "pyyaml" }, - { name = "sqlglot" }, + { name = "pydantic" }, + { name = "pyyaml" }, + { name = "sqlglot" }, ] [package.optional-dependencies] dev = [ - { name = "pre-commit" }, - { name = "pytest" }, - { name = "pytest-cov" }, - { name = "ruff" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, ] tpch = [ - { name = "duckdb" }, + { name = "duckdb" }, ] [package.dev-dependencies] dev = [ - { name = "pytest" }, - { name = "pytest-cov" }, + { name = "pytest" }, + { name = "pytest-cov" }, ] [package.metadata] requires-dist = [ - { name = "duckdb", marker = "extra == 'tpch'", specifier = ">=1.0" }, - { name = "pre-commit", marker = "extra == 'dev'" }, - { name = "pydantic", specifier = ">=2" }, - { name = "pytest", marker = "extra == 'dev'", specifier = ">=8" }, - { name = "pytest-cov", marker = "extra == 'dev'" }, - { name = "pyyaml", specifier = ">=6" }, - { name = "ruff", marker = "extra == 'dev'" }, - { name = "sqlglot", specifier = ">=26" }, + { name = "duckdb", marker = "extra == 'tpch'", specifier = ">=1.0" }, + { name = "pre-commit", marker = "extra == 'dev'" }, + { name = "pydantic", specifier = ">=2" }, + { name = "pytest", marker = "extra == 'dev'", specifier = ">=8" }, + { name = "pytest-cov", marker = "extra == 'dev'" }, + { name = "pyyaml", specifier = ">=6" }, + { name = "ruff", marker = "extra == 'dev'" }, + { name = "sqlglot", specifier = ">=30" }, ] provides-extras = ["dev", "tpch"] [package.metadata.requires-dev] dev = [ - { name = "pytest", specifier = ">=9.0.2" }, - { name = "pytest-cov", specifier = ">=7.1.0" }, + { name = "pytest", specifier = ">=9.0.2" }, + { name = "pytest-cov", specifier = ">=7.1.0" }, ] [[package]] @@ -566,20 +574,19 @@ source = { virtual = "." } [package.dev-dependencies] dev = [ - { name = "pre-commit" }, - { name = "pytest" }, - { name = "pytest-cov" }, - { name = "ruff" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, ] [package.metadata] - [package.metadata.requires-dev] dev = [ - { name = "pre-commit", specifier = ">=4.6.0" }, - { name = "pytest", specifier = ">=9.0.2" }, - { name = "pytest-cov", specifier = ">=7.1.0" }, - { name = "ruff", specifier = ">=0.8.4" }, + { name = "pre-commit", specifier = ">=4.6.0" }, + { name = "pytest", specifier = ">=9.0.2" }, + { name = "pytest-cov", specifier = ">=7.1.0" }, + { name = "ruff", specifier = ">=0.8.4" }, ] [[package]] @@ -588,19 +595,19 @@ version = "1.3.7" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/bf/18/18a3d0281c5e209156b877796096d4ac7259f03465409673056386c99221/lkml-1.3.7.tar.gz", hash = "sha256:51dc9f1b7e74cd7a00e0dbbf06fb573952015328f1f4a3a0730d444444a8ae7a", size = 28763, upload-time = "2025-01-31T02:30:35.472Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/15/e7124d4ec54fdcafa801b55d6b67d6196ed6c8a0de554e1a8b67b66fec65/lkml-1.3.7-py2.py3-none-any.whl", hash = "sha256:ce54c517f81fbd21d452038be9e2504fa02951a5bc30f7d7f1eb552c1f3f2b39", size = 23062, upload-time = "2025-01-31T02:30:34.377Z" }, + { url = "https://files.pythonhosted.org/packages/c7/15/e7124d4ec54fdcafa801b55d6b67d6196ed6c8a0de554e1a8b67b66fec65/lkml-1.3.7-py2.py3-none-any.whl", hash = "sha256:ce54c517f81fbd21d452038be9e2504fa02951a5bc30f7d7f1eb552c1f3f2b39", size = 23062, upload-time = "2025-01-31T02:30:34.377Z" }, ] [[package]] name = "markdown-it-py" -version = "4.0.0" +version = "4.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "mdurl" }, + { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, ] [[package]] @@ -609,50 +616,50 @@ version = "3.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, - { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, - { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, - { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, - { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, - { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, - { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, - { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, - { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, - { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, - { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, - { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, - { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, - { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, - { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, - { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, - { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, - { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, - { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, - { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, - { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, - { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, - { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, - { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, - { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, - { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, - { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, - { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, - { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, - { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, - { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, - { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, - { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, - { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, - { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, - { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, - { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, - { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, - { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, - { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, - { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, - { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, - { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] [[package]] @@ -661,7 +668,7 @@ version = "0.1.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] @@ -670,7 +677,7 @@ version = "1.3.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, ] [[package]] @@ -679,7 +686,7 @@ version = "3.6.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/6a/51/63fe664f3908c97be9d2e4f1158eb633317598cfa6e1fc14af5383f17512/networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509", size = 2517025, upload-time = "2025-12-08T17:02:39.908Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, + { url = "https://files.pythonhosted.org/packages/9e/c9/b2622292ea83fbb4ec318f5b9ab867d0a28ab43c5717bb85b0a5f6b3b0a4/networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762", size = 2068504, upload-time = "2025-12-08T17:02:38.159Z" }, ] [[package]] @@ -688,95 +695,95 @@ version = "1.10.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, + { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" }, ] [[package]] name = "numpy" -version = "2.4.4" +version = "2.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/9f/b8cef5bffa569759033adda9481211426f12f53299629b410340795c2514/numpy-2.4.4.tar.gz", hash = "sha256:2d390634c5182175533585cc89f3608a4682ccb173cc9bb940b2881c8d6f8fa0", size = 20731587, upload-time = "2026-03-29T13:22:01.298Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/14/1d/d0a583ce4fefcc3308806a749a536c201ed6b5ad6e1322e227ee4848979d/numpy-2.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:08f2e31ed5e6f04b118e49821397f12767934cfdd12a1ce86a058f91e004ee50", size = 16684933, upload-time = "2026-03-29T13:19:22.47Z" }, - { url = "https://files.pythonhosted.org/packages/c1/62/2b7a48fbb745d344742c0277f01286dead15f3f68e4f359fbfcf7b48f70f/numpy-2.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e823b8b6edc81e747526f70f71a9c0a07ac4e7ad13020aa736bb7c9d67196115", size = 14694532, upload-time = "2026-03-29T13:19:25.581Z" }, - { url = "https://files.pythonhosted.org/packages/e5/87/499737bfba066b4a3bebff24a8f1c5b2dee410b209bc6668c9be692580f0/numpy-2.4.4-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:4a19d9dba1a76618dd86b164d608566f393f8ec6ac7c44f0cc879011c45e65af", size = 5199661, upload-time = "2026-03-29T13:19:28.31Z" }, - { url = "https://files.pythonhosted.org/packages/cd/da/464d551604320d1491bc345efed99b4b7034143a85787aab78d5691d5a0e/numpy-2.4.4-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d2a8490669bfe99a233298348acc2d824d496dee0e66e31b66a6022c2ad74a5c", size = 6547539, upload-time = "2026-03-29T13:19:30.97Z" }, - { url = "https://files.pythonhosted.org/packages/7d/90/8d23e3b0dafd024bf31bdec225b3bb5c2dbfa6912f8a53b8659f21216cbf/numpy-2.4.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45dbed2ab436a9e826e302fcdcbe9133f9b0006e5af7168afb8963a6520da103", size = 15668806, upload-time = "2026-03-29T13:19:33.887Z" }, - { url = "https://files.pythonhosted.org/packages/d1/73/a9d864e42a01896bb5974475438f16086be9ba1f0d19d0bb7a07427c4a8b/numpy-2.4.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c901b15172510173f5cb310eae652908340f8dede90fff9e3bf6c0d8dfd92f83", size = 16632682, upload-time = "2026-03-29T13:19:37.336Z" }, - { url = "https://files.pythonhosted.org/packages/34/fb/14570d65c3bde4e202a031210475ae9cde9b7686a2e7dc97ee67d2833b35/numpy-2.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:99d838547ace2c4aace6c4f76e879ddfe02bb58a80c1549928477862b7a6d6ed", size = 17019810, upload-time = "2026-03-29T13:19:40.963Z" }, - { url = "https://files.pythonhosted.org/packages/8a/77/2ba9d87081fd41f6d640c83f26fb7351e536b7ce6dd9061b6af5904e8e46/numpy-2.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0aec54fd785890ecca25a6003fd9a5aed47ad607bbac5cd64f836ad8666f4959", size = 18357394, upload-time = "2026-03-29T13:19:44.859Z" }, - { url = "https://files.pythonhosted.org/packages/a2/23/52666c9a41708b0853fa3b1a12c90da38c507a3074883823126d4e9d5b30/numpy-2.4.4-cp313-cp313-win32.whl", hash = "sha256:07077278157d02f65c43b1b26a3886bce886f95d20aabd11f87932750dfb14ed", size = 5959556, upload-time = "2026-03-29T13:19:47.661Z" }, - { url = "https://files.pythonhosted.org/packages/57/fb/48649b4971cde70d817cf97a2a2fdc0b4d8308569f1dd2f2611959d2e0cf/numpy-2.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:5c70f1cc1c4efbe316a572e2d8b9b9cc44e89b95f79ca3331553fbb63716e2bf", size = 12317311, upload-time = "2026-03-29T13:19:50.67Z" }, - { url = "https://files.pythonhosted.org/packages/ba/d8/11490cddd564eb4de97b4579ef6bfe6a736cc07e94c1598590ae25415e01/numpy-2.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:ef4059d6e5152fa1a39f888e344c73fdc926e1b2dd58c771d67b0acfbf2aa67d", size = 10222060, upload-time = "2026-03-29T13:19:54.229Z" }, - { url = "https://files.pythonhosted.org/packages/99/5d/dab4339177a905aad3e2221c915b35202f1ec30d750dd2e5e9d9a72b804b/numpy-2.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4bbc7f303d125971f60ec0aaad5e12c62d0d2c925f0ab1273debd0e4ba37aba5", size = 14822302, upload-time = "2026-03-29T13:19:57.585Z" }, - { url = "https://files.pythonhosted.org/packages/eb/e4/0564a65e7d3d97562ed6f9b0fd0fb0a6f559ee444092f105938b50043876/numpy-2.4.4-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:4d6d57903571f86180eb98f8f0c839fa9ebbfb031356d87f1361be91e433f5b7", size = 5327407, upload-time = "2026-03-29T13:20:00.601Z" }, - { url = "https://files.pythonhosted.org/packages/29/8d/35a3a6ce5ad371afa58b4700f1c820f8f279948cca32524e0a695b0ded83/numpy-2.4.4-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:4636de7fd195197b7535f231b5de9e4b36d2c440b6e566d2e4e4746e6af0ca93", size = 6647631, upload-time = "2026-03-29T13:20:02.855Z" }, - { url = "https://files.pythonhosted.org/packages/f4/da/477731acbd5a58a946c736edfdabb2ac5b34c3d08d1ba1a7b437fa0884df/numpy-2.4.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ad2e2ef14e0b04e544ea2fa0a36463f847f113d314aa02e5b402fdf910ef309e", size = 15727691, upload-time = "2026-03-29T13:20:06.004Z" }, - { url = "https://files.pythonhosted.org/packages/e6/db/338535d9b152beabeb511579598418ba0212ce77cf9718edd70262cc4370/numpy-2.4.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a285b3b96f951841799528cd1f4f01cd70e7e0204b4abebac9463eecfcf2a40", size = 16681241, upload-time = "2026-03-29T13:20:09.417Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a9/ad248e8f58beb7a0219b413c9c7d8151c5d285f7f946c3e26695bdbbe2df/numpy-2.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f8474c4241bc18b750be2abea9d7a9ec84f46ef861dbacf86a4f6e043401f79e", size = 17085767, upload-time = "2026-03-29T13:20:13.126Z" }, - { url = "https://files.pythonhosted.org/packages/b5/1a/3b88ccd3694681356f70da841630e4725a7264d6a885c8d442a697e1146b/numpy-2.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4e874c976154687c1f71715b034739b45c7711bec81db01914770373d125e392", size = 18403169, upload-time = "2026-03-29T13:20:17.096Z" }, - { url = "https://files.pythonhosted.org/packages/c2/c9/fcfd5d0639222c6eac7f304829b04892ef51c96a75d479214d77e3ce6e33/numpy-2.4.4-cp313-cp313t-win32.whl", hash = "sha256:9c585a1790d5436a5374bac930dad6ed244c046ed91b2b2a3634eb2971d21008", size = 6083477, upload-time = "2026-03-29T13:20:20.195Z" }, - { url = "https://files.pythonhosted.org/packages/d5/e3/3938a61d1c538aaec8ed6fd6323f57b0c2d2d2219512434c5c878db76553/numpy-2.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:93e15038125dc1e5345d9b5b68aa7f996ec33b98118d18c6ca0d0b7d6198b7e8", size = 12457487, upload-time = "2026-03-29T13:20:22.946Z" }, - { url = "https://files.pythonhosted.org/packages/97/6a/7e345032cc60501721ef94e0e30b60f6b0bd601f9174ebd36389a2b86d40/numpy-2.4.4-cp313-cp313t-win_arm64.whl", hash = "sha256:0dfd3f9d3adbe2920b68b5cd3d51444e13a10792ec7154cd0a2f6e74d4ab3233", size = 10292002, upload-time = "2026-03-29T13:20:25.909Z" }, - { url = "https://files.pythonhosted.org/packages/6e/06/c54062f85f673dd5c04cbe2f14c3acb8c8b95e3384869bb8cc9bff8cb9df/numpy-2.4.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f169b9a863d34f5d11b8698ead99febeaa17a13ca044961aa8e2662a6c7766a0", size = 16684353, upload-time = "2026-03-29T13:20:29.504Z" }, - { url = "https://files.pythonhosted.org/packages/4c/39/8a320264a84404c74cc7e79715de85d6130fa07a0898f67fb5cd5bd79908/numpy-2.4.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2483e4584a1cb3092da4470b38866634bafb223cbcd551ee047633fd2584599a", size = 14704914, upload-time = "2026-03-29T13:20:33.547Z" }, - { url = "https://files.pythonhosted.org/packages/91/fb/287076b2614e1d1044235f50f03748f31fa287e3dbe6abeb35cdfa351eca/numpy-2.4.4-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:2d19e6e2095506d1736b7d80595e0f252d76b89f5e715c35e06e937679ea7d7a", size = 5210005, upload-time = "2026-03-29T13:20:36.45Z" }, - { url = "https://files.pythonhosted.org/packages/63/eb/fcc338595309910de6ecabfcef2419a9ce24399680bfb149421fa2df1280/numpy-2.4.4-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:6a246d5914aa1c820c9443ddcee9c02bec3e203b0c080349533fae17727dfd1b", size = 6544974, upload-time = "2026-03-29T13:20:39.014Z" }, - { url = "https://files.pythonhosted.org/packages/44/5d/e7e9044032a716cdfaa3fba27a8e874bf1c5f1912a1ddd4ed071bf8a14a6/numpy-2.4.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:989824e9faf85f96ec9c7761cd8d29c531ad857bfa1daa930cba85baaecf1a9a", size = 15684591, upload-time = "2026-03-29T13:20:42.146Z" }, - { url = "https://files.pythonhosted.org/packages/98/7c/21252050676612625449b4807d6b695b9ce8a7c9e1c197ee6216c8a65c7c/numpy-2.4.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:27a8d92cd10f1382a67d7cf4db7ce18341b66438bdd9f691d7b0e48d104c2a9d", size = 16637700, upload-time = "2026-03-29T13:20:46.204Z" }, - { url = "https://files.pythonhosted.org/packages/b1/29/56d2bbef9465db24ef25393383d761a1af4f446a1df9b8cded4fe3a5a5d7/numpy-2.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e44319a2953c738205bf3354537979eaa3998ed673395b964c1176083dd46252", size = 17035781, upload-time = "2026-03-29T13:20:50.242Z" }, - { url = "https://files.pythonhosted.org/packages/e3/2b/a35a6d7589d21f44cea7d0a98de5ddcbb3d421b2622a5c96b1edf18707c3/numpy-2.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e892aff75639bbef0d2a2cfd55535510df26ff92f63c92cd84ef8d4ba5a5557f", size = 18362959, upload-time = "2026-03-29T13:20:54.019Z" }, - { url = "https://files.pythonhosted.org/packages/64/c9/d52ec581f2390e0f5f85cbfd80fb83d965fc15e9f0e1aec2195faa142cde/numpy-2.4.4-cp314-cp314-win32.whl", hash = "sha256:1378871da56ca8943c2ba674530924bb8ca40cd228358a3b5f302ad60cf875fc", size = 6008768, upload-time = "2026-03-29T13:20:56.912Z" }, - { url = "https://files.pythonhosted.org/packages/fa/22/4cc31a62a6c7b74a8730e31a4274c5dc80e005751e277a2ce38e675e4923/numpy-2.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:715d1c092715954784bc79e1174fc2a90093dc4dc84ea15eb14dad8abdcdeb74", size = 12449181, upload-time = "2026-03-29T13:20:59.548Z" }, - { url = "https://files.pythonhosted.org/packages/70/2e/14cda6f4d8e396c612d1bf97f22958e92148801d7e4f110cabebdc0eef4b/numpy-2.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:2c194dd721e54ecad9ad387c1d35e63dce5c4450c6dc7dd5611283dda239aabb", size = 10496035, upload-time = "2026-03-29T13:21:02.524Z" }, - { url = "https://files.pythonhosted.org/packages/b1/e8/8fed8c8d848d7ecea092dc3469643f9d10bc3a134a815a3b033da1d2039b/numpy-2.4.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2aa0613a5177c264ff5921051a5719d20095ea586ca88cc802c5c218d1c67d3e", size = 14824958, upload-time = "2026-03-29T13:21:05.671Z" }, - { url = "https://files.pythonhosted.org/packages/05/1a/d8007a5138c179c2bf33ef44503e83d70434d2642877ee8fbb230e7c0548/numpy-2.4.4-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:42c16925aa5a02362f986765f9ebabf20de75cdefdca827d14315c568dcab113", size = 5330020, upload-time = "2026-03-29T13:21:08.635Z" }, - { url = "https://files.pythonhosted.org/packages/99/64/ffb99ac6ae93faf117bcbd5c7ba48a7f45364a33e8e458545d3633615dda/numpy-2.4.4-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:874f200b2a981c647340f841730fc3a2b54c9d940566a3c4149099591e2c4c3d", size = 6650758, upload-time = "2026-03-29T13:21:10.949Z" }, - { url = "https://files.pythonhosted.org/packages/6e/6e/795cc078b78a384052e73b2f6281ff7a700e9bf53bcce2ee579d4f6dd879/numpy-2.4.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c9b39d38a9bd2ae1becd7eac1303d031c5c110ad31f2b319c6e7d98b135c934d", size = 15729948, upload-time = "2026-03-29T13:21:14.047Z" }, - { url = "https://files.pythonhosted.org/packages/5f/86/2acbda8cc2af5f3d7bfc791192863b9e3e19674da7b5e533fded124d1299/numpy-2.4.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b268594bccac7d7cf5844c7732e3f20c50921d94e36d7ec9b79e9857694b1b2f", size = 16679325, upload-time = "2026-03-29T13:21:17.561Z" }, - { url = "https://files.pythonhosted.org/packages/bc/59/cafd83018f4aa55e0ac6fa92aa066c0a1877b77a615ceff1711c260ffae8/numpy-2.4.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac6b31e35612a26483e20750126d30d0941f949426974cace8e6b5c58a3657b0", size = 17084883, upload-time = "2026-03-29T13:21:21.106Z" }, - { url = "https://files.pythonhosted.org/packages/f0/85/a42548db84e65ece46ab2caea3d3f78b416a47af387fcbb47ec28e660dc2/numpy-2.4.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8e3ed142f2728df44263aaf5fb1f5b0b99f4070c553a0d7f033be65338329150", size = 18403474, upload-time = "2026-03-29T13:21:24.828Z" }, - { url = "https://files.pythonhosted.org/packages/ed/ad/483d9e262f4b831000062e5d8a45e342166ec8aaa1195264982bca267e62/numpy-2.4.4-cp314-cp314t-win32.whl", hash = "sha256:dddbbd259598d7240b18c9d87c56a9d2fb3b02fe266f49a7c101532e78c1d871", size = 6155500, upload-time = "2026-03-29T13:21:28.205Z" }, - { url = "https://files.pythonhosted.org/packages/c7/03/2fc4e14c7bd4ff2964b74ba90ecb8552540b6315f201df70f137faa5c589/numpy-2.4.4-cp314-cp314t-win_amd64.whl", hash = "sha256:a7164afb23be6e37ad90b2f10426149fd75aee07ca55653d2aa41e66c4ef697e", size = 12637755, upload-time = "2026-03-29T13:21:31.107Z" }, - { url = "https://files.pythonhosted.org/packages/58/78/548fb8e07b1a341746bfbecb32f2c268470f45fa028aacdbd10d9bc73aab/numpy-2.4.4-cp314-cp314t-win_arm64.whl", hash = "sha256:ba203255017337d39f89bdd58417f03c4426f12beed0440cfd933cb15f8669c7", size = 10566643, upload-time = "2026-03-29T13:21:34.339Z" }, + { url = "https://files.pythonhosted.org/packages/fb/82/bdab26d7438c6791ca31b7c024ca37c1eab8b726ba236129005cd4a06e45/numpy-2.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0", size = 16684648, upload-time = "2026-05-18T23:34:29.41Z" }, + { url = "https://files.pythonhosted.org/packages/1b/30/a80189bcc7f5e4258b3fbc3968d909d1756f54d023299ecc39ad6fdb9ef8/numpy-2.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb", size = 14693902, upload-time = "2026-05-18T23:34:33.013Z" }, + { url = "https://files.pythonhosted.org/packages/97/12/70b5d0d7c15e1ebb8a6a84a8caa1d19e181d84fb58bb6d70aca29099dec1/numpy-2.4.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f", size = 5198992, upload-time = "2026-05-18T23:34:36.132Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8c/ebd2a8f8a83541f8d38cc5667e8c2b69cecfd30da6e45693e8158857d44b/numpy-2.4.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3", size = 6546944, upload-time = "2026-05-18T23:34:38.484Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c5/7b863a97a91671a0338f4253bd3b5a3d3852f0692dae91711c9f4a10e787/numpy-2.4.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", size = 15669392, upload-time = "2026-05-18T23:34:41.257Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9d/3584b9984ca4c047aea75214ce1a4c4c73d849bd71b604264b7f5653f8a8/numpy-2.4.6-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", size = 16633220, upload-time = "2026-05-18T23:34:45.075Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/7c67fba23bd98caec7c99261f3a16072ade14813486b0282cb29846de832/numpy-2.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a", size = 17020800, upload-time = "2026-05-18T23:34:49.065Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5d/3b6725cb31d983c5e66916f5d36f6d7e5521129e4c4404d64f918292a5b6/numpy-2.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605", size = 18357600, upload-time = "2026-05-18T23:34:52.709Z" }, + { url = "https://files.pythonhosted.org/packages/f7/da/2ccc6c2fe8898dee01d90c75c5f5f914a23daf99e3e0f59516a08760c8b5/numpy-2.4.6-cp313-cp313-win32.whl", hash = "sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91", size = 5961134, upload-time = "2026-05-18T23:34:55.618Z" }, + { url = "https://files.pythonhosted.org/packages/b5/cd/9cc4dc876fb065d5c220aae4d5e14826b2715331bb7618ce1fb07a679d99/numpy-2.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359", size = 12318598, upload-time = "2026-05-18T23:34:58.928Z" }, + { url = "https://files.pythonhosted.org/packages/39/1e/c0bcba1f8694116485fe28fd1be698c278fcda4141c5b0e53a2aed8b12a8/numpy-2.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778", size = 10222272, upload-time = "2026-05-18T23:35:02.167Z" }, + { url = "https://files.pythonhosted.org/packages/63/6d/cc5619247c8f4204e507f5883528372e4ac4bb189e579fb859a12e480b1f/numpy-2.4.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1", size = 14821197, upload-time = "2026-05-18T23:35:05.468Z" }, + { url = "https://files.pythonhosted.org/packages/00/58/f1c39161c87d9e9bed660f1ed4bafc0e403d5ec9650b6dd77aead07d489b/numpy-2.4.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe", size = 5326287, upload-time = "2026-05-18T23:35:08.693Z" }, + { url = "https://files.pythonhosted.org/packages/af/57/3917ab0fd97f271a8694513581b8a36c655f111c446852c302f04ccdb6fc/numpy-2.4.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997", size = 6646763, upload-time = "2026-05-18T23:35:11.459Z" }, + { url = "https://files.pythonhosted.org/packages/eb/0f/037e64c494b67581ae18193d770adef354c41f3f2c8ebf865602d949bf8f/numpy-2.4.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20", size = 15728070, upload-time = "2026-05-18T23:35:14.79Z" }, + { url = "https://files.pythonhosted.org/packages/21/a6/5d2bae9c9542eb4df16dc9c46dc79c186e9bad53805dfa5399a6023c6db0/numpy-2.4.6-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d", size = 16681752, upload-time = "2026-05-18T23:35:18.836Z" }, + { url = "https://files.pythonhosted.org/packages/92/14/23d1dfb410ae362cd59ce53e936b1513d545eb40db3949ced632e19a459e/numpy-2.4.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", size = 17086024, upload-time = "2026-05-18T23:35:22.52Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6e/23595a2c642cdf3bc567877064bdd7f91c8b0038a4453cf2daf7248eafe9/numpy-2.4.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", size = 18403398, upload-time = "2026-05-18T23:35:26.398Z" }, + { url = "https://files.pythonhosted.org/packages/8a/90/0ac3bc947217e66dec77e7cbc6a1979d1af70b6461b82f620d3bccd5e4c8/numpy-2.4.6-cp313-cp313t-win32.whl", hash = "sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab", size = 6084971, upload-time = "2026-05-18T23:35:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/77/71/5673e351671a1d2bd6063b91b44f70c0affea7d1516fa7a6572941ba4aa1/numpy-2.4.6-cp313-cp313t-win_amd64.whl", hash = "sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75", size = 12458532, upload-time = "2026-05-18T23:35:32.175Z" }, + { url = "https://files.pythonhosted.org/packages/3f/88/19d3503c5046e688f049274b27a3ef3d771152fa80d3ba3d01a3dff61abe/numpy-2.4.6-cp313-cp313t-win_arm64.whl", hash = "sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd", size = 10291881, upload-time = "2026-05-18T23:35:35.465Z" }, + { url = "https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", size = 16683458, upload-time = "2026-05-18T23:35:38.353Z" }, + { url = "https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", size = 14704559, upload-time = "2026-05-18T23:35:42.14Z" }, + { url = "https://files.pythonhosted.org/packages/60/61/23f27c172f022e04025b7dc2367f4d63c1a398120607ec896228649a6f48/numpy-2.4.6-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", size = 5209716, upload-time = "2026-05-18T23:35:45.377Z" }, + { url = "https://files.pythonhosted.org/packages/03/71/21cf70dc6ea3e3acb95fc53a265b2fc248b981f0194ceb5b475271b8809d/numpy-2.4.6-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", size = 6543947, upload-time = "2026-05-18T23:35:47.926Z" }, + { url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" }, + { url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196, upload-time = "2026-05-18T23:36:05.92Z" }, + { url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334, upload-time = "2026-05-18T23:36:09.107Z" }, + { url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678, upload-time = "2026-05-18T23:36:12.766Z" }, + { url = "https://files.pythonhosted.org/packages/30/34/ec28d1aa8115971537c01469ab2011ee96827930f0a124de1000cc2a7ed7/numpy-2.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a", size = 14823672, upload-time = "2026-05-18T23:36:16.473Z" }, + { url = "https://files.pythonhosted.org/packages/16/bd/f6d1fede4e54e8042a7ff97bb495510f3c220f94bcd9e8b228e87c92cc0d/numpy-2.4.6-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e", size = 5328731, upload-time = "2026-05-18T23:36:19.767Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f0/e105b9e2fd728a9910103884decd6951d9dd73896b914a98d9a231de02ee/numpy-2.4.6-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", size = 6649805, upload-time = "2026-05-18T23:36:22.266Z" }, + { url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" }, + { url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" }, + { url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" }, + { url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982, upload-time = "2026-05-18T23:36:40.817Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908, upload-time = "2026-05-18T23:36:43.996Z" }, + { url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" }, ] [[package]] name = "orjson" -version = "3.11.8" +version = "3.11.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/1b/2024d06792d0779f9dbc51531b61c24f76c75b9f4ce05e6f3377a1814cea/orjson-3.11.8.tar.gz", hash = "sha256:96163d9cdc5a202703e9ad1b9ae757d5f0ca62f4fa0cc93d1f27b0e180cc404e", size = 5603832, upload-time = "2026-03-31T16:16:27.878Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/0c/964746fcafbd16f8ff53219ad9f6b412b34f345c75f384ad434ceaadb538/orjson-3.11.9.tar.gz", hash = "sha256:4fef17e1f8722c11587a6ef18e35902450221da0028e65dbaaa543619e68e48f", size = 5599163, upload-time = "2026-05-06T15:11:08.309Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/66/7f/95fba509bb2305fab0073558f1e8c3a2ec4b2afe58ed9fcb7d3b8beafe94/orjson-3.11.8-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:3f23426851d98478c8970da5991f84784a76682213cd50eb73a1da56b95239dc", size = 229180, upload-time = "2026-03-31T16:15:36.426Z" }, - { url = "https://files.pythonhosted.org/packages/f6/9d/b237215c743ca073697d759b5503abd2cb8a0d7b9c9e21f524bcf176ab66/orjson-3.11.8-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:ebaed4cef74a045b83e23537b52ef19a367c7e3f536751e355a2a394f8648559", size = 128754, upload-time = "2026-03-31T16:15:38.049Z" }, - { url = "https://files.pythonhosted.org/packages/42/3d/27d65b6d11e63f133781425f132807aef793ed25075fec686fc8e46dd528/orjson-3.11.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97c8f5d3b62380b70c36ffacb2a356b7c6becec86099b177f73851ba095ef623", size = 131877, upload-time = "2026-03-31T16:15:39.484Z" }, - { url = "https://files.pythonhosted.org/packages/dd/cc/faee30cd8f00421999e40ef0eba7332e3a625ce91a58200a2f52c7fef235/orjson-3.11.8-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:436c4922968a619fb7fef1ccd4b8b3a76c13b67d607073914d675026e911a65c", size = 130361, upload-time = "2026-03-31T16:15:41.274Z" }, - { url = "https://files.pythonhosted.org/packages/5c/bb/a6c55896197f97b6d4b4e7c7fd77e7235517c34f5d6ad5aadd43c54c6d7c/orjson-3.11.8-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ab359aff0436d80bfe8a23b46b5fea69f1e18aaf1760a709b4787f1318b317f", size = 135521, upload-time = "2026-03-31T16:15:42.758Z" }, - { url = "https://files.pythonhosted.org/packages/9c/7c/ca3a3525aa32ff636ebb1778e77e3587b016ab2edb1b618b36ba96f8f2c0/orjson-3.11.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f89b6d0b3a8d81e1929d3ab3d92bbc225688bd80a770c49432543928fe09ac55", size = 146862, upload-time = "2026-03-31T16:15:44.341Z" }, - { url = "https://files.pythonhosted.org/packages/3c/0c/18a9d7f18b5edd37344d1fd5be17e94dc652c67826ab749c6e5948a78112/orjson-3.11.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29c009e7a2ca9ad0ed1376ce20dd692146a5d9fe4310848904b6b4fee5c5c137", size = 132847, upload-time = "2026-03-31T16:15:46.368Z" }, - { url = "https://files.pythonhosted.org/packages/23/91/7e722f352ad67ca573cee44de2a58fb810d0f4eb4e33276c6a557979fd8a/orjson-3.11.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:705b895b781b3e395c067129d8551655642dfe9437273211d5404e87ac752b53", size = 133637, upload-time = "2026-03-31T16:15:48.123Z" }, - { url = "https://files.pythonhosted.org/packages/af/04/32845ce13ac5bd1046ddb02ac9432ba856cc35f6d74dde95864fe0ad5523/orjson-3.11.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:88006eda83858a9fdf73985ce3804e885c2befb2f506c9a3723cdeb5a2880e3e", size = 141906, upload-time = "2026-03-31T16:15:49.626Z" }, - { url = "https://files.pythonhosted.org/packages/02/5e/c551387ddf2d7106d9039369862245c85738b828844d13b99ccb8d61fd06/orjson-3.11.8-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:55120759e61309af7fcf9e961c6f6af3dde5921cdb3ee863ef63fd9db126cae6", size = 423722, upload-time = "2026-03-31T16:15:51.176Z" }, - { url = "https://files.pythonhosted.org/packages/00/a3/ecfe62434096f8a794d4976728cb59bcfc4a643977f21c2040545d37eb4c/orjson-3.11.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:98bdc6cb889d19bed01de46e67574a2eab61f5cc6b768ed50e8ac68e9d6ffab6", size = 147801, upload-time = "2026-03-31T16:15:52.939Z" }, - { url = "https://files.pythonhosted.org/packages/18/6d/0dce10b9f6643fdc59d99333871a38fa5a769d8e2fc34a18e5d2bfdee900/orjson-3.11.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:708c95f925a43ab9f34625e45dcdadf09ec8a6e7b664a938f2f8d5650f6c090b", size = 136460, upload-time = "2026-03-31T16:15:54.431Z" }, - { url = "https://files.pythonhosted.org/packages/01/d6/6dde4f31842d87099238f1f07b459d24edc1a774d20687187443ab044191/orjson-3.11.8-cp313-cp313-win32.whl", hash = "sha256:01c4e5a6695dc09098f2e6468a251bc4671c50922d4d745aff1a0a33a0cf5b8d", size = 131956, upload-time = "2026-03-31T16:15:56.081Z" }, - { url = "https://files.pythonhosted.org/packages/c1/f9/4e494a56e013db957fb77186b818b916d4695b8fa2aa612364974160e91b/orjson-3.11.8-cp313-cp313-win_amd64.whl", hash = "sha256:c154a35dd1330707450bb4d4e7dd1f17fa6f42267a40c1e8a1daa5e13719b4b8", size = 127410, upload-time = "2026-03-31T16:15:57.54Z" }, - { url = "https://files.pythonhosted.org/packages/57/7f/803203d00d6edb6e9e7eef421d4e1adbb5ea973e40b3533f3cfd9aeb374e/orjson-3.11.8-cp313-cp313-win_arm64.whl", hash = "sha256:4861bde57f4d253ab041e374f44023460e60e71efaa121f3c5f0ed457c3a701e", size = 127338, upload-time = "2026-03-31T16:15:59.106Z" }, - { url = "https://files.pythonhosted.org/packages/6d/35/b01910c3d6b85dc882442afe5060cbf719c7d1fc85749294beda23d17873/orjson-3.11.8-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:ec795530a73c269a55130498842aaa762e4a939f6ce481a7e986eeaa790e9da4", size = 229171, upload-time = "2026-03-31T16:16:00.651Z" }, - { url = "https://files.pythonhosted.org/packages/c2/56/c9ec97bd11240abef39b9e5d99a15462809c45f677420fd148a6c5e6295e/orjson-3.11.8-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:c492a0e011c0f9066e9ceaa896fbc5b068c54d365fea5f3444b697ee01bc8625", size = 128746, upload-time = "2026-03-31T16:16:02.673Z" }, - { url = "https://files.pythonhosted.org/packages/3b/e4/66d4f30a90de45e2f0cbd9623588e8ae71eef7679dbe2ae954ed6d66a41f/orjson-3.11.8-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:883206d55b1bd5f5679ad5e6ddd3d1a5e3cac5190482927fdb8c78fb699193b5", size = 131867, upload-time = "2026-03-31T16:16:04.342Z" }, - { url = "https://files.pythonhosted.org/packages/19/30/2a645fc9286b928675e43fa2a3a16fb7b6764aa78cc719dc82141e00f30b/orjson-3.11.8-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5774c1fdcc98b2259800b683b19599c133baeb11d60033e2095fd9d4667b82db", size = 124664, upload-time = "2026-03-31T16:16:05.837Z" }, - { url = "https://files.pythonhosted.org/packages/db/44/77b9a86d84a28d52ba3316d77737f6514e17118119ade3f91b639e859029/orjson-3.11.8-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7381c83dd3d4a6347e6635950aa448f54e7b8406a27c7ecb4a37e9f1ae08b", size = 129701, upload-time = "2026-03-31T16:16:07.407Z" }, - { url = "https://files.pythonhosted.org/packages/b3/ea/eff3d9bfe47e9bc6969c9181c58d9f71237f923f9c86a2d2f490cd898c82/orjson-3.11.8-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:14439063aebcb92401c11afc68ee4e407258d2752e62d748b6942dad20d2a70d", size = 141202, upload-time = "2026-03-31T16:16:09.48Z" }, - { url = "https://files.pythonhosted.org/packages/52/c8/90d4b4c60c84d62068d0cf9e4d8f0a4e05e76971d133ac0c60d818d4db20/orjson-3.11.8-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fa72e71977bff96567b0f500fc5bfd2fdf915f34052c782a4c6ebbdaa97aa858", size = 127194, upload-time = "2026-03-31T16:16:11.02Z" }, - { url = "https://files.pythonhosted.org/packages/8d/c7/ea9e08d1f0ba981adffb629811148b44774d935171e7b3d780ae43c4c254/orjson-3.11.8-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7679bc2f01bb0d219758f1a5f87bb7c8a81c0a186824a393b366876b4948e14f", size = 133639, upload-time = "2026-03-31T16:16:13.434Z" }, - { url = "https://files.pythonhosted.org/packages/6c/8c/ddbbfd6ba59453c8fc7fe1d0e5983895864e264c37481b2a791db635f046/orjson-3.11.8-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:14f7b8fcb35ef403b42fa5ecfa4ed032332a91f3dc7368fbce4184d59e1eae0d", size = 141914, upload-time = "2026-03-31T16:16:14.955Z" }, - { url = "https://files.pythonhosted.org/packages/4e/31/dbfbefec9df060d34ef4962cd0afcb6fa7a9ec65884cb78f04a7859526c3/orjson-3.11.8-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:c2bdf7b2facc80b5e34f48a2d557727d5c5c57a8a450de122ae81fa26a81c1bc", size = 423800, upload-time = "2026-03-31T16:16:16.594Z" }, - { url = "https://files.pythonhosted.org/packages/87/cf/f74e9ae9803d4ab46b163494adba636c6d7ea955af5cc23b8aaa94cfd528/orjson-3.11.8-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ccd7ba1b0605813a0715171d39ec4c314cb97a9c85893c2c5c0c3a3729df38bf", size = 147837, upload-time = "2026-03-31T16:16:18.585Z" }, - { url = "https://files.pythonhosted.org/packages/64/e6/9214f017b5db85e84e68602792f742e5dc5249e963503d1b356bee611e01/orjson-3.11.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:cdbc8c9c02463fef4d3c53a9ba3336d05496ec8e1f1c53326a1e4acc11f5c600", size = 136441, upload-time = "2026-03-31T16:16:20.151Z" }, - { url = "https://files.pythonhosted.org/packages/24/dd/3590348818f58f837a75fb969b04cdf187ae197e14d60b5e5a794a38b79d/orjson-3.11.8-cp314-cp314-win32.whl", hash = "sha256:0b57f67710a8cd459e4e54eb96d5f77f3624eba0c661ba19a525807e42eccade", size = 131983, upload-time = "2026-03-31T16:16:21.823Z" }, - { url = "https://files.pythonhosted.org/packages/3f/0f/b6cb692116e05d058f31ceee819c70f097fa9167c82f67fabe7516289abc/orjson-3.11.8-cp314-cp314-win_amd64.whl", hash = "sha256:735e2262363dcbe05c35e3a8869898022af78f89dde9e256924dc02e99fe69ca", size = 127396, upload-time = "2026-03-31T16:16:23.685Z" }, - { url = "https://files.pythonhosted.org/packages/c0/d1/facb5b5051fabb0ef9d26c6544d87ef19a939a9a001198655d0d891062dd/orjson-3.11.8-cp314-cp314-win_arm64.whl", hash = "sha256:6ccdea2c213cf9f3d9490cbd5d427693c870753df41e6cb375bd79bcbafc8817", size = 127330, upload-time = "2026-03-31T16:16:25.496Z" }, + { url = "https://files.pythonhosted.org/packages/32/33/93fcc25907235c344ae73122f8a4e01d2d393ef062b4af7d2e2487a32c37/orjson-3.11.9-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4bab1b2d6141fe7b32ae71dac905666ece4f94936efbfb13d55bb7739a3a6021", size = 228458, upload-time = "2026-05-06T15:10:20.079Z" }, + { url = "https://files.pythonhosted.org/packages/8f/27/b1e6dadb3c080313c03fdd8067b85e6a0460c7d8d6a1c3984ef77b904e4d/orjson-3.11.9-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:844417969855fc7a41be124aafe83dc424592a7f77cd4501900c67307122b92c", size = 128368, upload-time = "2026-05-06T15:10:21.549Z" }, + { url = "https://files.pythonhosted.org/packages/21/0f/c9ede0bf052f6b4051e64a7d4fa91b725cccf8321a6a786e86eb03519f00/orjson-3.11.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffe02797b5e9f3a9d8292ddcd289b474ad13e81ad83cd1891a240811f1d2cb81", size = 132070, upload-time = "2026-05-06T15:10:23.371Z" }, + { url = "https://files.pythonhosted.org/packages/fd/26/d398e28048dc18205bbe812f2c88cb9b40313db2470778e25964796458fe/orjson-3.11.9-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e4eed3b200023042814d2fc8a5d2e880f13b52e1ed2485e83da4f3962f7dc1a", size = 127892, upload-time = "2026-05-06T15:10:24.714Z" }, + { url = "https://files.pythonhosted.org/packages/66/60/52b0054c4c700d5aa7fc5b7ca96917400d8f061307778578e67a10e25852/orjson-3.11.9-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aff7da9952a5ad1cef8e68017724d96c7b9a66e99e91d6252e1b133d67a7b10", size = 135217, upload-time = "2026-05-06T15:10:26.084Z" }, + { url = "https://files.pythonhosted.org/packages/d5/97/1e3dc2b2a28b7b2528f403d2fc1d79ec5f39af3bc143ab65d3ec26426385/orjson-3.11.9-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d4e98d6f3b8afed8bc8cd9718ec0cdf46661826beefb53fe8eafb37f2bf0362", size = 145980, upload-time = "2026-05-06T15:10:28.062Z" }, + { url = "https://files.pythonhosted.org/packages/fc/39/31fbfe7850f2de32dee7e7e5c09f26d403ab01e440ac96001c6b01ad3c99/orjson-3.11.9-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a81d52442a7c99b3662333235b3adf96a1715864658b35bb797212be7bddb97", size = 132738, upload-time = "2026-05-06T15:10:29.727Z" }, + { url = "https://files.pythonhosted.org/packages/a1/08/dca0082dd2a194acb93e5457e73455388e2e2ca464a2672449a9ddbb679d/orjson-3.11.9-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e39364e726a8fff737309aff059ff67d8a8c8d5b677be7bb49a8b3e84b7e218", size = 134033, upload-time = "2026-05-06T15:10:31.152Z" }, + { url = "https://files.pythonhosted.org/packages/11/d4/5bdb0626801230139987385554c5d4c42255218ac906525bf4347f22cd95/orjson-3.11.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4fd66214623f1b17501df9f0543bef0b833979ab5b6ded1e1d123222866aa8c9", size = 141492, upload-time = "2026-05-06T15:10:32.641Z" }, + { url = "https://files.pythonhosted.org/packages/fa/88/a21fb53b3ede6703aede6dce4710ed4111e5b201cfa6bbff5e544f9d47d7/orjson-3.11.9-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:8ecc30f10465fa1e0ce13fd01d9e22c316e5053a719a8d915d4545a09a5ff677", size = 415087, upload-time = "2026-05-06T15:10:34.438Z" }, + { url = "https://files.pythonhosted.org/packages/3d/57/1b30daf70f0d8180e9a73cefbfbdd99e4bf19eb020466502b01fba7e0e50/orjson-3.11.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:97db4c94a7db398a5bd636273324f0b3fd58b350bbbac8bb380ceb825a9b40f4", size = 148031, upload-time = "2026-05-06T15:10:36.358Z" }, + { url = "https://files.pythonhosted.org/packages/04/83/45fbb6d962e260807f99441db9613cee868ceda4baceda59b3720a563f97/orjson-3.11.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9f78cf8fec5bd627f4082b8dfeac7871b43d7f3274904492a43dab39f18a19a0", size = 136915, upload-time = "2026-05-06T15:10:38.013Z" }, + { url = "https://files.pythonhosted.org/packages/5f/cc/2d10025f9056d376e4127ec05a5808b218d46f035fdc08178a5411b34250/orjson-3.11.9-cp313-cp313-win32.whl", hash = "sha256:d4087e5c0209a0a8efe4de3303c234b9c44d1174161dcd851e8eea07c7560b32", size = 131613, upload-time = "2026-05-06T15:10:39.569Z" }, + { url = "https://files.pythonhosted.org/packages/67/bd/2775ff28bfe883b9aa1ff348300542eb2ef1ee18d8ae0e3a49846817a865/orjson-3.11.9-cp313-cp313-win_amd64.whl", hash = "sha256:051b102c93b4f634e89f3866b07b9a9a98915ada541f4ec30f177067b2694979", size = 127086, upload-time = "2026-05-06T15:10:41.262Z" }, + { url = "https://files.pythonhosted.org/packages/91/2b/d26799e580939e32a7da9a39531bc9e58e15ca32ffaa6a8cb3e9bb0d22cd/orjson-3.11.9-cp313-cp313-win_arm64.whl", hash = "sha256:cce9127885941bd28f080cecf1f1d288336b7e0d812c345b08be88b572796254", size = 126696, upload-time = "2026-05-06T15:10:42.651Z" }, + { url = "https://files.pythonhosted.org/packages/8e/eb/5da01e356015aee6ecfa1187ced87aef51364e306f5e695dd52719bf0e78/orjson-3.11.9-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b6ef1979adc4bc243523f1a2ba91418030a8e29b0a99cbe7e0e2d6807d4dce6e", size = 228465, upload-time = "2026-05-06T15:10:44.097Z" }, + { url = "https://files.pythonhosted.org/packages/64/62/3e0e0c14c957133bcd855395c62b55ed4e3b0af23ffea11b032cb1dcbdb1/orjson-3.11.9-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:f36b7f32c7c0db4a719f1fc5824db4a9c6f8bd1a354debb91faf26ebf3a4c71e", size = 128364, upload-time = "2026-05-06T15:10:45.839Z" }, + { url = "https://files.pythonhosted.org/packages/5a/5a/07d8aa117211a8ed7630bda80c8c0b14d04e0f8dcf99bcf49656e4a710eb/orjson-3.11.9-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08f4d8ebb44925c794e535b2bebc507cebf32209df81de22ae285fb0d8d66de0", size = 132063, upload-time = "2026-05-06T15:10:47.267Z" }, + { url = "https://files.pythonhosted.org/packages/d6/ec/4acaf21483e18aa945be74a474c74b434f284b549f275a0a39b9f98956e9/orjson-3.11.9-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6cc7923789694fd58f001cbcac7e47abc13af4d560ebbfcf3b41a8b1a0748124", size = 122356, upload-time = "2026-05-06T15:10:48.765Z" }, + { url = "https://files.pythonhosted.org/packages/13/d8/5f0555e7638801323b7a75850f92e7dfa891bc84fe27a1ba4449170d1200/orjson-3.11.9-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea5c46eb2d3af39e806b986f4b09d5c2706a1f5afde3cbf7544ce6616127173c", size = 129592, upload-time = "2026-05-06T15:10:50.13Z" }, + { url = "https://files.pythonhosted.org/packages/b6/30/ed9860412a3603ceb3c5955bfd72d28b9d0e7ba6ed81add14f83d7114236/orjson-3.11.9-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f5d89a2ed90731df3be64bab0aa44f78bff39fdc9d71c291f4a8023aa46425b7", size = 140491, upload-time = "2026-05-06T15:10:51.582Z" }, + { url = "https://files.pythonhosted.org/packages/d0/17/adc514dea7ac7c505527febf884934b815d34f0c7b8693c1a8b39c5c4a57/orjson-3.11.9-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:25e4aed0312d292c09f61af25bba34e0b2c88546041472b09088c39a4d828af1", size = 127309, upload-time = "2026-05-06T15:10:53.329Z" }, + { url = "https://files.pythonhosted.org/packages/76/3e/c0b690253f0b82d86e99949af13533363acfb5432ecb5d53dd5b3bce9c34/orjson-3.11.9-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaea64f3f467d22e70eeed68bdccb3bc4f83f650446c4a03c59f2cba28a108db", size = 134030, upload-time = "2026-05-06T15:10:54.988Z" }, + { url = "https://files.pythonhosted.org/packages/c1/7a/bc82a0bb25e9faaf92dc4d9ef002732efc09737706af83e346788641d4a7/orjson-3.11.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a028425d1b440c5d92a6be1e1a020739dfe67ea87d96c6dbe828c1b30041728b", size = 141482, upload-time = "2026-05-06T15:10:56.663Z" }, + { url = "https://files.pythonhosted.org/packages/01/55/e69188b939f77d5d32a9833745ace31ea5ccae3ab613a1ec185d3cd2c4fb/orjson-3.11.9-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:5b192c6cf397e4455b11523c5cf2b18ed084c1bbd61b6c0926344d2129481972", size = 415178, upload-time = "2026-05-06T15:10:58.446Z" }, + { url = "https://files.pythonhosted.org/packages/2e/1a/b8a5a7ac527e80b9cb11d51e3f6689b709279183264b9ec5c7bc680bb8b5/orjson-3.11.9-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea407d4ccf5891d667d045fecae97a7a1e5e87b3b97f97ae1803c2e741130be0", size = 148089, upload-time = "2026-05-06T15:11:00.441Z" }, + { url = "https://files.pythonhosted.org/packages/97/4e/00503f64204bf859b37213a63927028f30fb6268cd8677fb0a5ad48155e1/orjson-3.11.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5f63aaf97afd9f6dec5b1a68e1b8da12bfccb4cb9a9a65c3e0b6c847849e7586", size = 136921, upload-time = "2026-05-06T15:11:02.176Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ba/a23b82a0a8d0ed7bed4e5f5035aae751cad4ff6a1e8d2ecd14d8860f5929/orjson-3.11.9-cp314-cp314-win32.whl", hash = "sha256:e30ab17845bb9fa54ccf67fa4f9f5282652d54faa6d17452f47d0f369d038673", size = 131638, upload-time = "2026-05-06T15:11:03.696Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c3/0c6798456bade745c75c452342dabacce5798196483e77e643be1f53877d/orjson-3.11.9-cp314-cp314-win_amd64.whl", hash = "sha256:32ef5f4283a3be81913947d19608eacb7c6608026851123790cd9cc8982af34b", size = 127078, upload-time = "2026-05-06T15:11:05.123Z" }, + { url = "https://files.pythonhosted.org/packages/16/21/5a3f1e8913103b703a436a5664238e5b965ec392b555fe68943ea3691e6b/orjson-3.11.9-cp314-cp314-win_arm64.whl", hash = "sha256:eebdbdeef0094e4f5aefa20dcd4eb2368ab5e7a3b4edea27f1e7b2892e009cf9", size = 126687, upload-time = "2026-05-06T15:11:06.602Z" }, ] [[package]] @@ -785,60 +792,60 @@ version = "26.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, ] [[package]] name = "pandas" -version = "3.0.2" +version = "3.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy" }, - { name = "python-dateutil" }, - { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, + { name = "numpy" }, + { name = "python-dateutil" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/da/99/b342345300f13440fe9fe385c3c481e2d9a595ee3bab4d3219247ac94e9a/pandas-3.0.2.tar.gz", hash = "sha256:f4753e73e34c8d83221ba58f232433fca2748be8b18dbca02d242ed153945043", size = 4645855, upload-time = "2026-03-31T06:48:30.816Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/87/4341c6252d1c47b08768c3d25ac487362bf403f0313ddae4a2a26c9b1b4c/pandas-3.0.3.tar.gz", hash = "sha256:696a4a00a2a2a35d4e5deb3fc946641b96c944f02230e4f76137fe35d806c4fc", size = 4651414, upload-time = "2026-05-11T18:54:29.21Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/ca/3e639a1ea6fcd0617ca4e8ca45f62a74de33a56ae6cd552735470b22c8d3/pandas-3.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5918ba197c951dec132b0c5929a00c0bf05d5942f590d3c10a807f6e15a57d3", size = 10321105, upload-time = "2026-03-31T06:46:57.327Z" }, - { url = "https://files.pythonhosted.org/packages/0b/77/dbc82ff2fb0e63c6564356682bf201edff0ba16c98630d21a1fb312a8182/pandas-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d606a041c89c0a474a4702d532ab7e73a14fe35c8d427b972a625c8e46373668", size = 9864088, upload-time = "2026-03-31T06:46:59.935Z" }, - { url = "https://files.pythonhosted.org/packages/5c/2b/341f1b04bbca2e17e13cd3f08c215b70ef2c60c5356ef1e8c6857449edc7/pandas-3.0.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:710246ba0616e86891b58ab95f2495143bb2bc83ab6b06747c74216f583a6ac9", size = 10369066, upload-time = "2026-03-31T06:47:02.792Z" }, - { url = "https://files.pythonhosted.org/packages/12/c5/cbb1ffefb20a93d3f0e1fdcda699fb84976210d411b008f97f48bf6ce27e/pandas-3.0.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5d3cfe227c725b1f3dff4278b43d8c784656a42a9325b63af6b1492a8232209e", size = 10876780, upload-time = "2026-03-31T06:47:06.205Z" }, - { url = "https://files.pythonhosted.org/packages/98/fe/2249ae5e0a69bd0ddf17353d0a5d26611d70970111f5b3600cdc8be883e7/pandas-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c3b723df9087a9a9a840e263ebd9f88b64a12075d1bf2ea401a5a42f254f084d", size = 11375181, upload-time = "2026-03-31T06:47:09.383Z" }, - { url = "https://files.pythonhosted.org/packages/de/64/77a38b09e70b6464883b8d7584ab543e748e42c1b5d337a2ee088e0df741/pandas-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a3096110bf9eac0070b7208465f2740e2d8a670d5cb6530b5bb884eca495fd39", size = 11928899, upload-time = "2026-03-31T06:47:12.686Z" }, - { url = "https://files.pythonhosted.org/packages/5e/52/42855bf626868413f761addd574acc6195880ae247a5346477a4361c3acb/pandas-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:07a10f5c36512eead51bc578eb3354ad17578b22c013d89a796ab5eee90cd991", size = 9746574, upload-time = "2026-03-31T06:47:15.64Z" }, - { url = "https://files.pythonhosted.org/packages/88/39/21304ae06a25e8bf9fc820d69b29b2c495b2ae580d1e143146c309941760/pandas-3.0.2-cp313-cp313-win_arm64.whl", hash = "sha256:5fdbfa05931071aba28b408e59226186b01eb5e92bea2ab78b65863ca3228d84", size = 9047156, upload-time = "2026-03-31T06:47:18.595Z" }, - { url = "https://files.pythonhosted.org/packages/72/20/7defa8b27d4f330a903bb68eea33be07d839c5ea6bdda54174efcec0e1d2/pandas-3.0.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:dbc20dea3b9e27d0e66d74c42b2d0c1bed9c2ffe92adea33633e3bedeb5ac235", size = 10756238, upload-time = "2026-03-31T06:47:22.012Z" }, - { url = "https://files.pythonhosted.org/packages/e9/95/49433c14862c636afc0e9b2db83ff16b3ad92959364e52b2955e44c8e94c/pandas-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b75c347eff42497452116ce05ef461822d97ce5b9ff8df6edacb8076092c855d", size = 10408520, upload-time = "2026-03-31T06:47:25.197Z" }, - { url = "https://files.pythonhosted.org/packages/3b/f8/462ad2b5881d6b8ec8e5f7ed2ea1893faa02290d13870a1600fe72ad8efc/pandas-3.0.2-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d1478075142e83a5571782ad007fb201ed074bdeac7ebcc8890c71442e96adf7", size = 10324154, upload-time = "2026-03-31T06:47:28.097Z" }, - { url = "https://files.pythonhosted.org/packages/0a/65/d1e69b649cbcddda23ad6e4c40ef935340f6f652a006e5cbc3555ac8adb3/pandas-3.0.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5880314e69e763d4c8b27937090de570f1fb8d027059a7ada3f7f8e98bdcb677", size = 10714449, upload-time = "2026-03-31T06:47:30.85Z" }, - { url = "https://files.pythonhosted.org/packages/47/a4/85b59bc65b8190ea3689882db6cdf32a5003c0ccd5a586c30fdcc3ffc4fc/pandas-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b5329e26898896f06035241a626d7c335daa479b9bbc82be7c2742d048e41172", size = 11338475, upload-time = "2026-03-31T06:47:34.026Z" }, - { url = "https://files.pythonhosted.org/packages/1e/c4/bc6966c6e38e5d9478b935272d124d80a589511ed1612a5d21d36f664c68/pandas-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:81526c4afd31971f8b62671442a4b2b51e0aa9acc3819c9f0f12a28b6fcf85f1", size = 11786568, upload-time = "2026-03-31T06:47:36.941Z" }, - { url = "https://files.pythonhosted.org/packages/e8/74/09298ca9740beed1d3504e073d67e128aa07e5ca5ca2824b0c674c0b8676/pandas-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:7cadd7e9a44ec13b621aec60f9150e744cfc7a3dd32924a7e2f45edff31823b0", size = 10488652, upload-time = "2026-03-31T06:47:40.612Z" }, - { url = "https://files.pythonhosted.org/packages/bb/40/c6ea527147c73b24fc15c891c3fcffe9c019793119c5742b8784a062c7db/pandas-3.0.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:db0dbfd2a6cdf3770aa60464d50333d8f3d9165b2f2671bcc299b72de5a6677b", size = 10326084, upload-time = "2026-03-31T06:47:43.834Z" }, - { url = "https://files.pythonhosted.org/packages/95/25/bdb9326c3b5455f8d4d3549fce7abcf967259de146fe2cf7a82368141948/pandas-3.0.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0555c5882688a39317179ab4a0ed41d3ebc8812ab14c69364bbee8fb7a3f6288", size = 9914146, upload-time = "2026-03-31T06:47:46.67Z" }, - { url = "https://files.pythonhosted.org/packages/8d/77/3a227ff3337aa376c60d288e1d61c5d097131d0ac71f954d90a8f369e422/pandas-3.0.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:01f31a546acd5574ef77fe199bc90b55527c225c20ccda6601cf6b0fd5ed597c", size = 10444081, upload-time = "2026-03-31T06:47:49.681Z" }, - { url = "https://files.pythonhosted.org/packages/15/88/3cdd54fa279341afa10acf8d2b503556b1375245dccc9315659f795dd2e9/pandas-3.0.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:deeca1b5a931fdf0c2212c8a659ade6d3b1edc21f0914ce71ef24456ca7a6535", size = 10897535, upload-time = "2026-03-31T06:47:53.033Z" }, - { url = "https://files.pythonhosted.org/packages/06/9d/98cc7a7624f7932e40f434299260e2917b090a579d75937cb8a57b9d2de3/pandas-3.0.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0f48afd9bb13300ffb5a3316973324c787054ba6665cda0da3fbd67f451995db", size = 11446992, upload-time = "2026-03-31T06:47:56.193Z" }, - { url = "https://files.pythonhosted.org/packages/9a/cd/19ff605cc3760e80602e6826ddef2824d8e7050ed80f2e11c4b079741dc3/pandas-3.0.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6c4d8458b97a35717b62469a4ea0e85abd5ed8687277f5ccfc67f8a5126f8c53", size = 11968257, upload-time = "2026-03-31T06:47:59.137Z" }, - { url = "https://files.pythonhosted.org/packages/db/60/aba6a38de456e7341285102bede27514795c1eaa353bc0e7638b6b785356/pandas-3.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:b35d14bb5d8285d9494fe93815a9e9307c0876e10f1e8e89ac5b88f728ec8dcf", size = 9865893, upload-time = "2026-03-31T06:48:02.038Z" }, - { url = "https://files.pythonhosted.org/packages/08/71/e5ec979dd2e8a093dacb8864598c0ff59a0cee0bbcdc0bfec16a51684d4f/pandas-3.0.2-cp314-cp314-win_arm64.whl", hash = "sha256:63d141b56ef686f7f0d714cfb8de4e320475b86bf4b620aa0b7da89af8cbdbbb", size = 9188644, upload-time = "2026-03-31T06:48:05.045Z" }, - { url = "https://files.pythonhosted.org/packages/f1/6c/7b45d85db19cae1eb524f2418ceaa9d85965dcf7b764ed151386b7c540f0/pandas-3.0.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:140f0cffb1fa2524e874dde5b477d9defe10780d8e9e220d259b2c0874c89d9d", size = 10776246, upload-time = "2026-03-31T06:48:07.789Z" }, - { url = "https://files.pythonhosted.org/packages/a8/3e/7b00648b086c106e81766f25322b48aa8dfa95b55e621dbdf2fdd413a117/pandas-3.0.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ae37e833ff4fed0ba352f6bdd8b73ba3ab3256a85e54edfd1ab51ae40cca0af8", size = 10424801, upload-time = "2026-03-31T06:48:10.897Z" }, - { url = "https://files.pythonhosted.org/packages/da/6e/558dd09a71b53b4008e7fc8a98ec6d447e9bfb63cdaeea10e5eb9b2dabe8/pandas-3.0.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4d888a5c678a419a5bb41a2a93818e8ed9fd3172246555c0b37b7cc27027effd", size = 10345643, upload-time = "2026-03-31T06:48:13.7Z" }, - { url = "https://files.pythonhosted.org/packages/be/e3/921c93b4d9a280409451dc8d07b062b503bbec0531d2627e73a756e99a82/pandas-3.0.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b444dc64c079e84df91baa8bf613d58405645461cabca929d9178f2cd392398d", size = 10743641, upload-time = "2026-03-31T06:48:16.659Z" }, - { url = "https://files.pythonhosted.org/packages/56/ca/fd17286f24fa3b4d067965d8d5d7e14fe557dd4f979a0b068ac0deaf8228/pandas-3.0.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:4544c7a54920de8eeacaa1466a6b7268ecfbc9bc64ab4dbb89c6bbe94d5e0660", size = 11361993, upload-time = "2026-03-31T06:48:19.475Z" }, - { url = "https://files.pythonhosted.org/packages/e4/a5/2f6ed612056819de445a433ca1f2821ac3dab7f150d569a59e9cc105de1d/pandas-3.0.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:734be7551687c00fbd760dc0522ed974f82ad230d4a10f54bf51b80d44a08702", size = 11815274, upload-time = "2026-03-31T06:48:22.695Z" }, - { url = "https://files.pythonhosted.org/packages/00/2f/b622683e99ec3ce00b0854bac9e80868592c5b051733f2cf3a868e5fea26/pandas-3.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:57a07209bebcbcf768d2d13c9b78b852f9a15978dac41b9e6421a81ad4cdd276", size = 10888530, upload-time = "2026-03-31T06:48:25.806Z" }, - { url = "https://files.pythonhosted.org/packages/cb/2b/f8434233fab2bd66a02ec014febe4e5adced20e2693e0e90a07d118ed30e/pandas-3.0.2-cp314-cp314t-win_arm64.whl", hash = "sha256:5371b72c2d4d415d08765f32d689217a43227484e81b2305b52076e328f6f482", size = 9455341, upload-time = "2026-03-31T06:48:28.418Z" }, + { url = "https://files.pythonhosted.org/packages/c5/90/62d8302883c44308c477e222c3daf7c813a34c8e96985882fbd53d964352/pandas-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:67b3b64c11910cfa29f4e94a14d3bff9ee693b6fc76055e7cad549cee0aec5fa", size = 10331071, upload-time = "2026-05-11T18:52:58.838Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ae/6a6493c783a101f165e4356953ba3c74d6f77f0042fa7d753da9dfbb640c/pandas-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39436b377d56d2a2e52d0395bdbee171f01068e99af5250509aceeb929f765c7", size = 9875690, upload-time = "2026-05-11T18:53:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/62/7c/5df8e9f56c69a2769fbe9382a5ef8f2658c007e376434e1e2cbb57ad895f/pandas-3.0.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4be06d68f9ddcfc645b87534911da79a8fbffc7573c80e0edcf42a5020624d8", size = 10381634, upload-time = "2026-05-11T18:53:04.393Z" }, + { url = "https://files.pythonhosted.org/packages/99/68/1237369725aa617bb358263d535803e3053fdbc593513ec5ed9c9896b5b6/pandas-3.0.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4eeb6830daf35a71cc09649bd823e2b542dac246cdee9614c6e4bd65028cd6a", size = 10891243, upload-time = "2026-05-11T18:53:07.643Z" }, + { url = "https://files.pythonhosted.org/packages/25/93/77d108e8af7222b4a503ebde0e30215b1c2e4f8e53a526431890f22d5586/pandas-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1928e07221f82db493cd4af1e23c1bfca524a19a4699887975bff68f49a72bfb", size = 11388659, upload-time = "2026-05-11T18:53:10.634Z" }, + { url = "https://files.pythonhosted.org/packages/d0/bd/eff5b4399f332ac386c853f6cd2bd3fa2ca0061b9f36ecd9c4d7c4265649/pandas-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51b1fe551acb77dac643c6fda86084d8d446c10fe64b06a9cc29c4cc8540e7f2", size = 11942880, upload-time = "2026-05-11T18:53:13.536Z" }, + { url = "https://files.pythonhosted.org/packages/2c/20/559ace4200982c3887d0b86bfd0d856a2143ef8ddab63cc07934951a964c/pandas-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:a82d532a3351d435432cd913edbccaf8b8e01d4dd0e5ced5a8d2e8ecd94c7e44", size = 9757091, upload-time = "2026-05-11T18:53:16.306Z" }, + { url = "https://files.pythonhosted.org/packages/3a/66/69055a09fe200f29f922a3eeec4804611900b95f52d932ece3393c3c0c19/pandas-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:275c14e0fce14a2ec20eee474aecd305478ea3c1e6f6a9d8fe219a165542717e", size = 9057282, upload-time = "2026-05-11T18:53:18.768Z" }, + { url = "https://files.pythonhosted.org/packages/57/0e/efe801b0e6811e8e650cd21b7f2608e30f08a7067e2bf6e8752b0d56ee3c/pandas-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:46997386d528eb40376ecd6b033cf4a8a1e5282580f68f43de875b78cba2199d", size = 10767016, upload-time = "2026-05-11T18:53:21.227Z" }, + { url = "https://files.pythonhosted.org/packages/ea/dc/eb55135a1d5f0f0519f28da1f609a206d2cad1f9c35c32d51e38dd7261ae/pandas-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:261e308dfb22448384b7580cf719d2f998fe2966c92893c3e77d14008af1f066", size = 10420210, upload-time = "2026-05-11T18:53:23.982Z" }, + { url = "https://files.pythonhosted.org/packages/c6/3e/b1d5d955ce33ffecb407465a60bc32769d74fcf68224b7ae67ae11d4dea4/pandas-3.0.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd1a5d1def6a46002e964510bdc67c368aa0951df5d1d9f8365336f5a1f490cd", size = 10336126, upload-time = "2026-05-11T18:53:26.731Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/a01261711ab60a22d71b862f0de20e4c504bf80457270ad8cb42110f6abc/pandas-3.0.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d72828c20c6d6e83e1e22a6a3b47b326b71664112fa9705dcbccfd7a39b62085", size = 10728051, upload-time = "2026-05-11T18:53:29.125Z" }, + { url = "https://files.pythonhosted.org/packages/e9/21/ea191195e587b18cf682e97f433f81b2d0fbe341380e80a3e0d6e4403c8e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d26cbe1fcfc12e8fd900e2454163e466b2d3af84f7c75481df7683ffc073d870", size = 11350796, upload-time = "2026-05-11T18:53:32.056Z" }, + { url = "https://files.pythonhosted.org/packages/64/69/f0eaaf54939f0e8c6768fd06be9af2cef9b36048b96dfb9e1b2c685a807e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e91cec1879ada0624fc3dc9953c5cbd60208e59c0db28f540c5d6d47502422f", size = 11799741, upload-time = "2026-05-11T18:53:34.985Z" }, + { url = "https://files.pythonhosted.org/packages/45/a4/865e0e510cae5fc2194de4db28be638952de942571ba9125934fd9c01d47/pandas-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:08d789b41f87e0905880e293cedf6197ce71fe67cc081358b1e148a491b9bd13", size = 10499958, upload-time = "2026-05-11T18:53:37.857Z" }, + { url = "https://files.pythonhosted.org/packages/86/54/effdcc3c0ff7a08037889200e148ebe94c16c4f653be078c7b3675955df1/pandas-3.0.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3650109c0f22879df8bd6179ab9ee3d7f1d1d4e7e0094a3f0032d9f51e2e64ac", size = 10336065, upload-time = "2026-05-11T18:53:41.099Z" }, + { url = "https://files.pythonhosted.org/packages/68/10/bf2d6738d72748b961a3751ab89522d58c54efc36a8e1a12161216cd45cf/pandas-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bab900348131a7db1f69a7309ef141fd5680f1487094193bcbbb61791573bf8f", size = 9926101, upload-time = "2026-05-11T18:53:43.515Z" }, + { url = "https://files.pythonhosted.org/packages/ae/e9/e35cf11c8a136e757b956f5f0efdcaa50aecde85ea055f1898dfc68262f3/pandas-3.0.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba7e08b9ac1d54569cd1e256e3668975ed624d6826f7b68df0342b012007bddb", size = 10457553, upload-time = "2026-05-11T18:53:46.394Z" }, + { url = "https://files.pythonhosted.org/packages/58/3b/1cdec6772bdbaf7b25dab360c59f03cadf05492dd724c6540af905389b07/pandas-3.0.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d71c63ae4ebdbf70209742096f1fc46a83a0613c99d4b23766cced9ff8cd62a", size = 10914065, upload-time = "2026-05-11T18:53:49.134Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c2/1ef644445fcd72e3627bceec77e3560636f87ddce4ed841afe76b83b5bf9/pandas-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3a2ec42c98ffa2565a67e08e218d06d72576d758d90facb7c00805194d8f360", size = 11459188, upload-time = "2026-05-11T18:53:52.527Z" }, + { url = "https://files.pythonhosted.org/packages/7e/49/4d8d4f42cbc9c4adc7a1870f269c02cbd6cd40d059622c06fb298addcbad/pandas-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:335f62418ed562cfc3c49e9e196375c28b729dcef8543abf4f9438e381bf3c76", size = 11982966, upload-time = "2026-05-11T18:53:55.043Z" }, + { url = "https://files.pythonhosted.org/packages/38/55/792619469bab9882d8bbd5865d45a72f6478762d04a9af4bf0d08c503e95/pandas-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:3c20a521bbb85902f79f7270c80a59e1b5452d96d170c034f207181870f97ac5", size = 9876755, upload-time = "2026-05-11T18:53:58.067Z" }, + { url = "https://files.pythonhosted.org/packages/2a/af/33c469653b0ba03b50c3a98192d4c07f0c75c66b263ceb097fce0ee97d31/pandas-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:a2d2dff8a04f3917b55ab3910c32990f8ddf7eceba114947838cefa976a68977", size = 9198658, upload-time = "2026-05-11T18:54:00.733Z" }, + { url = "https://files.pythonhosted.org/packages/a2/fa/b8c257bd76b8bd060c3a9151c1fca05e9b9c5e3af5d0f549c0356f6d143d/pandas-3.0.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:0d589105b3c14645af1738ff279b2995102d8f7a03b0a66dc8d95550eb513e04", size = 10787242, upload-time = "2026-05-11T18:54:03.564Z" }, + { url = "https://files.pythonhosted.org/packages/54/eb/f19206ffb0bf1919002969aa448b4702c6594845156a6f8050674855aac3/pandas-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:13fc1e853d9e04743d11ba75a985ccbc2a317fe07d8af61e445a6fd24dacd6a6", size = 10436369, upload-time = "2026-05-11T18:54:06.311Z" }, + { url = "https://files.pythonhosted.org/packages/fd/24/c7c39fb4fe22b71a0c2d78bf0c585c600092d85f94f086d2b3b2f6ca27e2/pandas-3.0.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:819959dab7bbd0049c15623fbac4e29a191b9528160a61fb1032242d8ced2d9c", size = 10358306, upload-time = "2026-05-11T18:54:09.085Z" }, + { url = "https://files.pythonhosted.org/packages/16/ec/dd2a9eb7fa1204df88c0864164e35b228ac581062ac612ba0a67fd812e4c/pandas-3.0.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:60ae316d3fd75d1858d450d0db0103ea2be3e7d4a95ec2f064f7e2ae63f7b028", size = 10758394, upload-time = "2026-05-11T18:54:11.956Z" }, + { url = "https://files.pythonhosted.org/packages/95/6e/00c61ea8e85b4f6d8d35e11852a1a4998fc7fafc91c6a602d1cc9c972d64/pandas-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd3a518890b400d32f9023722dc9a9a5c969f00b415419a3c06c043f09bb5d7d", size = 11375717, upload-time = "2026-05-11T18:54:14.539Z" }, + { url = "https://files.pythonhosted.org/packages/31/89/8fc1c268969fac43688d65fd92e67df24bd128d53cb4d2eee534cd307399/pandas-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c39be2d709d01fa972a0cabc522389fceca4f3969332ba25a7d6c5802cf976a", size = 11828897, upload-time = "2026-05-11T18:54:17.146Z" }, + { url = "https://files.pythonhosted.org/packages/56/3b/e7d20dea247a3e6dc0bd8a6953854afbedc03951def4e7371e05e7263e25/pandas-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4db8c527972a821cf5286b40ccc57642a39bc62e62022b42f99f8a67fca8c3a1", size = 10900855, upload-time = "2026-05-11T18:54:19.72Z" }, + { url = "https://files.pythonhosted.org/packages/0f/54/68a0978d1ef8502b8492099beaa6e7a0c1b32e3b5d4f677f5810cb08711c/pandas-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1", size = 9466464, upload-time = "2026-05-11T18:54:22.754Z" }, ] [[package]] name = "platformdirs" -version = "4.9.6" +version = "4.10.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9f/4a/0883b8e3802965322523f0b200ecf33d31f10991d0401162f4b23c698b42/platformdirs-4.9.6.tar.gz", hash = "sha256:3bfa75b0ad0db84096ae777218481852c0ebc6c727b3168c1b9e0118e458cf0a", size = 29400, upload-time = "2026-04-09T00:04:10.812Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/47/e4501f49c178ae1d9f4a75073fda4204f52647993f075a9db4d14930e0c5/platformdirs-4.10.0.tar.gz", hash = "sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7", size = 31224, upload-time = "2026-05-28T03:32:53.587Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/75/a6/a0a304dc33b49145b21f4808d763822111e67d1c3a32b524a1baf947b6e1/platformdirs-4.9.6-py3-none-any.whl", hash = "sha256:e61adb1d5e5cb3441b4b7710bea7e4c12250ca49439228cc1021c00dcfac0917", size = 21348, upload-time = "2026-04-09T00:04:09.463Z" }, + { url = "https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl", hash = "sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a", size = 22743, upload-time = "2026-05-28T03:32:52.175Z" }, ] [[package]] @@ -847,22 +854,22 @@ version = "1.6.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] name = "posthog" -version = "7.15.3" +version = "7.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "backoff" }, - { name = "distro" }, - { name = "requests" }, - { name = "typing-extensions" }, + { name = "backoff" }, + { name = "distro" }, + { name = "requests" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c5/ad/0eedae8cc9d2878d5b52c8607bd21f76101cfe4d875e5ff77fec9da3a83c/posthog-7.15.3.tar.gz", hash = "sha256:809dcaf08ca2d8bc0ea8228c28419181b74a79dfd1c0687a3d459a7bbe2e2953", size = 217645, upload-time = "2026-05-21T15:35:04.914Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b4/4f/a954175c862a3565d02c3f627874d85f18313472a0c4b08f45d84aaf3315/posthog-7.16.1.tar.gz", hash = "sha256:3619d3c619ad01f36c6d465e084950882417c63021eb3cfacacb23f900ec52d4", size = 226343, upload-time = "2026-05-27T18:46:20.129Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ad/b4/8dc673bed0f296c1acbb1107aef1c56db576731e894fe765206be5a91774/posthog-7.15.3-py3-none-any.whl", hash = "sha256:fd59fe4f5be637e4a2706b1457301d8308853ff23659036ecfcf6ac0a2d45eee", size = 254591, upload-time = "2026-05-21T15:35:02.846Z" }, + { url = "https://files.pythonhosted.org/packages/3e/28/0f840699a1d0db3c1e5483c6208f0804a51f21ccfa34e6aa356161606adc/posthog-7.16.1-py3-none-any.whl", hash = "sha256:fd5aa4510033f3b039fda2fbfce45f493d140d4782f681e69639793dda317d67", size = 264231, upload-time = "2026-05-27T18:46:17.933Z" }, ] [[package]] @@ -870,132 +877,132 @@ name = "pre-commit" version = "4.6.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "cfgv" }, - { name = "identify" }, - { name = "nodeenv" }, - { name = "pyyaml" }, - { name = "virtualenv" }, + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, ] sdist = { url = "https://files.pythonhosted.org/packages/8e/22/2de9408ac81acbb8a7d05d4cc064a152ccf33b3d480ebe0cd292153db239/pre_commit-4.6.0.tar.gz", hash = "sha256:718d2208cef53fdc38206e40524a6d4d9576d103eb16f0fec11c875e7716e9d9", size = 198525, upload-time = "2026-04-21T20:31:41.613Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl", hash = "sha256:e2cf246f7299edcabcf15f9b0571fdce06058527f0a06535068a86d38089f29b", size = 226472, upload-time = "2026-04-21T20:31:40.092Z" }, + { url = "https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl", hash = "sha256:e2cf246f7299edcabcf15f9b0571fdce06058527f0a06535068a86d38089f29b", size = 226472, upload-time = "2026-04-21T20:31:40.092Z" }, ] [[package]] name = "psycopg" -version = "3.3.3" +version = "3.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "tzdata", marker = "sys_platform == 'win32'" }, + { name = "tzdata", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d3/b6/379d0a960f8f435ec78720462fd94c4863e7a31237cf81bf76d0af5883bf/psycopg-3.3.3.tar.gz", hash = "sha256:5e9a47458b3c1583326513b2556a2a9473a1001a56c9efe9e587245b43148dd9", size = 165624, upload-time = "2026-02-18T16:52:16.546Z" } +sdist = { url = "https://files.pythonhosted.org/packages/db/2f/cb91e5502ec9de1de6f1b76cfbf69531932725361168bb06963620c77e2e/psycopg-3.3.4.tar.gz", hash = "sha256:e21207764952cff81b6b8bdacad9a3939f2793367fdac2987b3aac36a651b5bc", size = 165799, upload-time = "2026-05-01T23:31:55.179Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/5b/181e2e3becb7672b502f0ed7f16ed7352aca7c109cfb94cf3878a9186db9/psycopg-3.3.3-py3-none-any.whl", hash = "sha256:f96525a72bcfade6584ab17e89de415ff360748c766f0106959144dcbb38c698", size = 212768, upload-time = "2026-02-18T16:46:27.365Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e0/7b3dee031daae7743609ce3c746565d4a3ed7c2c186479eb48e34e838c64/psycopg-3.3.4-py3-none-any.whl", hash = "sha256:b6bbc25ccf05c8fad3b061d9db2ef0909a555171b84b07f29458a447253d679a", size = 213001, upload-time = "2026-05-01T23:20:50.816Z" }, ] [package.optional-dependencies] binary = [ - { name = "psycopg-binary", marker = "implementation_name != 'pypy'" }, + { name = "psycopg-binary", marker = "implementation_name != 'pypy'" }, ] [[package]] name = "psycopg-binary" -version = "3.3.3" +version = "3.3.4" source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/0a/cac9fdf1df16a269ba0e5f0f06cac61f826c94cadb39df028cdfe19d3a33/psycopg_binary-3.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05f32239aec25c5fb15f7948cffdc2dc0dac098e48b80a140e4ba32b572a2e7d", size = 4590414, upload-time = "2026-02-18T16:50:01.441Z" }, - { url = "https://files.pythonhosted.org/packages/9c/c0/d8f8508fbf440edbc0099b1abff33003cd80c9e66eb3a1e78834e3fb4fb9/psycopg_binary-3.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c84f9d214f2d1de2fafebc17fa68ac3f6561a59e291553dfc45ad299f4898c1", size = 4669021, upload-time = "2026-02-18T16:50:08.803Z" }, - { url = "https://files.pythonhosted.org/packages/04/05/097016b77e343b4568feddf12c72171fc513acef9a4214d21b9478569068/psycopg_binary-3.3.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:e77957d2ba17cada11be09a5066d93026cdb61ada7c8893101d7fe1c6e1f3925", size = 5467453, upload-time = "2026-02-18T16:50:14.985Z" }, - { url = "https://files.pythonhosted.org/packages/91/23/73244e5feb55b5ca109cede6e97f32ef45189f0fdac4c80d75c99862729d/psycopg_binary-3.3.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:42961609ac07c232a427da7c87a468d3c82fee6762c220f38e37cfdacb2b178d", size = 5151135, upload-time = "2026-02-18T16:50:24.82Z" }, - { url = "https://files.pythonhosted.org/packages/11/49/5309473b9803b207682095201d8708bbc7842ddf3f192488a69204e36455/psycopg_binary-3.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ae07a3114313dd91fce686cab2f4c44af094398519af0e0f854bc707e1aeedf1", size = 6737315, upload-time = "2026-02-18T16:50:35.106Z" }, - { url = "https://files.pythonhosted.org/packages/d4/5d/03abe74ef34d460b33c4d9662bf6ec1dd38888324323c1a1752133c10377/psycopg_binary-3.3.3-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d257c58d7b36a621dcce1d01476ad8b60f12d80eb1406aee4cf796f88b2ae482", size = 4979783, upload-time = "2026-02-18T16:50:42.067Z" }, - { url = "https://files.pythonhosted.org/packages/f0/6c/3fbf8e604e15f2f3752900434046c00c90bb8764305a1b81112bff30ba24/psycopg_binary-3.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:07c7211f9327d522c9c47560cae00a4ecf6687f4e02d779d035dd3177b41cb12", size = 4509023, upload-time = "2026-02-18T16:50:50.116Z" }, - { url = "https://files.pythonhosted.org/packages/9c/6b/1a06b43b7c7af756c80b67eac8bfaa51d77e68635a8a8d246e4f0bb7604a/psycopg_binary-3.3.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:8e7e9eca9b363dbedeceeadd8be97149d2499081f3c52d141d7cd1f395a91f83", size = 4185874, upload-time = "2026-02-18T16:50:55.97Z" }, - { url = "https://files.pythonhosted.org/packages/2b/d3/bf49e3dcaadba510170c8d111e5e69e5ae3f981c1554c5bb71c75ce354bb/psycopg_binary-3.3.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:cb85b1d5702877c16f28d7b92ba030c1f49ebcc9b87d03d8c10bf45a2f1c7508", size = 3925668, upload-time = "2026-02-18T16:51:03.299Z" }, - { url = "https://files.pythonhosted.org/packages/f8/92/0aac830ed6a944fe334404e1687a074e4215630725753f0e3e9a9a595b62/psycopg_binary-3.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4d4606c84d04b80f9138d72f1e28c6c02dc5ae0c7b8f3f8aaf89c681ce1cd1b1", size = 4234973, upload-time = "2026-02-18T16:51:09.097Z" }, - { url = "https://files.pythonhosted.org/packages/2e/96/102244653ee5a143ece5afe33f00f52fe64e389dfce8dbc87580c6d70d3d/psycopg_binary-3.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:74eae563166ebf74e8d950ff359be037b85723d99ca83f57d9b244a871d6c13b", size = 3551342, upload-time = "2026-02-18T16:51:13.892Z" }, - { url = "https://files.pythonhosted.org/packages/a2/71/7a57e5b12275fe7e7d84d54113f0226080423a869118419c9106c083a21c/psycopg_binary-3.3.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:497852c5eaf1f0c2d88ab74a64a8097c099deac0c71de1cbcf18659a8a04a4b2", size = 4607368, upload-time = "2026-02-18T16:51:19.295Z" }, - { url = "https://files.pythonhosted.org/packages/c7/04/cb834f120f2b2c10d4003515ef9ca9d688115b9431735e3936ae48549af8/psycopg_binary-3.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:258d1ea53464d29768bf25930f43291949f4c7becc706f6e220c515a63a24edd", size = 4687047, upload-time = "2026-02-18T16:51:23.84Z" }, - { url = "https://files.pythonhosted.org/packages/40/e9/47a69692d3da9704468041aa5ed3ad6fc7f6bb1a5ae788d261a26bbca6c7/psycopg_binary-3.3.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:111c59897a452196116db12e7f608da472fbff000693a21040e35fc978b23430", size = 5487096, upload-time = "2026-02-18T16:51:29.645Z" }, - { url = "https://files.pythonhosted.org/packages/0b/b6/0e0dd6a2f802864a4ae3dbadf4ec620f05e3904c7842b326aafc43e5f464/psycopg_binary-3.3.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:17bb6600e2455993946385249a3c3d0af52cd70c1c1cdbf712e9d696d0b0bf1b", size = 5168720, upload-time = "2026-02-18T16:51:36.499Z" }, - { url = "https://files.pythonhosted.org/packages/6f/0d/977af38ac19a6b55d22dff508bd743fd7c1901e1b73657e7937c7cccb0a3/psycopg_binary-3.3.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:642050398583d61c9856210568eb09a8e4f2fe8224bf3be21b67a370e677eead", size = 6762076, upload-time = "2026-02-18T16:51:43.167Z" }, - { url = "https://files.pythonhosted.org/packages/34/40/912a39d48322cf86895c0eaf2d5b95cb899402443faefd4b09abbba6b6e1/psycopg_binary-3.3.3-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:533efe6dc3a7cba5e2a84e38970786bb966306863e45f3db152007e9f48638a6", size = 4997623, upload-time = "2026-02-18T16:51:47.707Z" }, - { url = "https://files.pythonhosted.org/packages/98/0c/c14d0e259c65dc7be854d926993f151077887391d5a081118907a9d89603/psycopg_binary-3.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5958dbf28b77ce2033482f6cb9ef04d43f5d8f4b7636e6963d5626f000efb23e", size = 4532096, upload-time = "2026-02-18T16:51:51.421Z" }, - { url = "https://files.pythonhosted.org/packages/39/21/8b7c50a194cfca6ea0fd4d1f276158307785775426e90700ab2eba5cd623/psycopg_binary-3.3.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:a6af77b6626ce92b5817bf294b4d45ec1a6161dba80fc2d82cdffdd6814fd023", size = 4208884, upload-time = "2026-02-18T16:51:57.336Z" }, - { url = "https://files.pythonhosted.org/packages/c7/2c/a4981bf42cf30ebba0424971d7ce70a222ae9b82594c42fc3f2105d7b525/psycopg_binary-3.3.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:47f06fcbe8542b4d96d7392c476a74ada521c5aebdb41c3c0155f6595fc14c8d", size = 3944542, upload-time = "2026-02-18T16:52:04.266Z" }, - { url = "https://files.pythonhosted.org/packages/60/e9/b7c29b56aa0b85a4e0c4d89db691c1ceef08f46a356369144430c155a2f5/psycopg_binary-3.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e7800e6c6b5dc4b0ca7cc7370f770f53ac83886b76afda0848065a674231e856", size = 4254339, upload-time = "2026-02-18T16:52:10.444Z" }, - { url = "https://files.pythonhosted.org/packages/98/5a/291d89f44d3820fffb7a04ebc8f3ef5dda4f542f44a5daea0c55a84abf45/psycopg_binary-3.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:165f22ab5a9513a3d7425ffb7fcc7955ed8ccaeef6d37e369d6cc1dff1582383", size = 3652796, upload-time = "2026-02-18T16:52:14.02Z" }, + { url = "https://files.pythonhosted.org/packages/09/43/13e9c406fbbf354580476e248a16b64802a376873ebe6339e30bb655572d/psycopg_binary-3.3.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fbd1d4ed566895ad2d3bf4ddfd8bae90026930ddf29df3b9d91d32c8c47866a7", size = 4590377, upload-time = "2026-05-01T23:29:18.782Z" }, + { url = "https://files.pythonhosted.org/packages/22/be/2923cd7c3683e7afdecf4f10796a18de02f5c5ddc0969aa2ad0a8cdd3bbd/psycopg_binary-3.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:75a9067e236f9b9ae3535b66fe99bddb33d39c0de10112e49b9ab11eee53dc31", size = 4669023, upload-time = "2026-05-01T23:29:25.884Z" }, + { url = "https://files.pythonhosted.org/packages/96/a0/2c913d6fe13d6a8bd13597d36739bf47af063ad9399e402cfecab16f3c1e/psycopg_binary-3.3.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:b56b603ebcea8aa10b46228b8410ba7f13e7c2ee54389d4d9be0927fd8ce2a70", size = 5467423, upload-time = "2026-05-01T23:29:33.416Z" }, + { url = "https://files.pythonhosted.org/packages/e7/38/205d10bc1ad0df4a21c5c51659126bd3ea0ef98fcad1e852f78c249bb9c3/psycopg_binary-3.3.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c677c4ad433cb7150c8cd304a0769ae3bcfbe5ea0676eb53faa7b1443b16d0d3", size = 5151137, upload-time = "2026-05-01T23:29:42.013Z" }, + { url = "https://files.pythonhosted.org/packages/36/fc/f0381ddcd45eff3bb70dbca6823a996048d7f507b2ec3fc92c6fabc0fe87/psycopg_binary-3.3.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:26df2717e59c0473e4465a97dfb1b7afebaa479277870fd5784d1436470db47c", size = 6736671, upload-time = "2026-05-01T23:29:51.626Z" }, + { url = "https://files.pythonhosted.org/packages/95/40/fa545ae152c24327651e5624e4902121e808270be36c10b12e9939be09bc/psycopg_binary-3.3.4-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1dc1f79fd16bb1f3f4421417a514607539f17804d95c7ed617265369d1981cae", size = 4979601, upload-time = "2026-05-01T23:29:56.961Z" }, + { url = "https://files.pythonhosted.org/packages/86/e4/2f8a47ee97f90cd2b933d0463081d35631ff419de2b8c984a5f369857de0/psycopg_binary-3.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:136f199a407b5348b9b857c504aff60c77622a28482e7195839ce1b51238c4cc", size = 4510513, upload-time = "2026-05-01T23:30:07.243Z" }, + { url = "https://files.pythonhosted.org/packages/0e/0e/94e842ff4a7f98ed162580ca2e8b8864b28c1e0350f2443f8ee47f821167/psycopg_binary-3.3.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b6f5a29e9c775b9f12a1a717aa7a2c80f9e1db6f27ba44a5b59c80ac61d2ffcf", size = 4187243, upload-time = "2026-05-01T23:30:15.352Z" }, + { url = "https://files.pythonhosted.org/packages/d0/83/fc6c174b672e29b7de996ea77b6cbddf46c891751c3355f6974292baa6b4/psycopg_binary-3.3.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:ee17a2cf4943cde261adfad1bbc5bf38d6b3776d7afff74c7cabcbeaeb08c260", size = 3927347, upload-time = "2026-05-01T23:30:21.186Z" }, + { url = "https://files.pythonhosted.org/packages/e9/65/768364d4a97a15b1a7f47ba52688c1686f22941d8332a8398cefc468e25f/psycopg_binary-3.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5c4ab71be17bdca30cb34c34c4e1496e2f5d6f20c199c12bad226070b22ef9bf", size = 4236393, upload-time = "2026-05-01T23:30:26.211Z" }, + { url = "https://files.pythonhosted.org/packages/bd/3b/218efbc9e645becd80cdf651acda05f85cfe546b7a9c0458c7cbc8fe1f74/psycopg_binary-3.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:dbfdb9b6cc79f31104a7b162a2b921b765fcc62af6c00540a167a8de47e4ed38", size = 3564592, upload-time = "2026-05-01T23:30:31.764Z" }, + { url = "https://files.pythonhosted.org/packages/48/a6/828c9185701dab71b234c2a76c38a08b098ebfec5020716b4e93807492b5/psycopg_binary-3.3.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:28b7398fdd19db3232c884fb24550bdfe951221f510e195e233299e4c9b78f97", size = 4607292, upload-time = "2026-05-01T23:30:38.962Z" }, + { url = "https://files.pythonhosted.org/packages/92/58/5b40dbc9d839045c9dae956960e4fb6d20bcabe6c59a2aa34fc3a371913f/psycopg_binary-3.3.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1fbaa292a3c8bb61b45df1ad3da1908ccee7cb889db9425e3557d9e34e2a4829", size = 4687023, upload-time = "2026-05-01T23:30:47.227Z" }, + { url = "https://files.pythonhosted.org/packages/85/a9/793f0ac107a9003b48441d0d1f9f616d96e0f37458dd8dc12528ceff55fb/psycopg_binary-3.3.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:94596f9e7633ee3f6440711d43bb70aa31cc0a46a900ab8b4201a366ace5c9e7", size = 5486985, upload-time = "2026-05-01T23:30:55.517Z" }, + { url = "https://files.pythonhosted.org/packages/8f/26/42e8533497e2592334f68ec529cf5f840f7fa4e99575a4bb61aa184dbfbf/psycopg_binary-3.3.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8c0056529e68dbe9184cd4019a1f3d8f3a4ead2f6fc7a5afcf27d3314edd1277", size = 5168745, upload-time = "2026-05-01T23:31:01.904Z" }, + { url = "https://files.pythonhosted.org/packages/15/af/b7151776cc08d5935d45c833ec818a9beb417cf7c08239af1aafbdae78ee/psycopg_binary-3.3.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c09aad7051326e7603c14e50636db9c01f78272dc54b3accff03d46370461e6", size = 6761486, upload-time = "2026-05-01T23:31:14.511Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ed/c92533b9124712d592cbf1cd6c76da933a2e0acea81dfe1fbe7e735f0cff/psycopg_binary-3.3.4-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:514404ed543efd620c85602b747df2a23cf1241b4067199e1a66f2d2757aaa41", size = 4997427, upload-time = "2026-05-01T23:31:20.901Z" }, + { url = "https://files.pythonhosted.org/packages/a2/23/ccadfd0de416aa188356daa199453af24087b042e296088706d190ae0295/psycopg_binary-3.3.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:46893c26858be12cc49ca4226ed6a60b4bfccadd946b3bebb783a60b38788228", size = 4533549, upload-time = "2026-05-01T23:31:26.204Z" }, + { url = "https://files.pythonhosted.org/packages/fd/a0/c8f43cee36386f7bc891ab41a9d31ea07cf9826038e732da79f26b1e5f34/psycopg_binary-3.3.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:df1d567fc430f6df15c9fcf67d87685fc49bdb325adc0db5af1adfb2f44eb5c9", size = 4210256, upload-time = "2026-05-01T23:31:33.884Z" }, + { url = "https://files.pythonhosted.org/packages/4e/2c/c1547871be3790676e8868b38655496422f94f0978dfb66b74bdba2f1676/psycopg_binary-3.3.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:6b9016b1714da4dd5ecaaa75b82098aa5a0b87854ce9b092e21c27c4ae23e014", size = 3946204, upload-time = "2026-05-01T23:31:39.626Z" }, + { url = "https://files.pythonhosted.org/packages/c4/b1/f6670f00fa7ea601584623f6c11602ab92117d83eaff885e0210f6de7418/psycopg_binary-3.3.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:47c656a8a7ba6eb0cff1801a4caaa9c8bdc12d03080e273aff1c8ac39971a77e", size = 4255811, upload-time = "2026-05-01T23:31:44.986Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e6/5fff07a70d1f945ed90ae131c3bd76cab32beff7c58c6db15ad5820b6d1f/psycopg_binary-3.3.4-cp314-cp314-win_amd64.whl", hash = "sha256:c37e024c07308cd06cf3ec51bfd0e7f6157585a4d84d1bce4a7f5f7913719bf8", size = 3666849, upload-time = "2026-05-01T23:31:51.165Z" }, ] [[package]] name = "pydantic" -version = "2.13.3" +version = "2.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "annotated-types" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d9/e4/40d09941a2cebcb20609b86a559817d5b9291c49dd6f8c87e5feffbe703a/pydantic-2.13.3.tar.gz", hash = "sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d", size = 844068, upload-time = "2026-04-20T14:46:43.632Z" } +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/0a/fd7d723f8f8153418fb40cf9c940e82004fce7e987026b08a68a36dd3fe7/pydantic-2.13.3-py3-none-any.whl", hash = "sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927", size = 471981, upload-time = "2026-04-20T14:46:41.402Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, ] [[package]] name = "pydantic-core" -version = "2.46.3" +version = "2.46.4" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2a/ef/f7abb56c49382a246fd2ce9c799691e3c3e7175ec74b14d99e798bcddb1a/pydantic_core-2.46.3.tar.gz", hash = "sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c", size = 471412, upload-time = "2026-04-20T14:40:56.672Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9b/3c/9b5e8eb9821936d065439c3b0fb1490ffa64163bfe7e1595985a47896073/pydantic_core-2.46.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37", size = 2102109, upload-time = "2026-04-20T14:41:24.219Z" }, - { url = "https://files.pythonhosted.org/packages/91/97/1c41d1f5a19f241d8069f1e249853bcce378cdb76eec8ab636d7bc426280/pydantic_core-2.46.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f", size = 1951820, upload-time = "2026-04-20T14:42:14.236Z" }, - { url = "https://files.pythonhosted.org/packages/30/b4/d03a7ae14571bc2b6b3c7b122441154720619afe9a336fa3a95434df5e2f/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8", size = 1977785, upload-time = "2026-04-20T14:42:31.648Z" }, - { url = "https://files.pythonhosted.org/packages/ae/0c/4086f808834b59e3c8f1aa26df8f4b6d998cdcf354a143d18ef41529d1fe/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad", size = 2062761, upload-time = "2026-04-20T14:40:37.093Z" }, - { url = "https://files.pythonhosted.org/packages/fa/71/a649be5a5064c2df0db06e0a512c2281134ed2fcc981f52a657936a7527c/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c", size = 2232989, upload-time = "2026-04-20T14:42:59.254Z" }, - { url = "https://files.pythonhosted.org/packages/a2/84/7756e75763e810b3a710f4724441d1ecc5883b94aacb07ca71c5fb5cfb69/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f", size = 2303975, upload-time = "2026-04-20T14:41:32.287Z" }, - { url = "https://files.pythonhosted.org/packages/6c/35/68a762e0c1e31f35fa0dac733cbd9f5b118042853698de9509c8e5bf128b/pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35", size = 2095325, upload-time = "2026-04-20T14:42:47.685Z" }, - { url = "https://files.pythonhosted.org/packages/77/bf/1bf8c9a8e91836c926eae5e3e51dce009bf495a60ca56060689d3df3f340/pydantic_core-2.46.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687", size = 2133368, upload-time = "2026-04-20T14:41:22.766Z" }, - { url = "https://files.pythonhosted.org/packages/e5/50/87d818d6bab915984995157ceb2380f5aac4e563dddbed6b56f0ed057aba/pydantic_core-2.46.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3", size = 2173908, upload-time = "2026-04-20T14:42:52.044Z" }, - { url = "https://files.pythonhosted.org/packages/91/88/a311fb306d0bd6185db41fa14ae888fb81d0baf648a761ae760d30819d33/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022", size = 2186422, upload-time = "2026-04-20T14:43:29.55Z" }, - { url = "https://files.pythonhosted.org/packages/8f/79/28fd0d81508525ab2054fef7c77a638c8b5b0afcbbaeee493cf7c3fef7e1/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23", size = 2332709, upload-time = "2026-04-20T14:42:16.134Z" }, - { url = "https://files.pythonhosted.org/packages/b3/21/795bf5fe5c0f379308b8ef19c50dedab2e7711dbc8d0c2acf08f1c7daa05/pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7", size = 2372428, upload-time = "2026-04-20T14:41:10.974Z" }, - { url = "https://files.pythonhosted.org/packages/45/b3/ed14c659cbe7605e3ef063077680a64680aec81eb1a04763a05190d49b7f/pydantic_core-2.46.3-cp313-cp313-win32.whl", hash = "sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13", size = 1965601, upload-time = "2026-04-20T14:41:42.128Z" }, - { url = "https://files.pythonhosted.org/packages/ef/bb/adb70d9a762ddd002d723fbf1bd492244d37da41e3af7b74ad212609027e/pydantic_core-2.46.3-cp313-cp313-win_amd64.whl", hash = "sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0", size = 2071517, upload-time = "2026-04-20T14:43:36.096Z" }, - { url = "https://files.pythonhosted.org/packages/52/eb/66faefabebfe68bd7788339c9c9127231e680b11906368c67ce112fdb47f/pydantic_core-2.46.3-cp313-cp313-win_arm64.whl", hash = "sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec", size = 2035802, upload-time = "2026-04-20T14:43:38.507Z" }, - { url = "https://files.pythonhosted.org/packages/7f/db/a7bcb4940183fda36022cd18ba8dd12f2dff40740ec7b58ce7457befa416/pydantic_core-2.46.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b", size = 2097614, upload-time = "2026-04-20T14:44:38.374Z" }, - { url = "https://files.pythonhosted.org/packages/24/35/e4066358a22e3e99519db370494c7528f5a2aa1367370e80e27e20283543/pydantic_core-2.46.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018", size = 1951896, upload-time = "2026-04-20T14:40:53.996Z" }, - { url = "https://files.pythonhosted.org/packages/87/92/37cf4049d1636996e4b888c05a501f40a43ff218983a551d57f9d5e14f0d/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34", size = 1979314, upload-time = "2026-04-20T14:41:49.446Z" }, - { url = "https://files.pythonhosted.org/packages/d8/36/9ff4d676dfbdfb2d591cf43f3d90ded01e15b1404fd101180ed2d62a2fd3/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7", size = 2056133, upload-time = "2026-04-20T14:42:23.574Z" }, - { url = "https://files.pythonhosted.org/packages/bc/f0/405b442a4d7ba855b06eec8b2bf9c617d43b8432d099dfdc7bf999293495/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2", size = 2228726, upload-time = "2026-04-20T14:44:22.816Z" }, - { url = "https://files.pythonhosted.org/packages/e7/f8/65cd92dd5a0bd89ba277a98ecbfaf6fc36bbd3300973c7a4b826d6ab1391/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba", size = 2301214, upload-time = "2026-04-20T14:44:48.792Z" }, - { url = "https://files.pythonhosted.org/packages/fd/86/ef96a4c6e79e7a2d0410826a68fbc0eccc0fd44aa733be199d5fcac3bb87/pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f", size = 2099927, upload-time = "2026-04-20T14:41:40.196Z" }, - { url = "https://files.pythonhosted.org/packages/6d/53/269caf30e0096e0a8a8f929d1982a27b3879872cca2d917d17c2f9fdf4fe/pydantic_core-2.46.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22", size = 2128789, upload-time = "2026-04-20T14:41:15.868Z" }, - { url = "https://files.pythonhosted.org/packages/00/b0/1a6d9b6a587e118482910c244a1c5acf4d192604174132efd12bf0ac486f/pydantic_core-2.46.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f", size = 2173815, upload-time = "2026-04-20T14:44:25.152Z" }, - { url = "https://files.pythonhosted.org/packages/87/56/e7e00d4041a7e62b5a40815590114db3b535bf3ca0bf4dca9f16cef25246/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127", size = 2181608, upload-time = "2026-04-20T14:41:28.933Z" }, - { url = "https://files.pythonhosted.org/packages/e8/22/4bd23c3d41f7c185d60808a1de83c76cf5aeabf792f6c636a55c3b1ec7f9/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c", size = 2326968, upload-time = "2026-04-20T14:42:03.962Z" }, - { url = "https://files.pythonhosted.org/packages/24/ac/66cd45129e3915e5ade3b292cb3bc7fd537f58f8f8dbdaba6170f7cabb74/pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1", size = 2369842, upload-time = "2026-04-20T14:41:35.52Z" }, - { url = "https://files.pythonhosted.org/packages/a2/51/dd4248abb84113615473aa20d5545b7c4cd73c8644003b5259686f93996c/pydantic_core-2.46.3-cp314-cp314-win32.whl", hash = "sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505", size = 1959661, upload-time = "2026-04-20T14:41:00.042Z" }, - { url = "https://files.pythonhosted.org/packages/20/eb/59980e5f1ae54a3b86372bd9f0fa373ea2d402e8cdcd3459334430f91e91/pydantic_core-2.46.3-cp314-cp314-win_amd64.whl", hash = "sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e", size = 2071686, upload-time = "2026-04-20T14:43:16.471Z" }, - { url = "https://files.pythonhosted.org/packages/8c/db/1cf77e5247047dfee34bc01fa9bca134854f528c8eb053e144298893d370/pydantic_core-2.46.3-cp314-cp314-win_arm64.whl", hash = "sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df", size = 2026907, upload-time = "2026-04-20T14:43:31.732Z" }, - { url = "https://files.pythonhosted.org/packages/57/c0/b3df9f6a543276eadba0a48487b082ca1f201745329d97dbfa287034a230/pydantic_core-2.46.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf", size = 2095047, upload-time = "2026-04-20T14:42:37.982Z" }, - { url = "https://files.pythonhosted.org/packages/66/57/886a938073b97556c168fd99e1a7305bb363cd30a6d2c76086bf0587b32a/pydantic_core-2.46.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee", size = 1934329, upload-time = "2026-04-20T14:43:49.655Z" }, - { url = "https://files.pythonhosted.org/packages/0b/7c/b42eaa5c34b13b07ecb51da21761297a9b8eb43044c864a035999998f328/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a", size = 1974847, upload-time = "2026-04-20T14:42:10.737Z" }, - { url = "https://files.pythonhosted.org/packages/e6/9b/92b42db6543e7de4f99ae977101a2967b63122d4b6cf7773812da2d7d5b5/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c", size = 2041742, upload-time = "2026-04-20T14:40:44.262Z" }, - { url = "https://files.pythonhosted.org/packages/0f/19/46fbe1efabb5aa2834b43b9454e70f9a83ad9c338c1291e48bdc4fecf167/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1", size = 2236235, upload-time = "2026-04-20T14:41:27.307Z" }, - { url = "https://files.pythonhosted.org/packages/77/da/b3f95bc009ad60ec53120f5d16c6faa8cabdbe8a20d83849a1f2b8728148/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64", size = 2282633, upload-time = "2026-04-20T14:44:33.271Z" }, - { url = "https://files.pythonhosted.org/packages/cc/6e/401336117722e28f32fb8220df676769d28ebdf08f2f4469646d404c43a3/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb", size = 2109679, upload-time = "2026-04-20T14:44:41.065Z" }, - { url = "https://files.pythonhosted.org/packages/fc/53/b289f9bc8756a32fe718c46f55afaeaf8d489ee18d1a1e7be1db73f42cc4/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6", size = 2108342, upload-time = "2026-04-20T14:42:50.144Z" }, - { url = "https://files.pythonhosted.org/packages/10/5b/8292fc7c1f9111f1b2b7c1b0dcf1179edcd014fc3ea4517499f50b829d71/pydantic_core-2.46.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c", size = 2157208, upload-time = "2026-04-20T14:42:08.133Z" }, - { url = "https://files.pythonhosted.org/packages/2b/9e/f80044e9ec07580f057a89fc131f78dda7a58751ddf52bbe05eaf31db50f/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47", size = 2167237, upload-time = "2026-04-20T14:42:25.412Z" }, - { url = "https://files.pythonhosted.org/packages/f8/84/6781a1b037f3b96be9227edbd1101f6d3946746056231bf4ac48cdff1a8d/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab", size = 2312540, upload-time = "2026-04-20T14:40:40.313Z" }, - { url = "https://files.pythonhosted.org/packages/3e/db/19c0839feeb728e7df03255581f198dfdf1c2aeb1e174a8420b63c5252e5/pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba", size = 2369556, upload-time = "2026-04-20T14:41:09.427Z" }, - { url = "https://files.pythonhosted.org/packages/e0/15/3228774cb7cd45f5f721ddf1b2242747f4eb834d0c491f0c02d606f09fed/pydantic_core-2.46.3-cp314-cp314t-win32.whl", hash = "sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56", size = 1949756, upload-time = "2026-04-20T14:41:25.717Z" }, - { url = "https://files.pythonhosted.org/packages/b8/2a/c79cf53fd91e5a87e30d481809f52f9a60dd221e39de66455cf04deaad37/pydantic_core-2.46.3-cp314-cp314t-win_amd64.whl", hash = "sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8", size = 2051305, upload-time = "2026-04-20T14:43:18.627Z" }, - { url = "https://files.pythonhosted.org/packages/0b/db/d8182a7f1d9343a032265aae186eb063fe26ca4c40f256b21e8da4498e89/pydantic_core-2.46.3-cp314-cp314t-win_arm64.whl", hash = "sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374", size = 2026310, upload-time = "2026-04-20T14:41:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/51/a2/5d30b469c5267a17b39dec53208222f76a8d351dfac4af661888c5aee77d/pydantic_core-2.46.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:5d5902252db0d3cedf8d4a1bc68f70eeb430f7e4c7104c8c476753519b423008", size = 2106306, upload-time = "2026-05-06T13:37:48.029Z" }, + { url = "https://files.pythonhosted.org/packages/c1/81/4fa520eaffa8bd7d1525e644cd6d39e7d60b1592bc5b516693c7340b50f1/pydantic_core-2.46.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c94f0688e7b8d0a67abf40e57a7eaaecd17cc9586706a31b76c031f63df052b4", size = 1951906, upload-time = "2026-05-06T13:37:17.012Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/5b/24/b375a480d53113860c299764bfe9f349a3dc9108b3adc0d7f0d786492ebf/pydantic_core-2.46.4-cp313-cp313-win32.whl", hash = "sha256:9fa8ae11da9e2b3126c6426f147e0fba88d96d65921799bb30c6abd1cb2c97fb", size = 1973693, upload-time = "2026-05-06T13:37:55.072Z" }, + { url = "https://files.pythonhosted.org/packages/7e/e8/cff247591966f2d22ec8c003cd7587e27b7ba7b81ab2fb888e3ab75dc285/pydantic_core-2.46.4-cp313-cp313-win_amd64.whl", hash = "sha256:6b3ace8194b0e5204818c92802dcdca7fc6d88aabbb799d7c795540d9cd6d292", size = 2071819, upload-time = "2026-05-06T13:38:49.139Z" }, + { url = "https://files.pythonhosted.org/packages/c6/1a/f4aee670d5670e9e148e0c82c7db98d780be566c6e6a97ee8035528ca0b3/pydantic_core-2.46.4-cp313-cp313-win_arm64.whl", hash = "sha256:184c081504d17f1c1066e430e117142b2c77d9448a97f7b65c6ac9fd9aee238d", size = 2027411, upload-time = "2026-05-06T13:40:45.796Z" }, + { url = "https://files.pythonhosted.org/packages/8d/74/228a26ddad29c6672b805d9fd78e8d251cd04004fa7eed0e622096cd0250/pydantic_core-2.46.4-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:428e04521a40150c85216fc8b85e8d39fece235a9cf5e383761238c7fa9b96fb", size = 2102079, upload-time = "2026-05-06T13:38:41.019Z" }, + { url = "https://files.pythonhosted.org/packages/ad/1f/8970b150a4b4365623ae00fc88603491f763c627311ae8031e3111356d6e/pydantic_core-2.46.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:23ace664830ee0bfe014a0c7bc248b1f7f25ed7ad103852c317624a1083af462", size = 1952179, upload-time = "2026-05-06T13:36:59.812Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/f2/20/d15df15ba918c423461905802bfd2981c3af0bfa0e40d05e13edbfa48bc3/pydantic_core-2.46.4-cp314-cp314-win32.whl", hash = "sha256:85bb3611ff1802f3ee7fdd7dbff26b56f343fb432d57a4728fdd49b6ef35e2f4", size = 1966354, upload-time = "2026-05-06T13:38:03.499Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b6/6b8de4c0a7d7ab3004c439c80c5c1e0a3e8d78bbae19379b01960383d9e5/pydantic_core-2.46.4-cp314-cp314-win_amd64.whl", hash = "sha256:811ff8e9c313ab425368bcbb36e5c4ebd7108c2bbf4e4089cfbb0b01eff63fac", size = 2072238, upload-time = "2026-05-06T13:39:40.807Z" }, + { url = "https://files.pythonhosted.org/packages/32/36/51eb763beec1f4cf59b1db243a7dcc39cbb41230f050a09b9d69faaf0a48/pydantic_core-2.46.4-cp314-cp314-win_arm64.whl", hash = "sha256:bfec22eab3c8cc2ceec0248aec886624116dc079afa027ecc8ad4a7e62010f8a", size = 2018251, upload-time = "2026-05-06T13:37:26.72Z" }, + { url = "https://files.pythonhosted.org/packages/e8/91/855af51d625b23aa987116a19e231d2aaef9c4a415273ddc189b79a45fee/pydantic_core-2.46.4-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:af8244b2bef6aaad6d92cda81372de7f8c8d36c9f0c3ea36e827c60e7d9467a0", size = 2099593, upload-time = "2026-05-06T13:39:47.682Z" }, + { url = "https://files.pythonhosted.org/packages/fb/1b/8784a54c65edb5f49f0a14d6977cf1b209bba85a4c77445b255c2de58ab3/pydantic_core-2.46.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5a4330cdbc57162e4b3aa303f588ba752257694c9c9be3e7ebb11b4aca659b5d", size = 1935226, upload-time = "2026-05-06T13:40:40.428Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/30/a6/9f9f380dbb301f67023bf8f707aaa75daadf84f7152d95c410fd7e81d994/pydantic_core-2.46.4-cp314-cp314t-win32.whl", hash = "sha256:e846ae7835bf0703ae43f534ab79a867146dadd59dc9ca5c8b53d5c8f7c9ef02", size = 1955575, upload-time = "2026-05-06T13:38:51.116Z" }, + { url = "https://files.pythonhosted.org/packages/40/1f/f1eb9eb350e795d1af8586289746f5c5677d16043040d63710e22abc43c9/pydantic_core-2.46.4-cp314-cp314t-win_amd64.whl", hash = "sha256:2108ba5c1c1eca18030634489dc544844144ee36357f2f9f780b93e7ddbb44b5", size = 2051624, upload-time = "2026-05-06T13:38:21.672Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d2/42dd53d0a85c27606f316d3aa5d2869c4e8470a5ed6dec30e4a1abe19192/pydantic_core-2.46.4-cp314-cp314t-win_arm64.whl", hash = "sha256:4fcbe087dbc2068af7eda3aa87634eba216dbda64d1ae73c8684b621d33f6596", size = 2017325, upload-time = "2026-05-06T13:40:52.723Z" }, ] [[package]] @@ -1004,7 +1011,7 @@ version = "2.20.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, ] [[package]] @@ -1012,15 +1019,15 @@ name = "pytest" version = "9.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "iniconfig" }, - { name = "packaging" }, - { name = "pluggy" }, - { name = "pygments" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7d/0d/549bd94f1a0a402dc8cf64563a117c0f3765662e2e668477624baeec44d5/pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c", size = 1572165, upload-time = "2026-04-07T17:16:18.027Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, + { url = "https://files.pythonhosted.org/packages/d4/24/a372aaf5c9b7208e7112038812994107bc65a84cd00e0354a88c2c77a617/pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9", size = 375249, upload-time = "2026-04-07T17:16:16.13Z" }, ] [[package]] @@ -1028,13 +1035,13 @@ name = "pytest-cov" version = "7.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "coverage" }, - { name = "pluggy" }, - { name = "pytest" }, + { name = "coverage" }, + { name = "pluggy" }, + { name = "pytest" }, ] sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592, upload-time = "2026-03-21T20:11:16.284Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, + { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, ] [[package]] @@ -1042,24 +1049,24 @@ name = "python-dateutil" version = "2.9.0.post0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "six" }, + { name = "six" }, ] sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] [[package]] name = "python-discovery" -version = "1.2.2" +version = "1.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "filelock" }, - { name = "platformdirs" }, + { name = "filelock" }, + { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/de/ef/3bae0e537cfe91e8431efcba4434463d2c5a65f5a89edd47c6cf2f03c55f/python_discovery-1.2.2.tar.gz", hash = "sha256:876e9c57139eb757cb5878cbdd9ae5379e5d96266c99ef731119e04fffe533bb", size = 58872, upload-time = "2026-04-07T17:28:49.249Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/12/38c1a0b1e64806780c9563e3fc9f6e472251839662587cfbe9bfaf2ae10a/python_discovery-1.4.0.tar.gz", hash = "sha256:eb8bc7daad3c226c147e45bb4e970a1feb1bf4048ee178e6db59e197b8010ce3", size = 68455, upload-time = "2026-05-28T01:15:37.639Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d8/db/795879cc3ddfe338599bddea6388cc5100b088db0a4caf6e6c1af1c27e04/python_discovery-1.2.2-py3-none-any.whl", hash = "sha256:e1ae95d9af875e78f15e19aed0c6137ab1bb49c200f21f5061786490c9585c7a", size = 31894, upload-time = "2026-04-07T17:28:48.09Z" }, + { url = "https://files.pythonhosted.org/packages/c8/8d/3d316429f65029532bb1e28ff77b797d86b5ac3915bb44ca4e19aa283d43/python_discovery-1.4.0-py3-none-any.whl", hash = "sha256:26ed78d703e234879a66244c7d4114563fb13ec5cd30a2d1357e5fb4850782da", size = 33217, upload-time = "2026-05-28T01:15:36.573Z" }, ] [[package]] @@ -1068,7 +1075,7 @@ version = "1.2.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, + { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, ] [[package]] @@ -1077,121 +1084,121 @@ version = "6.0.3" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, - { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, - { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, - { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, - { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, - { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, - { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, - { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, - { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, - { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, - { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, - { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, - { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, - { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] name = "regex" -version = "2026.4.4" +version = "2026.5.9" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cb/0e/3a246dbf05666918bd3664d9d787f84a9108f6f43cc953a077e4a7dfdb7e/regex-2026.4.4.tar.gz", hash = "sha256:e08270659717f6973523ce3afbafa53515c4dc5dcad637dc215b6fd50f689423", size = 416000, upload-time = "2026-04-03T20:56:28.155Z" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/0e/49aee608ad09480e7fd276898c99ec6192985fa331abe4eb3a986094490b/regex-2026.5.9.tar.gz", hash = "sha256:a8234aa23ec39894bfe4a3f1b85616a7032481964a13ac6fc9f10de4f6fca270", size = 416074, upload-time = "2026-05-09T23:15:19.37Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9d/83/c4373bc5f31f2cf4b66f9b7c31005bd87fe66f0dce17701f7db4ee79ee29/regex-2026.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:62f5519042c101762509b1d717b45a69c0139d60414b3c604b81328c01bd1943", size = 490273, upload-time = "2026-04-03T20:54:11.202Z" }, - { url = "https://files.pythonhosted.org/packages/46/f8/fe62afbcc3cf4ad4ac9adeaafd98aa747869ae12d3e8e2ac293d0593c435/regex-2026.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3790ba9fb5dd76715a7afe34dbe603ba03f8820764b1dc929dd08106214ed031", size = 291954, upload-time = "2026-04-03T20:54:13.412Z" }, - { url = "https://files.pythonhosted.org/packages/5a/92/4712b9fe6a33d232eeb1c189484b80c6c4b8422b90e766e1195d6e758207/regex-2026.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8fae3c6e795d7678963f2170152b0d892cf6aee9ee8afc8c45e6be38d5107fe7", size = 289487, upload-time = "2026-04-03T20:54:15.824Z" }, - { url = "https://files.pythonhosted.org/packages/88/2c/f83b93f85e01168f1070f045a42d4c937b69fdb8dd7ae82d307253f7e36e/regex-2026.4.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:298c3ec2d53225b3bf91142eb9691025bab610e0c0c51592dde149db679b3d17", size = 796646, upload-time = "2026-04-03T20:54:18.229Z" }, - { url = "https://files.pythonhosted.org/packages/df/55/61a2e17bf0c4dc57e11caf8dd11771280d8aaa361785f9e3bc40d653f4a7/regex-2026.4.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e9638791082eaf5b3ac112c587518ee78e083a11c4b28012d8fe2a0f536dfb17", size = 865904, upload-time = "2026-04-03T20:54:20.019Z" }, - { url = "https://files.pythonhosted.org/packages/45/32/1ac8ed1b5a346b5993a3d256abe0a0f03b0b73c8cc88d928537368ac65b6/regex-2026.4.4-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ae3e764bd4c5ff55035dc82a8d49acceb42a5298edf6eb2fc4d328ee5dd7afae", size = 912304, upload-time = "2026-04-03T20:54:22.403Z" }, - { url = "https://files.pythonhosted.org/packages/26/47/2ee5c613ab546f0eddebf9905d23e07beb933416b1246c2d8791d01979b4/regex-2026.4.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ffa81f81b80047ba89a3c69ae6a0f78d06f4a42ce5126b0eb2a0a10ad44e0b2e", size = 801126, upload-time = "2026-04-03T20:54:24.308Z" }, - { url = "https://files.pythonhosted.org/packages/75/cd/41dacd129ca9fd20bd7d02f83e0fad83e034ac8a084ec369c90f55ef37e2/regex-2026.4.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f56ebf9d70305307a707911b88469213630aba821e77de7d603f9d2f0730687d", size = 776772, upload-time = "2026-04-03T20:54:26.319Z" }, - { url = "https://files.pythonhosted.org/packages/89/6d/5af0b588174cb5f46041fa7dd64d3fd5cd2fe51f18766703d1edc387f324/regex-2026.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:773d1dfd652bbffb09336abf890bfd64785c7463716bf766d0eb3bc19c8b7f27", size = 785228, upload-time = "2026-04-03T20:54:28.387Z" }, - { url = "https://files.pythonhosted.org/packages/b7/3b/f5a72b7045bd59575fc33bf1345f156fcfd5a8484aea6ad84b12c5a82114/regex-2026.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d51d20befd5275d092cdffba57ded05f3c436317ee56466c8928ac32d960edaf", size = 860032, upload-time = "2026-04-03T20:54:30.641Z" }, - { url = "https://files.pythonhosted.org/packages/39/a4/72a317003d6fcd7a573584a85f59f525dfe8f67e355ca74eb6b53d66a5e2/regex-2026.4.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:0a51cdb3c1e9161154f976cb2bef9894bc063ac82f31b733087ffb8e880137d0", size = 765714, upload-time = "2026-04-03T20:54:32.789Z" }, - { url = "https://files.pythonhosted.org/packages/25/1e/5672e16f34dbbcb2560cc7e6a2fbb26dfa8b270711e730101da4423d3973/regex-2026.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ae5266a82596114e41fb5302140e9630204c1b5f325c770bec654b95dd54b0aa", size = 852078, upload-time = "2026-04-03T20:54:34.546Z" }, - { url = "https://files.pythonhosted.org/packages/f7/0d/c813f0af7c6cc7ed7b9558bac2e5120b60ad0fa48f813e4d4bd55446f214/regex-2026.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c882cd92ec68585e9c1cf36c447ec846c0d94edd706fe59e0c198e65822fd23b", size = 789181, upload-time = "2026-04-03T20:54:36.642Z" }, - { url = "https://files.pythonhosted.org/packages/ea/6d/a344608d1adbd2a95090ddd906cec09a11be0e6517e878d02a5123e0917f/regex-2026.4.4-cp313-cp313-win32.whl", hash = "sha256:05568c4fbf3cb4fa9e28e3af198c40d3237cf6041608a9022285fe567ec3ad62", size = 266690, upload-time = "2026-04-03T20:54:38.343Z" }, - { url = "https://files.pythonhosted.org/packages/31/07/54049f89b46235ca6f45cd6c88668a7050e77d4a15555e47dd40fde75263/regex-2026.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:3384df51ed52db0bea967e21458ab0a414f67cdddfd94401688274e55147bb81", size = 277733, upload-time = "2026-04-03T20:54:40.11Z" }, - { url = "https://files.pythonhosted.org/packages/0e/21/61366a8e20f4d43fb597708cac7f0e2baadb491ecc9549b4980b2be27d16/regex-2026.4.4-cp313-cp313-win_arm64.whl", hash = "sha256:acd38177bd2c8e69a411d6521760806042e244d0ef94e2dd03ecdaa8a3c99427", size = 270565, upload-time = "2026-04-03T20:54:41.883Z" }, - { url = "https://files.pythonhosted.org/packages/f1/1e/3a2b9672433bef02f5d39aa1143ca2c08f311c1d041c464a42be9ae648dc/regex-2026.4.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:f94a11a9d05afcfcfa640e096319720a19cc0c9f7768e1a61fceee6a3afc6c7c", size = 494126, upload-time = "2026-04-03T20:54:43.602Z" }, - { url = "https://files.pythonhosted.org/packages/4e/4b/c132a4f4fe18ad3340d89fcb56235132b69559136036b845be3c073142ed/regex-2026.4.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:36bcb9d6d1307ab629edc553775baada2aefa5c50ccc0215fbfd2afcfff43141", size = 293882, upload-time = "2026-04-03T20:54:45.41Z" }, - { url = "https://files.pythonhosted.org/packages/f4/5f/eaa38092ce7a023656280f2341dbbd4ad5f05d780a70abba7bb4f4bea54c/regex-2026.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:261c015b3e2ed0919157046d768774ecde57f03d8fa4ba78d29793447f70e717", size = 292334, upload-time = "2026-04-03T20:54:47.051Z" }, - { url = "https://files.pythonhosted.org/packages/5f/f6/dd38146af1392dac33db7074ab331cec23cced3759167735c42c5460a243/regex-2026.4.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c228cf65b4a54583763645dcd73819b3b381ca8b4bb1b349dee1c135f4112c07", size = 811691, upload-time = "2026-04-03T20:54:49.074Z" }, - { url = "https://files.pythonhosted.org/packages/7a/f0/dc54c2e69f5eeec50601054998ec3690d5344277e782bd717e49867c1d29/regex-2026.4.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:dd2630faeb6876fb0c287f664d93ddce4d50cd46c6e88e60378c05c9047e08ca", size = 871227, upload-time = "2026-04-03T20:54:51.035Z" }, - { url = "https://files.pythonhosted.org/packages/a1/af/cb16bd5dc61621e27df919a4449bbb7e5a1034c34d307e0a706e9cc0f3e3/regex-2026.4.4-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6a50ab11b7779b849472337191f3a043e27e17f71555f98d0092fa6d73364520", size = 917435, upload-time = "2026-04-03T20:54:52.994Z" }, - { url = "https://files.pythonhosted.org/packages/5c/71/8b260897f22996b666edd9402861668f45a2ca259f665ac029e6104a2d7d/regex-2026.4.4-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0734f63afe785138549fbe822a8cfeaccd1bae814c5057cc0ed5b9f2de4fc883", size = 816358, upload-time = "2026-04-03T20:54:54.884Z" }, - { url = "https://files.pythonhosted.org/packages/1c/60/775f7f72a510ef238254906c2f3d737fc80b16ca85f07d20e318d2eea894/regex-2026.4.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c4ee50606cb1967db7e523224e05f32089101945f859928e65657a2cbb3d278b", size = 785549, upload-time = "2026-04-03T20:54:57.01Z" }, - { url = "https://files.pythonhosted.org/packages/58/42/34d289b3627c03cf381e44da534a0021664188fa49ba41513da0b4ec6776/regex-2026.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6c1818f37be3ca02dcb76d63f2c7aaba4b0dc171b579796c6fbe00148dfec6b1", size = 801364, upload-time = "2026-04-03T20:54:58.981Z" }, - { url = "https://files.pythonhosted.org/packages/fc/20/f6ecf319b382a8f1ab529e898b222c3f30600fcede7834733c26279e7465/regex-2026.4.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:f5bfc2741d150d0be3e4a0401a5c22b06e60acb9aa4daa46d9e79a6dcd0f135b", size = 866221, upload-time = "2026-04-03T20:55:00.88Z" }, - { url = "https://files.pythonhosted.org/packages/92/6a/9f16d3609d549bd96d7a0b2aee1625d7512ba6a03efc01652149ef88e74d/regex-2026.4.4-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:504ffa8a03609a087cad81277a629b6ce884b51a24bd388a7980ad61748618ff", size = 772530, upload-time = "2026-04-03T20:55:03.213Z" }, - { url = "https://files.pythonhosted.org/packages/fa/f6/aa9768bc96a4c361ac96419fbaf2dcdc33970bb813df3ba9b09d5d7b6d96/regex-2026.4.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:70aadc6ff12e4b444586e57fc30771f86253f9f0045b29016b9605b4be5f7dfb", size = 856989, upload-time = "2026-04-03T20:55:05.087Z" }, - { url = "https://files.pythonhosted.org/packages/4d/b4/c671db3556be2473ae3e4bb7a297c518d281452871501221251ea4ecba57/regex-2026.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f4f83781191007b6ef43b03debc35435f10cad9b96e16d147efe84a1d48bdde4", size = 803241, upload-time = "2026-04-03T20:55:07.162Z" }, - { url = "https://files.pythonhosted.org/packages/2a/5c/83e3b1d89fa4f6e5a1bc97b4abd4a9a97b3c1ac7854164f694f5f0ba98a0/regex-2026.4.4-cp313-cp313t-win32.whl", hash = "sha256:e014a797de43d1847df957c0a2a8e861d1c17547ee08467d1db2c370b7568baa", size = 269921, upload-time = "2026-04-03T20:55:09.62Z" }, - { url = "https://files.pythonhosted.org/packages/28/07/077c387121f42cdb4d92b1301133c0d93b5709d096d1669ab847dda9fe2e/regex-2026.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:b15b88b0d52b179712632832c1d6e58e5774f93717849a41096880442da41ab0", size = 281240, upload-time = "2026-04-03T20:55:11.521Z" }, - { url = "https://files.pythonhosted.org/packages/9d/22/ead4a4abc7c59a4d882662aa292ca02c8b617f30b6e163bc1728879e9353/regex-2026.4.4-cp313-cp313t-win_arm64.whl", hash = "sha256:586b89cdadf7d67bf86ae3342a4dcd2b8d70a832d90c18a0ae955105caf34dbe", size = 272440, upload-time = "2026-04-03T20:55:13.365Z" }, - { url = "https://files.pythonhosted.org/packages/f0/f5/ed97c2dc47b5fbd4b73c0d7d75f9ebc8eca139f2bbef476bba35f28c0a77/regex-2026.4.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2da82d643fa698e5e5210e54af90181603d5853cf469f5eedf9bfc8f59b4b8c7", size = 490343, upload-time = "2026-04-03T20:55:15.241Z" }, - { url = "https://files.pythonhosted.org/packages/80/e9/de4828a7385ec166d673a5790ad06ac48cdaa98bc0960108dd4b9cc1aef7/regex-2026.4.4-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:54a1189ad9d9357760557c91103d5e421f0a2dabe68a5cdf9103d0dcf4e00752", size = 291909, upload-time = "2026-04-03T20:55:17.558Z" }, - { url = "https://files.pythonhosted.org/packages/b4/d6/5cfbfc97f3201a4d24b596a77957e092030dcc4205894bc035cedcfce62f/regex-2026.4.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:76d67d5afb1fe402d10a6403bae668d000441e2ab115191a804287d53b772951", size = 289692, upload-time = "2026-04-03T20:55:20.561Z" }, - { url = "https://files.pythonhosted.org/packages/8e/ac/f2212d9fd56fe897e36d0110ba30ba2d247bd6410c5bd98499c7e5a1e1f2/regex-2026.4.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e7cd3e4ee8d80447a83bbc9ab0c8459781fa77087f856c3e740d7763be0df27f", size = 796979, upload-time = "2026-04-03T20:55:22.56Z" }, - { url = "https://files.pythonhosted.org/packages/c9/e3/a016c12675fbac988a60c7e1c16e67823ff0bc016beb27bd7a001dbdabc6/regex-2026.4.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e19e18c568d2866d8b6a6dfad823db86193503f90823a8f66689315ba28fbe8", size = 866744, upload-time = "2026-04-03T20:55:24.646Z" }, - { url = "https://files.pythonhosted.org/packages/af/a4/0b90ca4cf17adc3cb43de80ec71018c37c88ad64987e8d0d481a95ca60b5/regex-2026.4.4-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7698a6f38730fd1385d390d1ed07bb13dce39aa616aca6a6d89bea178464b9a4", size = 911613, upload-time = "2026-04-03T20:55:27.033Z" }, - { url = "https://files.pythonhosted.org/packages/8e/3b/2b3dac0b82d41ab43aa87c6ecde63d71189d03fe8854b8ca455a315edac3/regex-2026.4.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:173a66f3651cdb761018078e2d9487f4cf971232c990035ec0eb1cdc6bf929a9", size = 800551, upload-time = "2026-04-03T20:55:29.532Z" }, - { url = "https://files.pythonhosted.org/packages/25/fe/5365eb7aa0e753c4b5957815c321519ecab033c279c60e1b1ae2367fa810/regex-2026.4.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fa7922bbb2cc84fa062d37723f199d4c0cd200245ce269c05db82d904db66b83", size = 776911, upload-time = "2026-04-03T20:55:31.526Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b3/7fb0072156bba065e3b778a7bc7b0a6328212be5dd6a86fd207e0c4f2dab/regex-2026.4.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:59f67cd0a0acaf0e564c20bbd7f767286f23e91e2572c5703bf3e56ea7557edb", size = 785751, upload-time = "2026-04-03T20:55:33.797Z" }, - { url = "https://files.pythonhosted.org/packages/02/1a/9f83677eb699273e56e858f7bd95acdbee376d42f59e8bfca2fd80d79df3/regex-2026.4.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:475e50f3f73f73614f7cba5524d6de49dee269df00272a1b85e3d19f6d498465", size = 860484, upload-time = "2026-04-03T20:55:35.745Z" }, - { url = "https://files.pythonhosted.org/packages/3b/7a/93937507b61cfcff8b4c5857f1b452852b09f741daa9acae15c971d8554e/regex-2026.4.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:a1c0c7d67b64d85ac2e1879923bad2f08a08f3004055f2f406ef73c850114bd4", size = 765939, upload-time = "2026-04-03T20:55:37.972Z" }, - { url = "https://files.pythonhosted.org/packages/86/ea/81a7f968a351c6552b1670ead861e2a385be730ee28402233020c67f9e0f/regex-2026.4.4-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:1371c2ccbb744d66ee63631cc9ca12aa233d5749972626b68fe1a649dd98e566", size = 851417, upload-time = "2026-04-03T20:55:39.92Z" }, - { url = "https://files.pythonhosted.org/packages/4c/7e/323c18ce4b5b8f44517a36342961a0306e931e499febbd876bb149d900f0/regex-2026.4.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:59968142787042db793348a3f5b918cf24ced1f23247328530e063f89c128a95", size = 789056, upload-time = "2026-04-03T20:55:42.303Z" }, - { url = "https://files.pythonhosted.org/packages/c0/af/e7510f9b11b1913b0cd44eddb784b2d650b2af6515bfce4cffcc5bfd1d38/regex-2026.4.4-cp314-cp314-win32.whl", hash = "sha256:59efe72d37fd5a91e373e5146f187f921f365f4abc1249a5ab446a60f30dd5f8", size = 272130, upload-time = "2026-04-03T20:55:44.995Z" }, - { url = "https://files.pythonhosted.org/packages/9a/51/57dae534c915e2d3a21490e88836fa2ae79dde3b66255ecc0c0a155d2c10/regex-2026.4.4-cp314-cp314-win_amd64.whl", hash = "sha256:e0aab3ff447845049d676827d2ff714aab4f73f340e155b7de7458cf53baa5a4", size = 280992, upload-time = "2026-04-03T20:55:47.316Z" }, - { url = "https://files.pythonhosted.org/packages/0a/5e/abaf9f4c3792e34edb1434f06717fae2b07888d85cb5cec29f9204931bf8/regex-2026.4.4-cp314-cp314-win_arm64.whl", hash = "sha256:a7a5bb6aa0cf62208bb4fa079b0c756734f8ad0e333b425732e8609bd51ee22f", size = 273563, upload-time = "2026-04-03T20:55:49.273Z" }, - { url = "https://files.pythonhosted.org/packages/ff/06/35da85f9f217b9538b99cbb170738993bcc3b23784322decb77619f11502/regex-2026.4.4-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:97850d0638391bdc7d35dc1c1039974dcb921eaafa8cc935ae4d7f272b1d60b3", size = 494191, upload-time = "2026-04-03T20:55:51.258Z" }, - { url = "https://files.pythonhosted.org/packages/54/5b/1bc35f479eef8285c4baf88d8c002023efdeebb7b44a8735b36195486ae7/regex-2026.4.4-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:ee7337f88f2a580679f7bbfe69dc86c043954f9f9c541012f49abc554a962f2e", size = 293877, upload-time = "2026-04-03T20:55:53.214Z" }, - { url = "https://files.pythonhosted.org/packages/39/5b/f53b9ad17480b3ddd14c90da04bfb55ac6894b129e5dea87bcaf7d00e336/regex-2026.4.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7429f4e6192c11d659900c0648ba8776243bf396ab95558b8c51a345afeddde6", size = 292410, upload-time = "2026-04-03T20:55:55.736Z" }, - { url = "https://files.pythonhosted.org/packages/bb/56/52377f59f60a7c51aa4161eecf0b6032c20b461805aca051250da435ffc9/regex-2026.4.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc4f10fbd5dd13dcf4265b4cc07d69ca70280742870c97ae10093e3d66000359", size = 811831, upload-time = "2026-04-03T20:55:57.802Z" }, - { url = "https://files.pythonhosted.org/packages/dd/63/8026310bf066f702a9c361f83a8c9658f3fe4edb349f9c1e5d5273b7c40c/regex-2026.4.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a152560af4f9742b96f3827090f866eeec5becd4765c8e0d3473d9d280e76a5a", size = 871199, upload-time = "2026-04-03T20:56:00.333Z" }, - { url = "https://files.pythonhosted.org/packages/20/9f/a514bbb00a466dbb506d43f187a04047f7be1505f10a9a15615ead5080ee/regex-2026.4.4-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54170b3e95339f415d54651f97df3bff7434a663912f9358237941bbf9143f55", size = 917649, upload-time = "2026-04-03T20:56:02.445Z" }, - { url = "https://files.pythonhosted.org/packages/cb/6b/8399f68dd41a2030218839b9b18360d79b86d22b9fab5ef477c7f23ca67c/regex-2026.4.4-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:07f190d65f5a72dcb9cf7106bfc3d21e7a49dd2879eda2207b683f32165e4d99", size = 816388, upload-time = "2026-04-03T20:56:04.595Z" }, - { url = "https://files.pythonhosted.org/packages/1e/9c/103963f47c24339a483b05edd568594c2be486188f688c0170fd504b2948/regex-2026.4.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9a2741ce5a29d3c84b0b94261ba630ab459a1b847a0d6beca7d62d188175c790", size = 785746, upload-time = "2026-04-03T20:56:07.13Z" }, - { url = "https://files.pythonhosted.org/packages/fa/ee/7f6054c0dec0cee3463c304405e4ff42e27cff05bf36fcb34be549ab17bd/regex-2026.4.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:b26c30df3a28fd9793113dac7385a4deb7294a06c0f760dd2b008bd49a9139bc", size = 801483, upload-time = "2026-04-03T20:56:09.365Z" }, - { url = "https://files.pythonhosted.org/packages/30/c2/51d3d941cf6070dc00c3338ecf138615fc3cce0421c3df6abe97a08af61a/regex-2026.4.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:421439d1bee44b19f4583ccf42670ca464ffb90e9fdc38d37f39d1ddd1e44f1f", size = 866331, upload-time = "2026-04-03T20:56:12.039Z" }, - { url = "https://files.pythonhosted.org/packages/16/e8/76d50dcc122ac33927d939f350eebcfe3dbcbda96913e03433fc36de5e63/regex-2026.4.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:b40379b53ecbc747fd9bdf4a0ea14eb8188ca1bd0f54f78893a39024b28f4863", size = 772673, upload-time = "2026-04-03T20:56:14.558Z" }, - { url = "https://files.pythonhosted.org/packages/a5/6e/5f6bf75e20ea6873d05ba4ec78378c375cbe08cdec571c83fbb01606e563/regex-2026.4.4-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:08c55c13d2eef54f73eeadc33146fb0baaa49e7335eb1aff6ae1324bf0ddbe4a", size = 857146, upload-time = "2026-04-03T20:56:16.663Z" }, - { url = "https://files.pythonhosted.org/packages/0b/33/3c76d9962949e487ebba353a18e89399f292287204ac8f2f4cfc3a51c233/regex-2026.4.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9776b85f510062f5a75ef112afe5f494ef1635607bf1cc220c1391e9ac2f5e81", size = 803463, upload-time = "2026-04-03T20:56:18.923Z" }, - { url = "https://files.pythonhosted.org/packages/19/eb/ef32dcd2cb69b69bc0c3e55205bce94a7def48d495358946bc42186dcccc/regex-2026.4.4-cp314-cp314t-win32.whl", hash = "sha256:385edaebde5db5be103577afc8699fea73a0e36a734ba24870be7ffa61119d74", size = 275709, upload-time = "2026-04-03T20:56:20.996Z" }, - { url = "https://files.pythonhosted.org/packages/a0/86/c291bf740945acbf35ed7dbebf8e2eea2f3f78041f6bd7cdab80cb274dc0/regex-2026.4.4-cp314-cp314t-win_amd64.whl", hash = "sha256:5d354b18839328927832e2fa5f7c95b7a3ccc39e7a681529e1685898e6436d45", size = 285622, upload-time = "2026-04-03T20:56:23.641Z" }, - { url = "https://files.pythonhosted.org/packages/d5/e7/ec846d560ae6a597115153c02ca6138a7877a1748b2072d9521c10a93e58/regex-2026.4.4-cp314-cp314t-win_arm64.whl", hash = "sha256:af0384cb01a33600c49505c27c6c57ab0b27bf84a74e28524c92ca897ebdac9d", size = 275773, upload-time = "2026-04-03T20:56:26.07Z" }, + { url = "https://files.pythonhosted.org/packages/aa/da/797e91ecec6f84135da778ddce78c20e0af5d2a15c26f87a81bc3eadb6db/regex-2026.5.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d626b84406444b165fc0ba981604edea39f0588ff1f92baa23fe50799ea9afdb", size = 490303, upload-time = "2026-05-09T23:13:04.382Z" }, + { url = "https://files.pythonhosted.org/packages/44/da/bf30abaaa737b58f4a4b8c4a03659e02fd92092c822e0197ed9e0daab917/regex-2026.5.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d7bdc0ab8f3dd7e1b4f9ab88634e13374669db86bb3c72e8292f07ae313f539f", size = 292019, upload-time = "2026-05-09T23:13:06.022Z" }, + { url = "https://files.pythonhosted.org/packages/2d/e7/d0eaf5713828417b9e5648cf81fa9bacd4961f6ab98c380c2034f8716e35/regex-2026.5.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a8820737949116ffff55fe18f9fc644530063ba6ebfcb8314239416e78f1347c", size = 289468, upload-time = "2026-05-09T23:13:08.214Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9b/b3fdd62b003baa1a9b593cd8c8699c9651c2e80cc21a5c715707983c42d7/regex-2026.5.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0fbdbac82cb3e4450d0ccde7d7a35607f4cb2dd9fba4b8b69bfaf8c9fa6aed", size = 796749, upload-time = "2026-05-09T23:13:10.573Z" }, + { url = "https://files.pythonhosted.org/packages/d4/30/66ab84588765f5b4b271a9ca09ef7ce2b87caa95176ec3d2ad65d7bc4902/regex-2026.5.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:57e8915c7986aa33d25e4d3629cef711cd2863f2961b10409f0c04cb8b7d9020", size = 865445, upload-time = "2026-05-09T23:13:12.523Z" }, + { url = "https://files.pythonhosted.org/packages/1a/89/f05169e8588aac365f35ffc7f3bc3184f095ef4cfded7cfaa3c7fd5dbd89/regex-2026.5.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:508f56a89ba9cb26e4168cbc37dbd60a28d82430a9e18ad1d25fe0883c314ca2", size = 912322, upload-time = "2026-05-09T23:13:14.281Z" }, + { url = "https://files.pythonhosted.org/packages/30/e1/c93444052cf41581f3c884ab3fb5823daf0992f11cd4388d4275ca610558/regex-2026.5.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b6d189041f15691cfa2b6c4290448ec221244d225b3f5fe9e7771b34ffcdf6e2", size = 801269, upload-time = "2026-05-09T23:13:16.569Z" }, + { url = "https://files.pythonhosted.org/packages/50/fe/0cf96b882f540e62e8b9956599798203d599c44cf4c77917ca27400ff69b/regex-2026.5.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e82db382b44d0111b22601c509c89f64434816c9e0eef9d1989cda8cc6ff1c04", size = 777085, upload-time = "2026-05-09T23:13:18.675Z" }, + { url = "https://files.pythonhosted.org/packages/23/5c/d78d4924e7fc875557b9e9b768423925fdfaac5549d06da7810019a9bd26/regex-2026.5.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2acfb48634f64996b57f90f39afa692ff362162722581921fe92239a59960f3c", size = 785153, upload-time = "2026-05-09T23:13:20.525Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e0/5214774090e7b4524dcea3e3c4aa74141d43043f8beb49c1599db1c8b53a/regex-2026.5.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d29eebfc9525db68cad3c97eedd7f754fa265aa5cd0cf4f863b2421e1b48fc9f", size = 860164, upload-time = "2026-05-09T23:13:22.263Z" }, + { url = "https://files.pythonhosted.org/packages/6e/e1/4a57a83350319b1271f0d7a249b8672513ed928b237a741631270de6caea/regex-2026.5.9-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:debb893095e944091c16e641a6e33c1b0f4cb61ab945ec5afbf53ce7068834d8", size = 765731, upload-time = "2026-05-09T23:13:24.277Z" }, + { url = "https://files.pythonhosted.org/packages/12/f4/499e74a20c156fc75836ee04a72a38d1a063978f600937f9760467beb1b0/regex-2026.5.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d659eee77986549c9ea45b861c7567e44d6287c3dc9a4565478853f7b9fe2ff6", size = 852062, upload-time = "2026-05-09T23:13:26.125Z" }, + { url = "https://files.pythonhosted.org/packages/5b/92/7eebc0d0a01e78629695f342ba17e0deaff8fb45e79cc0d7b98287da6e3e/regex-2026.5.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2efa205e6d98b24d1f3ab395c11aa15cdf10935bca283d0285e0499c284fba21", size = 789577, upload-time = "2026-05-09T23:13:27.814Z" }, + { url = "https://files.pythonhosted.org/packages/05/a4/018e71f7d2ad48c1ebe6d3ae0026f9b7cb4802fd15c7cc02fdf724355102/regex-2026.5.9-cp313-cp313-win32.whl", hash = "sha256:f3844f134e834076677dd369976e9f5068679fcb8e50102fdf6b7ac96a3ec127", size = 266691, upload-time = "2026-05-09T23:13:29.549Z" }, + { url = "https://files.pythonhosted.org/packages/e6/1d/861a93719fb9ee7dbfc3761b3797b7a3e112a5d42c6129459d2d741be9b5/regex-2026.5.9-cp313-cp313-win_amd64.whl", hash = "sha256:3527bb4942d2c14552155406cdedd906567456821848aed1cb4933a391bf5eca", size = 277747, upload-time = "2026-05-09T23:13:31.859Z" }, + { url = "https://files.pythonhosted.org/packages/d9/c6/0a2436ae4da1ba76e51cb98943c6838a9a721faa40ebe2dce07694ae34e3/regex-2026.5.9-cp313-cp313-win_arm64.whl", hash = "sha256:56a33f191f17d8c417f99945ebdc1e691d3af9605d86ec68c7e54a57e3e17af6", size = 270500, upload-time = "2026-05-09T23:13:33.525Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e9/d21346f7b60ed58789371358ed66b09d00f832e1bd7c06e55d9da5679882/regex-2026.5.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:01f28d868834624c934b8d2e0aa1c8341337e37831f4a012f18a5afcba4cbaf3", size = 494172, upload-time = "2026-05-09T23:13:35.935Z" }, + { url = "https://files.pythonhosted.org/packages/c4/43/fd1177a2032037c681baecdb3422ee4e1424aec4e4f470ef47793d325274/regex-2026.5.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:48036f6374aaa79eb3b754ec29c61d1c6b1606749d705a13f8854fa2539671f6", size = 293952, upload-time = "2026-05-09T23:13:38.307Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7d/9fbf919768368d3f8a4f6c692cf2aa61e482b2b81ec6a298ace4cbf02480/regex-2026.5.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b96350aa424e79d4fd6b567b344dcbe2b2d6bfc48dfe7717587e1fa6d43da6ff", size = 292314, upload-time = "2026-05-09T23:13:40.353Z" }, + { url = "https://files.pythonhosted.org/packages/e2/6c/e41bfeecb589716843e7c4df09ba46ff2a42961457afece19059d85caeef/regex-2026.5.9-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8f3af7a4903c5c04a11a196a5aa75cdd7dd3f8508132f9fb3259d9f5908e3b88", size = 811681, upload-time = "2026-05-09T23:13:42.543Z" }, + { url = "https://files.pythonhosted.org/packages/87/83/a5c1c525fba0aa656e88ad0face0b1829788ef4c2fb6b26df58aa1151b84/regex-2026.5.9-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e87577720152d2caae19fe2baaf1f8d5ca12091e9e229f03915c37d1e4b9178", size = 871135, upload-time = "2026-05-09T23:13:44.326Z" }, + { url = "https://files.pythonhosted.org/packages/18/d4/80882e799e440dd878b0979cbebf8fa4d54624a332c83037c7a701649e3f/regex-2026.5.9-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c8b9b9d294cfea3cd19c718ade7cc93492b2c4991abd9a68d0b3477ae6d8e100", size = 917265, upload-time = "2026-05-09T23:13:47.295Z" }, + { url = "https://files.pythonhosted.org/packages/ae/ff/8db60211e2286e396aad7dc7725356c502bff0901ea05bd6cdc2e1a042b9/regex-2026.5.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:728d8bfd28a8845c8b6bc5dc7ce010453d206396786c0765c2740cb65f37791e", size = 816311, upload-time = "2026-05-09T23:13:49.885Z" }, + { url = "https://files.pythonhosted.org/packages/4c/47/742ef579c61730f8d268e5cf1f9ce0e37e2ea041ad0f5644724f2378e463/regex-2026.5.9-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7e30b874d341fac767d7df5a0870540541c2c054b80cfaac116e8d367a8a7ff2", size = 785498, upload-time = "2026-05-09T23:13:52.25Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ab/cb0999802dcb0fb95b1ab005e8d4163d8afdd67efc2cb6b6630ac13f8cb1/regex-2026.5.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:fd190e88a895a8901325fad284a3f74ea52b1da8525b76cc811fa9b1edf0ce2b", size = 801348, upload-time = "2026-05-09T23:13:54.127Z" }, + { url = "https://files.pythonhosted.org/packages/7d/62/8ca59a24c55bc34d166eefaf3717bd77772f329fdbf984d86581e0a3571c/regex-2026.5.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:8e76e8161ad00694cfce6767d5dea860c6391ac5b83e5c3a39661e696f11fc7e", size = 866493, upload-time = "2026-05-09T23:13:56.067Z" }, + { url = "https://files.pythonhosted.org/packages/8d/3d/30f2ae62cef3278bb5bb821f467277a55fb73f01032cf85997e15e8289a8/regex-2026.5.9-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ddda5340e6c01a293027dd46232fa79eaff1b48058ce7a98f572b6445b088041", size = 772811, upload-time = "2026-05-09T23:13:57.867Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ae/7d2089bcd78ad0c0161bc684339df50032acb438a7bd3305e7ddb1193cec/regex-2026.5.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:205109e96b3cf5adf8f4cd62bedde9487feb282b9497a3535451e5a24cd706a0", size = 856584, upload-time = "2026-05-09T23:13:59.679Z" }, + { url = "https://files.pythonhosted.org/packages/a9/29/92ff47f75990131ea4f24ba17819e5a9d141e10819807e09addd73409af6/regex-2026.5.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dfbe4579b9f08036aa7d101d1835437a20783574ac66327e6b29b4018a138081", size = 803453, upload-time = "2026-05-09T23:14:01.978Z" }, + { url = "https://files.pythonhosted.org/packages/04/99/eff29f1037dcab36702c9ee5d6858cf1ce2336ea8ea2987f64245b99ea5e/regex-2026.5.9-cp313-cp313t-win32.whl", hash = "sha256:ed2c9e8068b614c574d8d30e543d617cf5379b0535d46f97ef00e904745a08b5", size = 269951, upload-time = "2026-05-09T23:14:03.661Z" }, + { url = "https://files.pythonhosted.org/packages/0e/9d/8870b8981d27b22cda77bb26a5ac7ebfa9c7d9e0dea195a834a82380e748/regex-2026.5.9-cp313-cp313t-win_amd64.whl", hash = "sha256:b46b0f094dc1d3b90356c85a0bd2c9bafc4a6a190b9d6f8ddd5a033b6e088ed4", size = 281240, upload-time = "2026-05-09T23:14:05.56Z" }, + { url = "https://files.pythonhosted.org/packages/72/b1/3379415e8f135c13ac551353397cc4fe97b4978f3cac73c5fcbcded548b8/regex-2026.5.9-cp313-cp313t-win_arm64.whl", hash = "sha256:872acc074bd29ffc9913ecdfedf6ea77502312ca44a4aa0d3779089c6069d8de", size = 272383, upload-time = "2026-05-09T23:14:07.843Z" }, + { url = "https://files.pythonhosted.org/packages/13/3e/9c3cd292d8808b3645a2ce517e200179b6d0e903f176300bd8b542e14de5/regex-2026.5.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:1bd7587a2948b4085195d5a3374eaf4a425dc3e55784c038175355ecf3bbbf8a", size = 490376, upload-time = "2026-05-09T23:14:09.64Z" }, + { url = "https://files.pythonhosted.org/packages/60/70/d43ee8a2ca0a8b68d167f21658b85520ac0574617c7f320367c5047f7556/regex-2026.5.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:dea2e88e1cce4522496cce630e11e67b98b7076620bc4336c3f674bc21a375f4", size = 291964, upload-time = "2026-05-09T23:14:11.424Z" }, + { url = "https://files.pythonhosted.org/packages/21/91/9d50b433828d8e74196904e168a43abf1e6e88b2a15d47ed742456720c37/regex-2026.5.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2099f7e7ff7b6aa3192312650a56e91cc091e49d50b04e4f6f8b6e28b3b27f1c", size = 289682, upload-time = "2026-05-09T23:14:13.123Z" }, + { url = "https://files.pythonhosted.org/packages/3e/d2/b835e3cafbb9d977736912436259ff551d60919f7d7b3d37d46659c63564/regex-2026.5.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecd353045824e4477562a2ac718c25799cdaaa41f7aa925a806a8a3e6848a5b9", size = 796996, upload-time = "2026-05-09T23:14:14.923Z" }, + { url = "https://files.pythonhosted.org/packages/2c/a6/9f992d00019166b9de01c546dd4549bc679f2a68df11b877740b0760b7c2/regex-2026.5.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:65c8c8c37377794bd5b2f3ebe51919042bf17aec802e23c833d89782ed0c78af", size = 866089, upload-time = "2026-05-09T23:14:17.757Z" }, + { url = "https://files.pythonhosted.org/packages/e0/08/4d32af657e049b19cb62b02e46e38fe1518797bfb2203ee93a510b21b0dc/regex-2026.5.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5b73ab8afcf66c622db143d1c6fda4e58e4d537ee4f125229ad47b1ab80f34c0", size = 911530, upload-time = "2026-05-09T23:14:20.353Z" }, + { url = "https://files.pythonhosted.org/packages/d9/27/2af43dd1dc201d1fecefda64a45f4ad0995855b92724f795a777b402ee69/regex-2026.5.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0de5cf193997384ed2ca6f1cd4f78055b255d93d82d5a8cd6ba0d11c10b167e4", size = 800643, upload-time = "2026-05-09T23:14:22.265Z" }, + { url = "https://files.pythonhosted.org/packages/a4/dd/23a249047013b5321d4a60c4d2437462086f601b061776a525e5fba2a59f/regex-2026.5.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d641a8c9a61618047796d572a39a79b26167b0411d2c3031937b2fe2d081e2cf", size = 777223, upload-time = "2026-05-09T23:14:24.179Z" }, + { url = "https://files.pythonhosted.org/packages/94/6a/e85ed9538cd19586d0465076a4578a12e093ce776d15f3f8ce92733a8dd6/regex-2026.5.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:24b2355ef5cc9aa5b8f07d17704face1c166fdcc2290fa7bd6e6c925655a8346", size = 785760, upload-time = "2026-05-09T23:14:26.065Z" }, + { url = "https://files.pythonhosted.org/packages/2a/c4/f25473209438638e947c55f9156fd8f236f74169229028cc99116380868e/regex-2026.5.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:a24852d3c29ad9e47593593d8a247c44ccc3d0548ef12c822d6ed0810affe676", size = 860891, upload-time = "2026-05-09T23:14:28.17Z" }, + { url = "https://files.pythonhosted.org/packages/f9/f7/f4f86e3c74419c37370e91f150ae0c2ef7d34b2e0e4cdd5da046a02e4022/regex-2026.5.9-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:916714069da19329ef7de197dcbc77bb3104145c7c2c864dbfbe318f46b88b14", size = 765891, upload-time = "2026-05-09T23:14:30.06Z" }, + { url = "https://files.pythonhosted.org/packages/26/70/704d8e13765939146b1cd0ef4e2feb71d7929727d2290f026eed10095955/regex-2026.5.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:fa411799ca8da32a8d38d020a88faa5b6f91657d284761352940ecf9f7c3bbdd", size = 851380, upload-time = "2026-05-09T23:14:32.123Z" }, + { url = "https://files.pythonhosted.org/packages/26/29/1a13582a8460038edc38e49f64ceb0dd7c60f5caba77571f4bf6601965d9/regex-2026.5.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:1e6da47d679b7010ef27556b6e0f99771b744936db1792a10ceac6547ae1503e", size = 789350, upload-time = "2026-05-09T23:14:34.799Z" }, + { url = "https://files.pythonhosted.org/packages/73/56/3dcafe34fc72e271d62ad9a291801e88a1457bb251c132f15fcc2e5aad1a/regex-2026.5.9-cp314-cp314-win32.whl", hash = "sha256:98bd73080e8756255137e1bd3f3f00295bbc5aa383c0e0f973920e9134d7c4ad", size = 272130, upload-time = "2026-05-09T23:14:36.729Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9c/02eebf0be95efe416c664db7fb8b6b05b7a0b06a7544f2884f2558b0526f/regex-2026.5.9-cp314-cp314-win_amd64.whl", hash = "sha256:ff8d372ac2acdc048d1c19916f27ee61bc5722728458ba6ca5052f2c72d51763", size = 280999, upload-time = "2026-05-09T23:14:39.126Z" }, + { url = "https://files.pythonhosted.org/packages/70/5a/1dd1abee76cb7a846a0bcf42fdc87e5720c3c33c24f3e37814310a513d9f/regex-2026.5.9-cp314-cp314-win_arm64.whl", hash = "sha256:e1d93bf647916292e8edcec150c07ddf3dc50179ccaf770c04a7f9e452155372", size = 273500, upload-time = "2026-05-09T23:14:41.059Z" }, + { url = "https://files.pythonhosted.org/packages/86/c1/c5f619b0057a7965cb78ec559c1d7a45ce8c99a35bea95483d64959a93d9/regex-2026.5.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:83d0ee4a57d1c87cb549e195ec300b8f0ec3a82eba66d835e4e2ed8634fe4499", size = 494269, upload-time = "2026-05-09T23:14:42.869Z" }, + { url = "https://files.pythonhosted.org/packages/05/2c/5d01f1aee33de4bbe60c8452945bfc8477ca7c5ae4450f6bfe711036cb36/regex-2026.5.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d3d7eb5c9a7f6df82ed3cfac9beb93882a5cbcb5b8b157b56cb2b3b276574ac1", size = 293954, upload-time = "2026-05-09T23:14:44.822Z" }, + { url = "https://files.pythonhosted.org/packages/7a/fe/e8988b2ae2108c6ef71bd4aa8d87fbe257976dd0810e826cd75f701c68b6/regex-2026.5.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:075160bf16658e16d35233300b8453aac25de4cbea808d22348b6979668e924d", size = 292405, upload-time = "2026-05-09T23:14:47.211Z" }, + { url = "https://files.pythonhosted.org/packages/79/34/d2b0937faa7859263f7f0a3c6b103a1296306be6952dc173d0154e9a2f49/regex-2026.5.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:45375819235558a4ff1c4971dc32881f022613abdb180128f5cb4768c1765a1c", size = 811855, upload-time = "2026-05-09T23:14:49.21Z" }, + { url = "https://files.pythonhosted.org/packages/80/fe/daf53a47457a8486db66c66c01ceb9c2303eecee3f87197f1e77eb1a736d/regex-2026.5.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ead4b163ac30a29574510cd4b3e2e985ac5290c05fc7095557d6a5f403fc31b5", size = 871189, upload-time = "2026-05-09T23:14:51.555Z" }, + { url = "https://files.pythonhosted.org/packages/1c/75/058fc4470cbfbf57d800aff1a0022b929a3f9fa553ee10a0cdf2070eb31f/regex-2026.5.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8c6e4218fbdfbcd4f6c19efca40930d24a621bf4b48cb76bc6640543bd28ef20", size = 917485, upload-time = "2026-05-09T23:14:53.633Z" }, + { url = "https://files.pythonhosted.org/packages/88/e7/179cfda3a28bc843b5c6cfe7f79f23489c791ed95f151083803660878432/regex-2026.5.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6351571c8a42b505eb555c0dc47d740d0fb66977dc142919eea6f4325b7c56a0", size = 816369, upload-time = "2026-05-09T23:14:56.198Z" }, + { url = "https://files.pythonhosted.org/packages/41/90/6f0cc422071688266d344fca8462d787cba0a2c144acb25721f9a61ec265/regex-2026.5.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:002205cafd2a9e78c6290c7d1df277bf3277b3b7a30e0b4bb0dac2e2e3f7cb2d", size = 785869, upload-time = "2026-05-09T23:14:58.602Z" }, + { url = "https://files.pythonhosted.org/packages/02/67/a31f1760f09c27b251ef39e9beb541f462cf977381d067faa764c2c0e393/regex-2026.5.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8abd33fef90b2a9efac5557d6033ca82d1195ed3a15fea5af15ba7b463c6a63b", size = 801427, upload-time = "2026-05-09T23:15:00.642Z" }, + { url = "https://files.pythonhosted.org/packages/e3/c4/1a80654597b6bc1e1ea0494824c31200e8a956abe290afae9b19a166a148/regex-2026.5.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:31037c82eccb44b7ea2e9e221d7c01429430e989a1f4b91ea5a855f6017b509a", size = 866482, upload-time = "2026-05-09T23:15:03.384Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/960724e06482c08466ff5611e242e86f80062949cdf6b4b9cc317b9dd93d/regex-2026.5.9-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5604dfd046dc37eca90250fc3be938b076c8059fa772ac0ed6f499b0f0fb0415", size = 773022, upload-time = "2026-05-09T23:15:05.625Z" }, + { url = "https://files.pythonhosted.org/packages/50/a8/a9979c3e7918280e93159ebcab5ef1a65116dd4f3bd6091be0eae4a126e8/regex-2026.5.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e1b1b4e496afbb24f4a62aba855ee4f88f25578927697b340702e48c9ee6bc2", size = 856642, upload-time = "2026-05-09T23:15:07.966Z" }, + { url = "https://files.pythonhosted.org/packages/fe/d4/a9b732f2f0072c0ab12227483abb24fffcb9f73f8a2b203df0a6d0434735/regex-2026.5.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:be3372b9df6ddecff6486d37e19095a7b4973137caf5512407a89f4455361f41", size = 803552, upload-time = "2026-05-09T23:15:10.215Z" }, + { url = "https://files.pythonhosted.org/packages/d5/fe/1b3113817447a1d4155e4ac76d2e072f42c0bcba2f43fa8a0e756ea2cd91/regex-2026.5.9-cp314-cp314t-win32.whl", hash = "sha256:3ddd90103f9e5c471c49c7852ecc1fe27c7e45eb99e977aefe7caa4e779f4f58", size = 275746, upload-time = "2026-05-09T23:15:12.609Z" }, + { url = "https://files.pythonhosted.org/packages/92/73/93d42045302636c91f2e5ef588b65b84b01428f28ec77de256b1dfdfbe5c/regex-2026.5.9-cp314-cp314t-win_amd64.whl", hash = "sha256:ca518ed29c46eecba6010b15f1b9a479314d2de409536e71b6a13aa04e3b8a77", size = 285685, upload-time = "2026-05-09T23:15:15.086Z" }, + { url = "https://files.pythonhosted.org/packages/da/80/35b4c33c804a165a7f55289afda3ea9e3eb6d15800341a2d66455c0f1f30/regex-2026.5.9-cp314-cp314t-win_arm64.whl", hash = "sha256:5e41809d2683fcde7d5a8c87a6567ba1fb1ce0de9f31bff578de00a4b2d76daa", size = 275713, upload-time = "2026-05-09T23:15:16.98Z" }, ] [[package]] name = "requests" -version = "2.33.1" +version = "2.34.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5f/a4/98b9c7c6428a668bf7e42ebb7c79d576a1c3c1e3ae2d47e674b468388871/requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517", size = 134120, upload-time = "2026-03-30T16:09:15.531Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/8e/7540e8a2036f79a125c1d2ebadf69ed7901608859186c856fa0388ef4197/requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a", size = 64947, upload-time = "2026-03-30T16:09:13.83Z" }, + { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, ] [[package]] @@ -1199,37 +1206,37 @@ name = "rich" version = "15.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "markdown-it-py" }, - { name = "pygments" }, + { name = "markdown-it-py" }, + { name = "pygments" }, ] sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, ] [[package]] name = "ruff" -version = "0.15.12" +version = "0.15.14" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/99/43/3291f1cc9106f4c63bdce7a8d0df5047fe8422a75b091c16b5e9355e0b11/ruff-0.15.12.tar.gz", hash = "sha256:ecea26adb26b4232c0c2ca19ccbc0083a68344180bba2a600605538ce51a40a6", size = 4643852, upload-time = "2026-04-24T18:17:14.305Z" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/8a/8bce2894573e9dae6ff4d77fe34ad727d79b9e6238ad288c5638990d90f6/ruff-0.15.14.tar.gz", hash = "sha256:48e866b165be4a9bdbf310f7d3c9a07edef2fe8cd63ffeb4e00bb590506ebf9f", size = 4700910, upload-time = "2026-05-21T14:34:55.177Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/6e/e78ffb61d4686f3d96ba3df2c801161843746dcbcbb17a1e927d4829312b/ruff-0.15.12-py3-none-linux_armv6l.whl", hash = "sha256:f86f176e188e94d6bdbc09f09bfd9dc729059ad93d0e7390b5a73efe19f8861c", size = 10640713, upload-time = "2026-04-24T18:17:22.841Z" }, - { url = "https://files.pythonhosted.org/packages/ae/08/a317bc231fb9e7b93e4ef3089501e51922ff88d6936ce5cf870c4fe55419/ruff-0.15.12-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e3bcd123364c3770b8e1b7baaf343cc99a35f197c5c6e8af79015c666c423a6c", size = 11069267, upload-time = "2026-04-24T18:17:30.105Z" }, - { url = "https://files.pythonhosted.org/packages/aa/a4/f828e9718d3dce1f5f11c39c4f65afd32783c8b2aebb2e3d259e492c47bd/ruff-0.15.12-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fe87510d000220aa1ed530d4448a7c696a0cae1213e5ec30e5874287b66557b5", size = 10397182, upload-time = "2026-04-24T18:17:07.177Z" }, - { url = "https://files.pythonhosted.org/packages/71/e0/3310fc6d1b5e1fdea22bf3b1b807c7e187b581021b0d7d4514cccdb5fb71/ruff-0.15.12-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84a1630093121375a3e2a95b4a6dc7b59e2b4ee76216e32d81aae550a832d002", size = 10758012, upload-time = "2026-04-24T18:16:55.759Z" }, - { url = "https://files.pythonhosted.org/packages/11/c1/a606911aee04c324ddaa883ae418f3569792fd3c4a10c50e0dd0a2311e1e/ruff-0.15.12-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fb129f40f114f089ebe0ca56c0d251cf2061b17651d464bb6478dc01e69f11f5", size = 10447479, upload-time = "2026-04-24T18:16:51.677Z" }, - { url = "https://files.pythonhosted.org/packages/9d/68/4201e8444f0894f21ab4aeeaee68aa4f10b51613514a20d80bd628d57e88/ruff-0.15.12-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b0c862b172d695db7598426b8af465e7e9ac00a3ea2a3630ee67eb82e366aaa6", size = 11234040, upload-time = "2026-04-24T18:17:16.529Z" }, - { url = "https://files.pythonhosted.org/packages/34/ff/8a6d6cf4ccc23fd67060874e832c18919d1557a0611ebef03fdb01fff11e/ruff-0.15.12-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2849ea9f3484c3aca43a82f484210370319e7170df4dfe4843395ddf6c57bc33", size = 12087377, upload-time = "2026-04-24T18:17:04.944Z" }, - { url = "https://files.pythonhosted.org/packages/85/f6/c669cf73f5152f623d34e69866a46d5e6185816b19fcd5b6dd8a2d299922/ruff-0.15.12-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9e77c7e51c07fe396826d5969a5b846d9cd4c402535835fb6e21ce8b28fef847", size = 11367784, upload-time = "2026-04-24T18:17:25.409Z" }, - { url = "https://files.pythonhosted.org/packages/e8/39/c61d193b8a1daaa8977f7dea9e8d8ba866e02ea7b65d32f6861693aa4c12/ruff-0.15.12-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b2f4f2f3b1026b5fb449b467d9264bf22067b600f7b6f41fc5958909f449d0", size = 11344088, upload-time = "2026-04-24T18:17:12.258Z" }, - { url = "https://files.pythonhosted.org/packages/c2/8d/49afab3645e31e12c590acb6d3b5b69d7aab5b81926dbaf7461f9441f37a/ruff-0.15.12-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:9ba3b8f1afd7e2e43d8943e55f249e13f9682fde09711644a6e7290eb4f3e339", size = 11271770, upload-time = "2026-04-24T18:17:02.457Z" }, - { url = "https://files.pythonhosted.org/packages/46/06/33f41fe94403e2b755481cdfb9b7ef3e4e0ed031c4581124658d935d52b4/ruff-0.15.12-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e852ba9fdc890655e1d78f2df1499efbe0e54126bd405362154a75e2bde159c5", size = 10719355, upload-time = "2026-04-24T18:17:27.648Z" }, - { url = "https://files.pythonhosted.org/packages/0d/59/18aa4e014debbf559670e4048e39260a85c7fcee84acfd761ac01e7b8d35/ruff-0.15.12-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dd8aed930da53780d22fc70bdf84452c843cf64f8cb4eb38984319c24c5cd5fd", size = 10462758, upload-time = "2026-04-24T18:17:32.347Z" }, - { url = "https://files.pythonhosted.org/packages/25/e7/cc9f16fd0f3b5fddcbd7ec3d6ae30c8f3fde1047f32a4093a98d633c6570/ruff-0.15.12-py3-none-musllinux_1_2_i686.whl", hash = "sha256:01da3988d225628b709493d7dc67c3b9b12c0210016b08690ef9bd27970b262b", size = 10953498, upload-time = "2026-04-24T18:17:20.674Z" }, - { url = "https://files.pythonhosted.org/packages/72/7a/a9ba7f98c7a575978698f4230c5e8cc54bbc761af34f560818f933dafa0c/ruff-0.15.12-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9cae0f92bd5700d1213188b31cd3bdd2b315361296d10b96b8e2337d3d11f53e", size = 11447765, upload-time = "2026-04-24T18:17:09.755Z" }, - { url = "https://files.pythonhosted.org/packages/ea/f9/0ae446942c846b8266059ad8a30702a35afae55f5cdc54c5adf8d7afdc27/ruff-0.15.12-py3-none-win32.whl", hash = "sha256:d0185894e038d7043ba8fd6aee7499ece6462dc0ea9f1e260c7451807c714c20", size = 10657277, upload-time = "2026-04-24T18:17:18.591Z" }, - { url = "https://files.pythonhosted.org/packages/33/f1/9614e03e1cdcbf9437570b5400ced8a720b5db22b28d8e0f1bda429f660d/ruff-0.15.12-py3-none-win_amd64.whl", hash = "sha256:c87a162d61ab3adca47c03f7f717c68672edec7d1b5499e652331780fe74950d", size = 11837758, upload-time = "2026-04-24T18:17:00.113Z" }, - { url = "https://files.pythonhosted.org/packages/c0/98/6beb4b351e472e5f4c4613f7c35a5290b8be2497e183825310c4c3a3984b/ruff-0.15.12-py3-none-win_arm64.whl", hash = "sha256:a538f7a82d061cee7be55542aca1d86d1393d55d81d4fcc314370f4340930d4f", size = 11120821, upload-time = "2026-04-24T18:16:57.979Z" }, + { url = "https://files.pythonhosted.org/packages/b9/c8/74a92c6ff9fcfb4f1f947126d3ebee8389276e161ecc85de5bda7cda51bd/ruff-0.15.14-py3-none-linux_armv6l.whl", hash = "sha256:8dd2db9416e487c8d4b01fa7056bb02c4d05969d4f8d17a08c229c2f4ff3c108", size = 10739177, upload-time = "2026-05-21T14:34:37.332Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/254a35c20acc38a7223c9d2d594af12e794432464f2cdeb52af1dc4a892d/ruff-0.15.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:be4ff55af755bd71a00ab3dc6bd7ffc467bd76e0df6881e286c2e3d23e8fb43b", size = 11144969, upload-time = "2026-05-21T14:34:43.978Z" }, + { url = "https://files.pythonhosted.org/packages/56/9e/d13e40f83b8d0a94430e6778ce1d94a43b38cf2efe63278bdd2b4c65abbf/ruff-0.15.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:48d5909d7d06276ce7dde6d32bfa4b0d4cb2651145cd8ee4b440722cbc77832f", size = 10478207, upload-time = "2026-05-21T14:34:48.378Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f1/b15a7839fa4f332f8acec78e20564f26bb2d866e3d21710b877fd0263000/ruff-0.15.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca8cbfa94c4f90984a67561978602746d4cd27103568f745fa90eee3f0d4107d", size = 10818459, upload-time = "2026-05-21T14:34:22.318Z" }, + { url = "https://files.pythonhosted.org/packages/45/33/53d651177f84f94b400a0e27f8824eeada3dddc9d5ee8aeb048f4352a520/ruff-0.15.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a6bbc0333f1ab053423bcbf6226477d266ca7cec7738c4c8e3f55647803f3c4", size = 10541800, upload-time = "2026-05-21T14:34:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/b8/a6/868f87e0bf9786ed24b5d0d0ad8676b8a94fd1912f42cddf9cfc7857818a/ruff-0.15.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a24a4f7605d7003a6674d4387651effd939dead3fddd0f36561eb77a9a2e542", size = 11342149, upload-time = "2026-05-21T14:34:46.365Z" }, + { url = "https://files.pythonhosted.org/packages/a7/8b/38cd5c19faffdcc05a408d2b78edccc69492ab9720eadb49ea15ef80d768/ruff-0.15.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:049b5326e53ed80978f2fc041a280603f69dd6b0c95464342a2bb4572d9d9e2f", size = 12212563, upload-time = "2026-05-21T14:34:28.579Z" }, + { url = "https://files.pythonhosted.org/packages/3e/4d/a3c5b874a556d5731e3e657aaf04311bb76f0a5c3ec220ed43051be6b64b/ruff-0.15.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4ed42e6696c8dfa5f06728e6441993901f548eb92d73bc472cb5a38d1395fbf", size = 11493299, upload-time = "2026-05-21T14:34:41.836Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c0/56472c251d09858a53e51efbd485b09e1995d8731668b76d52e5dd6ee0f1/ruff-0.15.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:715c543cf450c4888251f91c52f1942a800541d9bddd7ac060aa4e6b77ae7cba", size = 11455931, upload-time = "2026-05-21T14:34:57.276Z" }, + { url = "https://files.pythonhosted.org/packages/2c/4a/e2e7b4d8dbf233d4eace59c75bc3435fa6d8bd3bae82d351d4e4300c0fd1/ruff-0.15.14-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:72ebab6013ec887d439d8b7593737a0a4ffb06d45d209d4e4bf2e92813082d3f", size = 11400794, upload-time = "2026-05-21T14:34:39.773Z" }, + { url = "https://files.pythonhosted.org/packages/97/c7/83c0539fe34c3e09136204d1e75d6052492364e0b3cb05e9465423f567d7/ruff-0.15.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:49072d36abdbe97a8dd7f480afe9c675699c0c495d4c84076e2c1203c4550581", size = 10804759, upload-time = "2026-05-21T14:34:31.045Z" }, + { url = "https://files.pythonhosted.org/packages/86/a6/18f2bfc095a2ab4a78745644e428205532ce6653a5d0fa8501572891534d/ruff-0.15.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:958522aee105068640c2c2ceae08f413ae44d922f52a1374ac13d6a96032fc93", size = 10539517, upload-time = "2026-05-21T14:34:53.064Z" }, + { url = "https://files.pythonhosted.org/packages/54/3a/5a8b3b69c654d4e4bf1d246ac5b49cbcdac6eaab6905925f8915f31e3b80/ruff-0.15.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f3707da619a143a2e8830e2abab8224478d69ace2d28cb6c20543ae97c36bf61", size = 11065169, upload-time = "2026-05-21T14:34:24.484Z" }, + { url = "https://files.pythonhosted.org/packages/ed/c5/8864e4e7925b836ea354b31d57641ec03830564e281a8b6f061f8c3e0ec1/ruff-0.15.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bb01d645694e3ec0102105d07ef2d53703970407d59c04e59d3ba0b7a1d53553", size = 11560214, upload-time = "2026-05-21T14:34:50.975Z" }, + { url = "https://files.pythonhosted.org/packages/36/38/012bf76752e1f89ed50b77b99532d90f3a3e287bc7918e1fc0948ac866ac/ruff-0.15.14-py3-none-win32.whl", hash = "sha256:6d0c1ad2a0ab718d39b6d8fd2217981ce4d625cd96a720095f798fb47d8b13e6", size = 10805548, upload-time = "2026-05-21T14:34:33.453Z" }, + { url = "https://files.pythonhosted.org/packages/d1/b7/4ea2c170f10ad760fff2a5250beb18897719dc8b52b53a24cddbb9dd3f19/ruff-0.15.14-py3-none-win_amd64.whl", hash = "sha256:802342981e056db3851a7836e5b070f8f15f67d4a685ae2a6160939d364b2902", size = 11939523, upload-time = "2026-05-21T14:34:18.077Z" }, + { url = "https://files.pythonhosted.org/packages/62/d5/bc97ff895ec35cf3925d4bd60f3b39d822f377a446906ec9bcc87405e59b/ruff-0.15.14-py3-none-win_arm64.whl", hash = "sha256:ff47b90a9ef6a40c9e2f3b479c1fb78531adf055b94c1eba0a7ba04b31951826", size = 11208607, upload-time = "2026-05-21T14:34:26.525Z" }, ] [[package]] @@ -1238,20 +1245,20 @@ version = "0.7.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/29/9c/6e74567782559a63bd040a236edca26fd71bc7ba88de2ef35d75df3bca5e/safetensors-0.7.0.tar.gz", hash = "sha256:07663963b67e8bd9f0b8ad15bb9163606cd27cc5a1b96235a50d8369803b96b0", size = 200878, upload-time = "2025-11-19T15:18:43.199Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fa/47/aef6c06649039accf914afef490268e1067ed82be62bcfa5b7e886ad15e8/safetensors-0.7.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c82f4d474cf725255d9e6acf17252991c3c8aac038d6ef363a4bf8be2f6db517", size = 467781, upload-time = "2025-11-19T15:18:35.84Z" }, - { url = "https://files.pythonhosted.org/packages/e8/00/374c0c068e30cd31f1e1b46b4b5738168ec79e7689ca82ee93ddfea05109/safetensors-0.7.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:94fd4858284736bb67a897a41608b5b0c2496c9bdb3bf2af1fa3409127f20d57", size = 447058, upload-time = "2025-11-19T15:18:34.416Z" }, - { url = "https://files.pythonhosted.org/packages/f1/06/578ffed52c2296f93d7fd2d844cabfa92be51a587c38c8afbb8ae449ca89/safetensors-0.7.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e07d91d0c92a31200f25351f4acb2bc6aff7f48094e13ebb1d0fb995b54b6542", size = 491748, upload-time = "2025-11-19T15:18:09.79Z" }, - { url = "https://files.pythonhosted.org/packages/ae/33/1debbbb70e4791dde185edb9413d1fe01619255abb64b300157d7f15dddd/safetensors-0.7.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8469155f4cb518bafb4acf4865e8bb9d6804110d2d9bdcaa78564b9fd841e104", size = 503881, upload-time = "2025-11-19T15:18:16.145Z" }, - { url = "https://files.pythonhosted.org/packages/8e/1c/40c2ca924d60792c3be509833df711b553c60effbd91da6f5284a83f7122/safetensors-0.7.0-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:54bef08bf00a2bff599982f6b08e8770e09cc012d7bba00783fc7ea38f1fb37d", size = 623463, upload-time = "2025-11-19T15:18:21.11Z" }, - { url = "https://files.pythonhosted.org/packages/9b/3a/13784a9364bd43b0d61eef4bea2845039bc2030458b16594a1bd787ae26e/safetensors-0.7.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42cb091236206bb2016d245c377ed383aa7f78691748f3bb6ee1bfa51ae2ce6a", size = 532855, upload-time = "2025-11-19T15:18:25.719Z" }, - { url = "https://files.pythonhosted.org/packages/a0/60/429e9b1cb3fc651937727befe258ea24122d9663e4d5709a48c9cbfceecb/safetensors-0.7.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac7252938f0696ddea46f5e855dd3138444e82236e3be475f54929f0c510d48", size = 507152, upload-time = "2025-11-19T15:18:33.023Z" }, - { url = "https://files.pythonhosted.org/packages/3c/a8/4b45e4e059270d17af60359713ffd83f97900d45a6afa73aaa0d737d48b6/safetensors-0.7.0-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1d060c70284127fa805085d8f10fbd0962792aed71879d00864acda69dbab981", size = 541856, upload-time = "2025-11-19T15:18:31.075Z" }, - { url = "https://files.pythonhosted.org/packages/06/87/d26d8407c44175d8ae164a95b5a62707fcc445f3c0c56108e37d98070a3d/safetensors-0.7.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cdab83a366799fa730f90a4ebb563e494f28e9e92c4819e556152ad55e43591b", size = 674060, upload-time = "2025-11-19T15:18:37.211Z" }, - { url = "https://files.pythonhosted.org/packages/11/f5/57644a2ff08dc6325816ba7217e5095f17269dada2554b658442c66aed51/safetensors-0.7.0-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:672132907fcad9f2aedcb705b2d7b3b93354a2aec1b2f706c4db852abe338f85", size = 771715, upload-time = "2025-11-19T15:18:38.689Z" }, - { url = "https://files.pythonhosted.org/packages/86/31/17883e13a814bd278ae6e266b13282a01049b0c81341da7fd0e3e71a80a3/safetensors-0.7.0-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:5d72abdb8a4d56d4020713724ba81dac065fedb7f3667151c4a637f1d3fb26c0", size = 714377, upload-time = "2025-11-19T15:18:40.162Z" }, - { url = "https://files.pythonhosted.org/packages/4a/d8/0c8a7dc9b41dcac53c4cbf9df2b9c83e0e0097203de8b37a712b345c0be5/safetensors-0.7.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b0f6d66c1c538d5a94a73aa9ddca8ccc4227e6c9ff555322ea40bdd142391dd4", size = 677368, upload-time = "2025-11-19T15:18:41.627Z" }, - { url = "https://files.pythonhosted.org/packages/05/e5/cb4b713c8a93469e3c5be7c3f8d77d307e65fe89673e731f5c2bfd0a9237/safetensors-0.7.0-cp38-abi3-win32.whl", hash = "sha256:c74af94bf3ac15ac4d0f2a7c7b4663a15f8c2ab15ed0fc7531ca61d0835eccba", size = 326423, upload-time = "2025-11-19T15:18:45.74Z" }, - { url = "https://files.pythonhosted.org/packages/5d/e6/ec8471c8072382cb91233ba7267fd931219753bb43814cbc71757bfd4dab/safetensors-0.7.0-cp38-abi3-win_amd64.whl", hash = "sha256:d1239932053f56f3456f32eb9625590cc7582e905021f94636202a864d470755", size = 341380, upload-time = "2025-11-19T15:18:44.427Z" }, + { url = "https://files.pythonhosted.org/packages/fa/47/aef6c06649039accf914afef490268e1067ed82be62bcfa5b7e886ad15e8/safetensors-0.7.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:c82f4d474cf725255d9e6acf17252991c3c8aac038d6ef363a4bf8be2f6db517", size = 467781, upload-time = "2025-11-19T15:18:35.84Z" }, + { url = "https://files.pythonhosted.org/packages/e8/00/374c0c068e30cd31f1e1b46b4b5738168ec79e7689ca82ee93ddfea05109/safetensors-0.7.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:94fd4858284736bb67a897a41608b5b0c2496c9bdb3bf2af1fa3409127f20d57", size = 447058, upload-time = "2025-11-19T15:18:34.416Z" }, + { url = "https://files.pythonhosted.org/packages/f1/06/578ffed52c2296f93d7fd2d844cabfa92be51a587c38c8afbb8ae449ca89/safetensors-0.7.0-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e07d91d0c92a31200f25351f4acb2bc6aff7f48094e13ebb1d0fb995b54b6542", size = 491748, upload-time = "2025-11-19T15:18:09.79Z" }, + { url = "https://files.pythonhosted.org/packages/ae/33/1debbbb70e4791dde185edb9413d1fe01619255abb64b300157d7f15dddd/safetensors-0.7.0-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8469155f4cb518bafb4acf4865e8bb9d6804110d2d9bdcaa78564b9fd841e104", size = 503881, upload-time = "2025-11-19T15:18:16.145Z" }, + { url = "https://files.pythonhosted.org/packages/8e/1c/40c2ca924d60792c3be509833df711b553c60effbd91da6f5284a83f7122/safetensors-0.7.0-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:54bef08bf00a2bff599982f6b08e8770e09cc012d7bba00783fc7ea38f1fb37d", size = 623463, upload-time = "2025-11-19T15:18:21.11Z" }, + { url = "https://files.pythonhosted.org/packages/9b/3a/13784a9364bd43b0d61eef4bea2845039bc2030458b16594a1bd787ae26e/safetensors-0.7.0-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:42cb091236206bb2016d245c377ed383aa7f78691748f3bb6ee1bfa51ae2ce6a", size = 532855, upload-time = "2025-11-19T15:18:25.719Z" }, + { url = "https://files.pythonhosted.org/packages/a0/60/429e9b1cb3fc651937727befe258ea24122d9663e4d5709a48c9cbfceecb/safetensors-0.7.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac7252938f0696ddea46f5e855dd3138444e82236e3be475f54929f0c510d48", size = 507152, upload-time = "2025-11-19T15:18:33.023Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a8/4b45e4e059270d17af60359713ffd83f97900d45a6afa73aaa0d737d48b6/safetensors-0.7.0-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1d060c70284127fa805085d8f10fbd0962792aed71879d00864acda69dbab981", size = 541856, upload-time = "2025-11-19T15:18:31.075Z" }, + { url = "https://files.pythonhosted.org/packages/06/87/d26d8407c44175d8ae164a95b5a62707fcc445f3c0c56108e37d98070a3d/safetensors-0.7.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:cdab83a366799fa730f90a4ebb563e494f28e9e92c4819e556152ad55e43591b", size = 674060, upload-time = "2025-11-19T15:18:37.211Z" }, + { url = "https://files.pythonhosted.org/packages/11/f5/57644a2ff08dc6325816ba7217e5095f17269dada2554b658442c66aed51/safetensors-0.7.0-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:672132907fcad9f2aedcb705b2d7b3b93354a2aec1b2f706c4db852abe338f85", size = 771715, upload-time = "2025-11-19T15:18:38.689Z" }, + { url = "https://files.pythonhosted.org/packages/86/31/17883e13a814bd278ae6e266b13282a01049b0c81341da7fd0e3e71a80a3/safetensors-0.7.0-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:5d72abdb8a4d56d4020713724ba81dac065fedb7f3667151c4a637f1d3fb26c0", size = 714377, upload-time = "2025-11-19T15:18:40.162Z" }, + { url = "https://files.pythonhosted.org/packages/4a/d8/0c8a7dc9b41dcac53c4cbf9df2b9c83e0e0097203de8b37a712b345c0be5/safetensors-0.7.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b0f6d66c1c538d5a94a73aa9ddca8ccc4227e6c9ff555322ea40bdd142391dd4", size = 677368, upload-time = "2025-11-19T15:18:41.627Z" }, + { url = "https://files.pythonhosted.org/packages/05/e5/cb4b713c8a93469e3c5be7c3f8d77d307e65fe89673e731f5c2bfd0a9237/safetensors-0.7.0-cp38-abi3-win32.whl", hash = "sha256:c74af94bf3ac15ac4d0f2a7c7b4663a15f8c2ab15ed0fc7531ca61d0835eccba", size = 326423, upload-time = "2025-11-19T15:18:45.74Z" }, + { url = "https://files.pythonhosted.org/packages/5d/e6/ec8471c8072382cb91233ba7267fd931219753bb43814cbc71757bfd4dab/safetensors-0.7.0-cp38-abi3-win_amd64.whl", hash = "sha256:d1239932053f56f3456f32eb9625590cc7582e905021f94636202a864d470755", size = 341380, upload-time = "2025-11-19T15:18:44.427Z" }, ] [[package]] @@ -1259,37 +1266,37 @@ name = "scikit-learn" version = "1.8.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "joblib" }, - { name = "numpy" }, - { name = "scipy" }, - { name = "threadpoolctl" }, + { name = "joblib" }, + { name = "numpy" }, + { name = "scipy" }, + { name = "threadpoolctl" }, ] sdist = { url = "https://files.pythonhosted.org/packages/0e/d4/40988bf3b8e34feec1d0e6a051446b1f66225f8529b9309becaeef62b6c4/scikit_learn-1.8.0.tar.gz", hash = "sha256:9bccbb3b40e3de10351f8f5068e105d0f4083b1a65fa07b6634fbc401a6287fd", size = 7335585, upload-time = "2025-12-10T07:08:53.618Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/aa/e22e0768512ce9255eba34775be2e85c2048da73da1193e841707f8f039c/scikit_learn-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0d6ae97234d5d7079dc0040990a6f7aeb97cb7fa7e8945f1999a429b23569e0a", size = 8513770, upload-time = "2025-12-10T07:08:03.251Z" }, - { url = "https://files.pythonhosted.org/packages/58/37/31b83b2594105f61a381fc74ca19e8780ee923be2d496fcd8d2e1147bd99/scikit_learn-1.8.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:edec98c5e7c128328124a029bceb09eda2d526997780fef8d65e9a69eead963e", size = 8044458, upload-time = "2025-12-10T07:08:05.336Z" }, - { url = "https://files.pythonhosted.org/packages/2d/5a/3f1caed8765f33eabb723596666da4ebbf43d11e96550fb18bdec42b467b/scikit_learn-1.8.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:74b66d8689d52ed04c271e1329f0c61635bcaf5b926db9b12d58914cdc01fe57", size = 8610341, upload-time = "2025-12-10T07:08:07.732Z" }, - { url = "https://files.pythonhosted.org/packages/38/cf/06896db3f71c75902a8e9943b444a56e727418f6b4b4a90c98c934f51ed4/scikit_learn-1.8.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8fdf95767f989b0cfedb85f7ed8ca215d4be728031f56ff5a519ee1e3276dc2e", size = 8900022, upload-time = "2025-12-10T07:08:09.862Z" }, - { url = "https://files.pythonhosted.org/packages/1c/f9/9b7563caf3ec8873e17a31401858efab6b39a882daf6c1bfa88879c0aa11/scikit_learn-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:2de443b9373b3b615aec1bb57f9baa6bb3a9bd093f1269ba95c17d870422b271", size = 7989409, upload-time = "2025-12-10T07:08:12.028Z" }, - { url = "https://files.pythonhosted.org/packages/49/bd/1f4001503650e72c4f6009ac0c4413cb17d2d601cef6f71c0453da2732fc/scikit_learn-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:eddde82a035681427cbedded4e6eff5e57fa59216c2e3e90b10b19ab1d0a65c3", size = 7619760, upload-time = "2025-12-10T07:08:13.688Z" }, - { url = "https://files.pythonhosted.org/packages/d2/7d/a630359fc9dcc95496588c8d8e3245cc8fd81980251079bc09c70d41d951/scikit_learn-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7cc267b6108f0a1499a734167282c00c4ebf61328566b55ef262d48e9849c735", size = 8826045, upload-time = "2025-12-10T07:08:15.215Z" }, - { url = "https://files.pythonhosted.org/packages/cc/56/a0c86f6930cfcd1c7054a2bc417e26960bb88d32444fe7f71d5c2cfae891/scikit_learn-1.8.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:fe1c011a640a9f0791146011dfd3c7d9669785f9fed2b2a5f9e207536cf5c2fd", size = 8420324, upload-time = "2025-12-10T07:08:17.561Z" }, - { url = "https://files.pythonhosted.org/packages/46/1e/05962ea1cebc1cf3876667ecb14c283ef755bf409993c5946ade3b77e303/scikit_learn-1.8.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72358cce49465d140cc4e7792015bb1f0296a9742d5622c67e31399b75468b9e", size = 8680651, upload-time = "2025-12-10T07:08:19.952Z" }, - { url = "https://files.pythonhosted.org/packages/fe/56/a85473cd75f200c9759e3a5f0bcab2d116c92a8a02ee08ccd73b870f8bb4/scikit_learn-1.8.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:80832434a6cc114f5219211eec13dcbc16c2bac0e31ef64c6d346cde3cf054cb", size = 8925045, upload-time = "2025-12-10T07:08:22.11Z" }, - { url = "https://files.pythonhosted.org/packages/cc/b7/64d8cfa896c64435ae57f4917a548d7ac7a44762ff9802f75a79b77cb633/scikit_learn-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ee787491dbfe082d9c3013f01f5991658b0f38aa8177e4cd4bf434c58f551702", size = 8507994, upload-time = "2025-12-10T07:08:23.943Z" }, - { url = "https://files.pythonhosted.org/packages/5e/37/e192ea709551799379958b4c4771ec507347027bb7c942662c7fbeba31cb/scikit_learn-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf97c10a3f5a7543f9b88cbf488d33d175e9146115a451ae34568597ba33dcde", size = 7869518, upload-time = "2025-12-10T07:08:25.71Z" }, - { url = "https://files.pythonhosted.org/packages/24/05/1af2c186174cc92dcab2233f327336058c077d38f6fe2aceb08e6ab4d509/scikit_learn-1.8.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c22a2da7a198c28dd1a6e1136f19c830beab7fdca5b3e5c8bba8394f8a5c45b3", size = 8528667, upload-time = "2025-12-10T07:08:27.541Z" }, - { url = "https://files.pythonhosted.org/packages/a8/25/01c0af38fe969473fb292bba9dc2b8f9b451f3112ff242c647fee3d0dfe7/scikit_learn-1.8.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:6b595b07a03069a2b1740dc08c2299993850ea81cce4fe19b2421e0c970de6b7", size = 8066524, upload-time = "2025-12-10T07:08:29.822Z" }, - { url = "https://files.pythonhosted.org/packages/be/ce/a0623350aa0b68647333940ee46fe45086c6060ec604874e38e9ab7d8e6c/scikit_learn-1.8.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:29ffc74089f3d5e87dfca4c2c8450f88bdc61b0fc6ed5d267f3988f19a1309f6", size = 8657133, upload-time = "2025-12-10T07:08:31.865Z" }, - { url = "https://files.pythonhosted.org/packages/b8/cb/861b41341d6f1245e6ca80b1c1a8c4dfce43255b03df034429089ca2a2c5/scikit_learn-1.8.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb65db5d7531bccf3a4f6bec3462223bea71384e2cda41da0f10b7c292b9e7c4", size = 8923223, upload-time = "2025-12-10T07:08:34.166Z" }, - { url = "https://files.pythonhosted.org/packages/76/18/a8def8f91b18cd1ba6e05dbe02540168cb24d47e8dcf69e8d00b7da42a08/scikit_learn-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:56079a99c20d230e873ea40753102102734c5953366972a71d5cb39a32bc40c6", size = 8096518, upload-time = "2025-12-10T07:08:36.339Z" }, - { url = "https://files.pythonhosted.org/packages/d1/77/482076a678458307f0deb44e29891d6022617b2a64c840c725495bee343f/scikit_learn-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:3bad7565bc9cf37ce19a7c0d107742b320c1285df7aab1a6e2d28780df167242", size = 7754546, upload-time = "2025-12-10T07:08:38.128Z" }, - { url = "https://files.pythonhosted.org/packages/2d/d1/ef294ca754826daa043b2a104e59960abfab4cf653891037d19dd5b6f3cf/scikit_learn-1.8.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:4511be56637e46c25721e83d1a9cea9614e7badc7040c4d573d75fbe257d6fd7", size = 8848305, upload-time = "2025-12-10T07:08:41.013Z" }, - { url = "https://files.pythonhosted.org/packages/5b/e2/b1f8b05138ee813b8e1a4149f2f0d289547e60851fd1bb268886915adbda/scikit_learn-1.8.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:a69525355a641bf8ef136a7fa447672fb54fe8d60cab5538d9eb7c6438543fb9", size = 8432257, upload-time = "2025-12-10T07:08:42.873Z" }, - { url = "https://files.pythonhosted.org/packages/26/11/c32b2138a85dcb0c99f6afd13a70a951bfdff8a6ab42d8160522542fb647/scikit_learn-1.8.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c2656924ec73e5939c76ac4c8b026fc203b83d8900362eb2599d8aee80e4880f", size = 8678673, upload-time = "2025-12-10T07:08:45.362Z" }, - { url = "https://files.pythonhosted.org/packages/c7/57/51f2384575bdec454f4fe4e7a919d696c9ebce914590abf3e52d47607ab8/scikit_learn-1.8.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15fc3b5d19cc2be65404786857f2e13c70c83dd4782676dd6814e3b89dc8f5b9", size = 8922467, upload-time = "2025-12-10T07:08:47.408Z" }, - { url = "https://files.pythonhosted.org/packages/35/4d/748c9e2872637a57981a04adc038dacaa16ba8ca887b23e34953f0b3f742/scikit_learn-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:00d6f1d66fbcf4eba6e356e1420d33cc06c70a45bb1363cd6f6a8e4ebbbdece2", size = 8774395, upload-time = "2025-12-10T07:08:49.337Z" }, - { url = "https://files.pythonhosted.org/packages/60/22/d7b2ebe4704a5e50790ba089d5c2ae308ab6bb852719e6c3bd4f04c3a363/scikit_learn-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f28dd15c6bb0b66ba09728cf09fd8736c304be29409bd8445a080c1280619e8c", size = 8002647, upload-time = "2025-12-10T07:08:51.601Z" }, + { url = "https://files.pythonhosted.org/packages/03/aa/e22e0768512ce9255eba34775be2e85c2048da73da1193e841707f8f039c/scikit_learn-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0d6ae97234d5d7079dc0040990a6f7aeb97cb7fa7e8945f1999a429b23569e0a", size = 8513770, upload-time = "2025-12-10T07:08:03.251Z" }, + { url = "https://files.pythonhosted.org/packages/58/37/31b83b2594105f61a381fc74ca19e8780ee923be2d496fcd8d2e1147bd99/scikit_learn-1.8.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:edec98c5e7c128328124a029bceb09eda2d526997780fef8d65e9a69eead963e", size = 8044458, upload-time = "2025-12-10T07:08:05.336Z" }, + { url = "https://files.pythonhosted.org/packages/2d/5a/3f1caed8765f33eabb723596666da4ebbf43d11e96550fb18bdec42b467b/scikit_learn-1.8.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:74b66d8689d52ed04c271e1329f0c61635bcaf5b926db9b12d58914cdc01fe57", size = 8610341, upload-time = "2025-12-10T07:08:07.732Z" }, + { url = "https://files.pythonhosted.org/packages/38/cf/06896db3f71c75902a8e9943b444a56e727418f6b4b4a90c98c934f51ed4/scikit_learn-1.8.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8fdf95767f989b0cfedb85f7ed8ca215d4be728031f56ff5a519ee1e3276dc2e", size = 8900022, upload-time = "2025-12-10T07:08:09.862Z" }, + { url = "https://files.pythonhosted.org/packages/1c/f9/9b7563caf3ec8873e17a31401858efab6b39a882daf6c1bfa88879c0aa11/scikit_learn-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:2de443b9373b3b615aec1bb57f9baa6bb3a9bd093f1269ba95c17d870422b271", size = 7989409, upload-time = "2025-12-10T07:08:12.028Z" }, + { url = "https://files.pythonhosted.org/packages/49/bd/1f4001503650e72c4f6009ac0c4413cb17d2d601cef6f71c0453da2732fc/scikit_learn-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:eddde82a035681427cbedded4e6eff5e57fa59216c2e3e90b10b19ab1d0a65c3", size = 7619760, upload-time = "2025-12-10T07:08:13.688Z" }, + { url = "https://files.pythonhosted.org/packages/d2/7d/a630359fc9dcc95496588c8d8e3245cc8fd81980251079bc09c70d41d951/scikit_learn-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7cc267b6108f0a1499a734167282c00c4ebf61328566b55ef262d48e9849c735", size = 8826045, upload-time = "2025-12-10T07:08:15.215Z" }, + { url = "https://files.pythonhosted.org/packages/cc/56/a0c86f6930cfcd1c7054a2bc417e26960bb88d32444fe7f71d5c2cfae891/scikit_learn-1.8.0-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:fe1c011a640a9f0791146011dfd3c7d9669785f9fed2b2a5f9e207536cf5c2fd", size = 8420324, upload-time = "2025-12-10T07:08:17.561Z" }, + { url = "https://files.pythonhosted.org/packages/46/1e/05962ea1cebc1cf3876667ecb14c283ef755bf409993c5946ade3b77e303/scikit_learn-1.8.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72358cce49465d140cc4e7792015bb1f0296a9742d5622c67e31399b75468b9e", size = 8680651, upload-time = "2025-12-10T07:08:19.952Z" }, + { url = "https://files.pythonhosted.org/packages/fe/56/a85473cd75f200c9759e3a5f0bcab2d116c92a8a02ee08ccd73b870f8bb4/scikit_learn-1.8.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:80832434a6cc114f5219211eec13dcbc16c2bac0e31ef64c6d346cde3cf054cb", size = 8925045, upload-time = "2025-12-10T07:08:22.11Z" }, + { url = "https://files.pythonhosted.org/packages/cc/b7/64d8cfa896c64435ae57f4917a548d7ac7a44762ff9802f75a79b77cb633/scikit_learn-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ee787491dbfe082d9c3013f01f5991658b0f38aa8177e4cd4bf434c58f551702", size = 8507994, upload-time = "2025-12-10T07:08:23.943Z" }, + { url = "https://files.pythonhosted.org/packages/5e/37/e192ea709551799379958b4c4771ec507347027bb7c942662c7fbeba31cb/scikit_learn-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf97c10a3f5a7543f9b88cbf488d33d175e9146115a451ae34568597ba33dcde", size = 7869518, upload-time = "2025-12-10T07:08:25.71Z" }, + { url = "https://files.pythonhosted.org/packages/24/05/1af2c186174cc92dcab2233f327336058c077d38f6fe2aceb08e6ab4d509/scikit_learn-1.8.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:c22a2da7a198c28dd1a6e1136f19c830beab7fdca5b3e5c8bba8394f8a5c45b3", size = 8528667, upload-time = "2025-12-10T07:08:27.541Z" }, + { url = "https://files.pythonhosted.org/packages/a8/25/01c0af38fe969473fb292bba9dc2b8f9b451f3112ff242c647fee3d0dfe7/scikit_learn-1.8.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:6b595b07a03069a2b1740dc08c2299993850ea81cce4fe19b2421e0c970de6b7", size = 8066524, upload-time = "2025-12-10T07:08:29.822Z" }, + { url = "https://files.pythonhosted.org/packages/be/ce/a0623350aa0b68647333940ee46fe45086c6060ec604874e38e9ab7d8e6c/scikit_learn-1.8.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:29ffc74089f3d5e87dfca4c2c8450f88bdc61b0fc6ed5d267f3988f19a1309f6", size = 8657133, upload-time = "2025-12-10T07:08:31.865Z" }, + { url = "https://files.pythonhosted.org/packages/b8/cb/861b41341d6f1245e6ca80b1c1a8c4dfce43255b03df034429089ca2a2c5/scikit_learn-1.8.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fb65db5d7531bccf3a4f6bec3462223bea71384e2cda41da0f10b7c292b9e7c4", size = 8923223, upload-time = "2025-12-10T07:08:34.166Z" }, + { url = "https://files.pythonhosted.org/packages/76/18/a8def8f91b18cd1ba6e05dbe02540168cb24d47e8dcf69e8d00b7da42a08/scikit_learn-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:56079a99c20d230e873ea40753102102734c5953366972a71d5cb39a32bc40c6", size = 8096518, upload-time = "2025-12-10T07:08:36.339Z" }, + { url = "https://files.pythonhosted.org/packages/d1/77/482076a678458307f0deb44e29891d6022617b2a64c840c725495bee343f/scikit_learn-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:3bad7565bc9cf37ce19a7c0d107742b320c1285df7aab1a6e2d28780df167242", size = 7754546, upload-time = "2025-12-10T07:08:38.128Z" }, + { url = "https://files.pythonhosted.org/packages/2d/d1/ef294ca754826daa043b2a104e59960abfab4cf653891037d19dd5b6f3cf/scikit_learn-1.8.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:4511be56637e46c25721e83d1a9cea9614e7badc7040c4d573d75fbe257d6fd7", size = 8848305, upload-time = "2025-12-10T07:08:41.013Z" }, + { url = "https://files.pythonhosted.org/packages/5b/e2/b1f8b05138ee813b8e1a4149f2f0d289547e60851fd1bb268886915adbda/scikit_learn-1.8.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:a69525355a641bf8ef136a7fa447672fb54fe8d60cab5538d9eb7c6438543fb9", size = 8432257, upload-time = "2025-12-10T07:08:42.873Z" }, + { url = "https://files.pythonhosted.org/packages/26/11/c32b2138a85dcb0c99f6afd13a70a951bfdff8a6ab42d8160522542fb647/scikit_learn-1.8.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c2656924ec73e5939c76ac4c8b026fc203b83d8900362eb2599d8aee80e4880f", size = 8678673, upload-time = "2025-12-10T07:08:45.362Z" }, + { url = "https://files.pythonhosted.org/packages/c7/57/51f2384575bdec454f4fe4e7a919d696c9ebce914590abf3e52d47607ab8/scikit_learn-1.8.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15fc3b5d19cc2be65404786857f2e13c70c83dd4782676dd6814e3b89dc8f5b9", size = 8922467, upload-time = "2025-12-10T07:08:47.408Z" }, + { url = "https://files.pythonhosted.org/packages/35/4d/748c9e2872637a57981a04adc038dacaa16ba8ca887b23e34953f0b3f742/scikit_learn-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:00d6f1d66fbcf4eba6e356e1420d33cc06c70a45bb1363cd6f6a8e4ebbbdece2", size = 8774395, upload-time = "2025-12-10T07:08:49.337Z" }, + { url = "https://files.pythonhosted.org/packages/60/22/d7b2ebe4704a5e50790ba089d5c2ae308ab6bb852719e6c3bd4f04c3a363/scikit_learn-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:f28dd15c6bb0b66ba09728cf09fd8736c304be29409bd8445a080c1280619e8c", size = 8002647, upload-time = "2025-12-10T07:08:51.601Z" }, ] [[package]] @@ -1297,70 +1304,70 @@ name = "scipy" version = "1.17.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy" }, + { name = "numpy" }, ] sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/27/07ee1b57b65e92645f219b37148a7e7928b82e2b5dbeccecb4dff7c64f0b/scipy-1.17.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5e3c5c011904115f88a39308379c17f91546f77c1667cea98739fe0fccea804c", size = 31590199, upload-time = "2026-02-23T00:19:17.192Z" }, - { url = "https://files.pythonhosted.org/packages/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f", size = 28154001, upload-time = "2026-02-23T00:19:22.241Z" }, - { url = "https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d", size = 20325719, upload-time = "2026-02-23T00:19:26.329Z" }, - { url = "https://files.pythonhosted.org/packages/b2/83/15087d945e0e4d48ce2377498abf5ad171ae013232ae31d06f336e64c999/scipy-1.17.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4b400bdc6f79fa02a4d86640310dde87a21fba0c979efff5248908c6f15fad1b", size = 22683595, upload-time = "2026-02-23T00:19:30.304Z" }, - { url = "https://files.pythonhosted.org/packages/b4/e0/e58fbde4a1a594c8be8114eb4aac1a55bcd6587047efc18a61eb1f5c0d30/scipy-1.17.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b64ca7d4aee0102a97f3ba22124052b4bd2152522355073580bf4845e2550b6", size = 32896429, upload-time = "2026-02-23T00:19:35.536Z" }, - { url = "https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464", size = 35203952, upload-time = "2026-02-23T00:19:42.259Z" }, - { url = "https://files.pythonhosted.org/packages/8d/a5/9afd17de24f657fdfe4df9a3f1ea049b39aef7c06000c13db1530d81ccca/scipy-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:beeda3d4ae615106d7094f7e7cef6218392e4465cc95d25f900bebabfded0950", size = 34979063, upload-time = "2026-02-23T00:19:47.547Z" }, - { url = "https://files.pythonhosted.org/packages/8b/13/88b1d2384b424bf7c924f2038c1c409f8d88bb2a8d49d097861dd64a57b2/scipy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6609bc224e9568f65064cfa72edc0f24ee6655b47575954ec6339534b2798369", size = 37598449, upload-time = "2026-02-23T00:19:53.238Z" }, - { url = "https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448", size = 36510943, upload-time = "2026-02-23T00:20:50.89Z" }, - { url = "https://files.pythonhosted.org/packages/2a/fd/3be73c564e2a01e690e19cc618811540ba5354c67c8680dce3281123fb79/scipy-1.17.1-cp313-cp313-win_arm64.whl", hash = "sha256:5cf36e801231b6a2059bf354720274b7558746f3b1a4efb43fcf557ccd484a87", size = 24545621, upload-time = "2026-02-23T00:20:55.871Z" }, - { url = "https://files.pythonhosted.org/packages/6f/6b/17787db8b8114933a66f9dcc479a8272e4b4da75fe03b0c282f7b0ade8cd/scipy-1.17.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:d59c30000a16d8edc7e64152e30220bfbd724c9bbb08368c054e24c651314f0a", size = 31936708, upload-time = "2026-02-23T00:19:58.694Z" }, - { url = "https://files.pythonhosted.org/packages/38/2e/524405c2b6392765ab1e2b722a41d5da33dc5c7b7278184a8ad29b6cb206/scipy-1.17.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0", size = 28570135, upload-time = "2026-02-23T00:20:03.934Z" }, - { url = "https://files.pythonhosted.org/packages/fd/c3/5bd7199f4ea8556c0c8e39f04ccb014ac37d1468e6cfa6a95c6b3562b76e/scipy-1.17.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:2ceb2d3e01c5f1d83c4189737a42d9cb2fc38a6eeed225e7515eef71ad301dce", size = 20741977, upload-time = "2026-02-23T00:20:07.935Z" }, - { url = "https://files.pythonhosted.org/packages/d9/b8/8ccd9b766ad14c78386599708eb745f6b44f08400a5fd0ade7cf89b6fc93/scipy-1.17.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:844e165636711ef41f80b4103ed234181646b98a53c8f05da12ca5ca289134f6", size = 23029601, upload-time = "2026-02-23T00:20:12.161Z" }, - { url = "https://files.pythonhosted.org/packages/6d/a0/3cb6f4d2fb3e17428ad2880333cac878909ad1a89f678527b5328b93c1d4/scipy-1.17.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:158dd96d2207e21c966063e1635b1063cd7787b627b6f07305315dd73d9c679e", size = 33019667, upload-time = "2026-02-23T00:20:17.208Z" }, - { url = "https://files.pythonhosted.org/packages/f3/c3/2d834a5ac7bf3a0c806ad1508efc02dda3c8c61472a56132d7894c312dea/scipy-1.17.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74cbb80d93260fe2ffa334efa24cb8f2f0f622a9b9febf8b483c0b865bfb3475", size = 35264159, upload-time = "2026-02-23T00:20:23.087Z" }, - { url = "https://files.pythonhosted.org/packages/4d/77/d3ed4becfdbd217c52062fafe35a72388d1bd82c2d0ba5ca19d6fcc93e11/scipy-1.17.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dbc12c9f3d185f5c737d801da555fb74b3dcfa1a50b66a1a93e09190f41fab50", size = 35102771, upload-time = "2026-02-23T00:20:28.636Z" }, - { url = "https://files.pythonhosted.org/packages/bd/12/d19da97efde68ca1ee5538bb261d5d2c062f0c055575128f11a2730e3ac1/scipy-1.17.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94055a11dfebe37c656e70317e1996dc197e1a15bbcc351bcdd4610e128fe1ca", size = 37665910, upload-time = "2026-02-23T00:20:34.743Z" }, - { url = "https://files.pythonhosted.org/packages/06/1c/1172a88d507a4baaf72c5a09bb6c018fe2ae0ab622e5830b703a46cc9e44/scipy-1.17.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e30bdeaa5deed6bc27b4cc490823cd0347d7dae09119b8803ae576ea0ce52e4c", size = 36562980, upload-time = "2026-02-23T00:20:40.575Z" }, - { url = "https://files.pythonhosted.org/packages/70/b0/eb757336e5a76dfa7911f63252e3b7d1de00935d7705cf772db5b45ec238/scipy-1.17.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a720477885a9d2411f94a93d16f9d89bad0f28ca23c3f8daa521e2dcc3f44d49", size = 24856543, upload-time = "2026-02-23T00:20:45.313Z" }, - { url = "https://files.pythonhosted.org/packages/cf/83/333afb452af6f0fd70414dc04f898647ee1423979ce02efa75c3b0f2c28e/scipy-1.17.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:a48a72c77a310327f6a3a920092fa2b8fd03d7deaa60f093038f22d98e096717", size = 31584510, upload-time = "2026-02-23T00:21:01.015Z" }, - { url = "https://files.pythonhosted.org/packages/ed/a6/d05a85fd51daeb2e4ea71d102f15b34fedca8e931af02594193ae4fd25f7/scipy-1.17.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:45abad819184f07240d8a696117a7aacd39787af9e0b719d00285549ed19a1e9", size = 28170131, upload-time = "2026-02-23T00:21:05.888Z" }, - { url = "https://files.pythonhosted.org/packages/db/7b/8624a203326675d7746a254083a187398090a179335b2e4a20e2ddc46e83/scipy-1.17.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3fd1fcdab3ea951b610dc4cef356d416d5802991e7e32b5254828d342f7b7e0b", size = 20342032, upload-time = "2026-02-23T00:21:09.904Z" }, - { url = "https://files.pythonhosted.org/packages/c9/35/2c342897c00775d688d8ff3987aced3426858fd89d5a0e26e020b660b301/scipy-1.17.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7bdf2da170b67fdf10bca777614b1c7d96ae3ca5794fd9587dce41eb2966e866", size = 22678766, upload-time = "2026-02-23T00:21:14.313Z" }, - { url = "https://files.pythonhosted.org/packages/ef/f2/7cdb8eb308a1a6ae1e19f945913c82c23c0c442a462a46480ce487fdc0ac/scipy-1.17.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:adb2642e060a6549c343603a3851ba76ef0b74cc8c079a9a58121c7ec9fe2350", size = 32957007, upload-time = "2026-02-23T00:21:19.663Z" }, - { url = "https://files.pythonhosted.org/packages/0b/2e/7eea398450457ecb54e18e9d10110993fa65561c4f3add5e8eccd2b9cd41/scipy-1.17.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eee2cfda04c00a857206a4330f0c5e3e56535494e30ca445eb19ec624ae75118", size = 35221333, upload-time = "2026-02-23T00:21:25.278Z" }, - { url = "https://files.pythonhosted.org/packages/d9/77/5b8509d03b77f093a0d52e606d3c4f79e8b06d1d38c441dacb1e26cacf46/scipy-1.17.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d2650c1fb97e184d12d8ba010493ee7b322864f7d3d00d3f9bb97d9c21de4068", size = 35042066, upload-time = "2026-02-23T00:21:31.358Z" }, - { url = "https://files.pythonhosted.org/packages/f9/df/18f80fb99df40b4070328d5ae5c596f2f00fffb50167e31439e932f29e7d/scipy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:08b900519463543aa604a06bec02461558a6e1cef8fdbb8098f77a48a83c8118", size = 37612763, upload-time = "2026-02-23T00:21:37.247Z" }, - { url = "https://files.pythonhosted.org/packages/4b/39/f0e8ea762a764a9dc52aa7dabcfad51a354819de1f0d4652b6a1122424d6/scipy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:3877ac408e14da24a6196de0ddcace62092bfc12a83823e92e49e40747e52c19", size = 37290984, upload-time = "2026-02-23T00:22:35.023Z" }, - { url = "https://files.pythonhosted.org/packages/7c/56/fe201e3b0f93d1a8bcf75d3379affd228a63d7e2d80ab45467a74b494947/scipy-1.17.1-cp314-cp314-win_arm64.whl", hash = "sha256:f8885db0bc2bffa59d5c1b72fad7a6a92d3e80e7257f967dd81abb553a90d293", size = 25192877, upload-time = "2026-02-23T00:22:39.798Z" }, - { url = "https://files.pythonhosted.org/packages/96/ad/f8c414e121f82e02d76f310f16db9899c4fcde36710329502a6b2a3c0392/scipy-1.17.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:1cc682cea2ae55524432f3cdff9e9a3be743d52a7443d0cba9017c23c87ae2f6", size = 31949750, upload-time = "2026-02-23T00:21:42.289Z" }, - { url = "https://files.pythonhosted.org/packages/7c/b0/c741e8865d61b67c81e255f4f0a832846c064e426636cd7de84e74d209be/scipy-1.17.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:2040ad4d1795a0ae89bfc7e8429677f365d45aa9fd5e4587cf1ea737f927b4a1", size = 28585858, upload-time = "2026-02-23T00:21:47.706Z" }, - { url = "https://files.pythonhosted.org/packages/ed/1b/3985219c6177866628fa7c2595bfd23f193ceebbe472c98a08824b9466ff/scipy-1.17.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:131f5aaea57602008f9822e2115029b55d4b5f7c070287699fe45c661d051e39", size = 20757723, upload-time = "2026-02-23T00:21:52.039Z" }, - { url = "https://files.pythonhosted.org/packages/c0/19/2a04aa25050d656d6f7b9e7b685cc83d6957fb101665bfd9369ca6534563/scipy-1.17.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9cdc1a2fcfd5c52cfb3045feb399f7b3ce822abdde3a193a6b9a60b3cb5854ca", size = 23043098, upload-time = "2026-02-23T00:21:56.185Z" }, - { url = "https://files.pythonhosted.org/packages/86/f1/3383beb9b5d0dbddd030335bf8a8b32d4317185efe495374f134d8be6cce/scipy-1.17.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e3dcd57ab780c741fde8dc68619de988b966db759a3c3152e8e9142c26295ad", size = 33030397, upload-time = "2026-02-23T00:22:01.404Z" }, - { url = "https://files.pythonhosted.org/packages/41/68/8f21e8a65a5a03f25a79165ec9d2b28c00e66dc80546cf5eb803aeeff35b/scipy-1.17.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9956e4d4f4a301ebf6cde39850333a6b6110799d470dbbb1e25326ac447f52a", size = 35281163, upload-time = "2026-02-23T00:22:07.024Z" }, - { url = "https://files.pythonhosted.org/packages/84/8d/c8a5e19479554007a5632ed7529e665c315ae7492b4f946b0deb39870e39/scipy-1.17.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a4328d245944d09fd639771de275701ccadf5f781ba0ff092ad141e017eccda4", size = 35116291, upload-time = "2026-02-23T00:22:12.585Z" }, - { url = "https://files.pythonhosted.org/packages/52/52/e57eceff0e342a1f50e274264ed47497b59e6a4e3118808ee58ddda7b74a/scipy-1.17.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a77cbd07b940d326d39a1d1b37817e2ee4d79cb30e7338f3d0cddffae70fcaa2", size = 37682317, upload-time = "2026-02-23T00:22:18.513Z" }, - { url = "https://files.pythonhosted.org/packages/11/2f/b29eafe4a3fbc3d6de9662b36e028d5f039e72d345e05c250e121a230dd4/scipy-1.17.1-cp314-cp314t-win_amd64.whl", hash = "sha256:eb092099205ef62cd1782b006658db09e2fed75bffcae7cc0d44052d8aa0f484", size = 37345327, upload-time = "2026-02-23T00:22:24.442Z" }, - { url = "https://files.pythonhosted.org/packages/07/39/338d9219c4e87f3e708f18857ecd24d22a0c3094752393319553096b98af/scipy-1.17.1-cp314-cp314t-win_arm64.whl", hash = "sha256:200e1050faffacc162be6a486a984a0497866ec54149a01270adc8a59b7c7d21", size = 25489165, upload-time = "2026-02-23T00:22:29.563Z" }, + { url = "https://files.pythonhosted.org/packages/76/27/07ee1b57b65e92645f219b37148a7e7928b82e2b5dbeccecb4dff7c64f0b/scipy-1.17.1-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:5e3c5c011904115f88a39308379c17f91546f77c1667cea98739fe0fccea804c", size = 31590199, upload-time = "2026-02-23T00:19:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ae/db19f8ab842e9b724bf5dbb7db29302a91f1e55bc4d04b1025d6d605a2c5/scipy-1.17.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:6fac755ca3d2c3edcb22f479fceaa241704111414831ddd3bc6056e18516892f", size = 28154001, upload-time = "2026-02-23T00:19:22.241Z" }, + { url = "https://files.pythonhosted.org/packages/5b/58/3ce96251560107b381cbd6e8413c483bbb1228a6b919fa8652b0d4090e7f/scipy-1.17.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:7ff200bf9d24f2e4d5dc6ee8c3ac64d739d3a89e2326ba68aaf6c4a2b838fd7d", size = 20325719, upload-time = "2026-02-23T00:19:26.329Z" }, + { url = "https://files.pythonhosted.org/packages/b2/83/15087d945e0e4d48ce2377498abf5ad171ae013232ae31d06f336e64c999/scipy-1.17.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4b400bdc6f79fa02a4d86640310dde87a21fba0c979efff5248908c6f15fad1b", size = 22683595, upload-time = "2026-02-23T00:19:30.304Z" }, + { url = "https://files.pythonhosted.org/packages/b4/e0/e58fbde4a1a594c8be8114eb4aac1a55bcd6587047efc18a61eb1f5c0d30/scipy-1.17.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b64ca7d4aee0102a97f3ba22124052b4bd2152522355073580bf4845e2550b6", size = 32896429, upload-time = "2026-02-23T00:19:35.536Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464", size = 35203952, upload-time = "2026-02-23T00:19:42.259Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a5/9afd17de24f657fdfe4df9a3f1ea049b39aef7c06000c13db1530d81ccca/scipy-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:beeda3d4ae615106d7094f7e7cef6218392e4465cc95d25f900bebabfded0950", size = 34979063, upload-time = "2026-02-23T00:19:47.547Z" }, + { url = "https://files.pythonhosted.org/packages/8b/13/88b1d2384b424bf7c924f2038c1c409f8d88bb2a8d49d097861dd64a57b2/scipy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6609bc224e9568f65064cfa72edc0f24ee6655b47575954ec6339534b2798369", size = 37598449, upload-time = "2026-02-23T00:19:53.238Z" }, + { url = "https://files.pythonhosted.org/packages/35/e5/d6d0e51fc888f692a35134336866341c08655d92614f492c6860dc45bb2c/scipy-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:37425bc9175607b0268f493d79a292c39f9d001a357bebb6b88fdfaff13f6448", size = 36510943, upload-time = "2026-02-23T00:20:50.89Z" }, + { url = "https://files.pythonhosted.org/packages/2a/fd/3be73c564e2a01e690e19cc618811540ba5354c67c8680dce3281123fb79/scipy-1.17.1-cp313-cp313-win_arm64.whl", hash = "sha256:5cf36e801231b6a2059bf354720274b7558746f3b1a4efb43fcf557ccd484a87", size = 24545621, upload-time = "2026-02-23T00:20:55.871Z" }, + { url = "https://files.pythonhosted.org/packages/6f/6b/17787db8b8114933a66f9dcc479a8272e4b4da75fe03b0c282f7b0ade8cd/scipy-1.17.1-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:d59c30000a16d8edc7e64152e30220bfbd724c9bbb08368c054e24c651314f0a", size = 31936708, upload-time = "2026-02-23T00:19:58.694Z" }, + { url = "https://files.pythonhosted.org/packages/38/2e/524405c2b6392765ab1e2b722a41d5da33dc5c7b7278184a8ad29b6cb206/scipy-1.17.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:010f4333c96c9bb1a4516269e33cb5917b08ef2166d5556ca2fd9f082a9e6ea0", size = 28570135, upload-time = "2026-02-23T00:20:03.934Z" }, + { url = "https://files.pythonhosted.org/packages/fd/c3/5bd7199f4ea8556c0c8e39f04ccb014ac37d1468e6cfa6a95c6b3562b76e/scipy-1.17.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:2ceb2d3e01c5f1d83c4189737a42d9cb2fc38a6eeed225e7515eef71ad301dce", size = 20741977, upload-time = "2026-02-23T00:20:07.935Z" }, + { url = "https://files.pythonhosted.org/packages/d9/b8/8ccd9b766ad14c78386599708eb745f6b44f08400a5fd0ade7cf89b6fc93/scipy-1.17.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:844e165636711ef41f80b4103ed234181646b98a53c8f05da12ca5ca289134f6", size = 23029601, upload-time = "2026-02-23T00:20:12.161Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a0/3cb6f4d2fb3e17428ad2880333cac878909ad1a89f678527b5328b93c1d4/scipy-1.17.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:158dd96d2207e21c966063e1635b1063cd7787b627b6f07305315dd73d9c679e", size = 33019667, upload-time = "2026-02-23T00:20:17.208Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c3/2d834a5ac7bf3a0c806ad1508efc02dda3c8c61472a56132d7894c312dea/scipy-1.17.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74cbb80d93260fe2ffa334efa24cb8f2f0f622a9b9febf8b483c0b865bfb3475", size = 35264159, upload-time = "2026-02-23T00:20:23.087Z" }, + { url = "https://files.pythonhosted.org/packages/4d/77/d3ed4becfdbd217c52062fafe35a72388d1bd82c2d0ba5ca19d6fcc93e11/scipy-1.17.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dbc12c9f3d185f5c737d801da555fb74b3dcfa1a50b66a1a93e09190f41fab50", size = 35102771, upload-time = "2026-02-23T00:20:28.636Z" }, + { url = "https://files.pythonhosted.org/packages/bd/12/d19da97efde68ca1ee5538bb261d5d2c062f0c055575128f11a2730e3ac1/scipy-1.17.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94055a11dfebe37c656e70317e1996dc197e1a15bbcc351bcdd4610e128fe1ca", size = 37665910, upload-time = "2026-02-23T00:20:34.743Z" }, + { url = "https://files.pythonhosted.org/packages/06/1c/1172a88d507a4baaf72c5a09bb6c018fe2ae0ab622e5830b703a46cc9e44/scipy-1.17.1-cp313-cp313t-win_amd64.whl", hash = "sha256:e30bdeaa5deed6bc27b4cc490823cd0347d7dae09119b8803ae576ea0ce52e4c", size = 36562980, upload-time = "2026-02-23T00:20:40.575Z" }, + { url = "https://files.pythonhosted.org/packages/70/b0/eb757336e5a76dfa7911f63252e3b7d1de00935d7705cf772db5b45ec238/scipy-1.17.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a720477885a9d2411f94a93d16f9d89bad0f28ca23c3f8daa521e2dcc3f44d49", size = 24856543, upload-time = "2026-02-23T00:20:45.313Z" }, + { url = "https://files.pythonhosted.org/packages/cf/83/333afb452af6f0fd70414dc04f898647ee1423979ce02efa75c3b0f2c28e/scipy-1.17.1-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:a48a72c77a310327f6a3a920092fa2b8fd03d7deaa60f093038f22d98e096717", size = 31584510, upload-time = "2026-02-23T00:21:01.015Z" }, + { url = "https://files.pythonhosted.org/packages/ed/a6/d05a85fd51daeb2e4ea71d102f15b34fedca8e931af02594193ae4fd25f7/scipy-1.17.1-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:45abad819184f07240d8a696117a7aacd39787af9e0b719d00285549ed19a1e9", size = 28170131, upload-time = "2026-02-23T00:21:05.888Z" }, + { url = "https://files.pythonhosted.org/packages/db/7b/8624a203326675d7746a254083a187398090a179335b2e4a20e2ddc46e83/scipy-1.17.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:3fd1fcdab3ea951b610dc4cef356d416d5802991e7e32b5254828d342f7b7e0b", size = 20342032, upload-time = "2026-02-23T00:21:09.904Z" }, + { url = "https://files.pythonhosted.org/packages/c9/35/2c342897c00775d688d8ff3987aced3426858fd89d5a0e26e020b660b301/scipy-1.17.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:7bdf2da170b67fdf10bca777614b1c7d96ae3ca5794fd9587dce41eb2966e866", size = 22678766, upload-time = "2026-02-23T00:21:14.313Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f2/7cdb8eb308a1a6ae1e19f945913c82c23c0c442a462a46480ce487fdc0ac/scipy-1.17.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:adb2642e060a6549c343603a3851ba76ef0b74cc8c079a9a58121c7ec9fe2350", size = 32957007, upload-time = "2026-02-23T00:21:19.663Z" }, + { url = "https://files.pythonhosted.org/packages/0b/2e/7eea398450457ecb54e18e9d10110993fa65561c4f3add5e8eccd2b9cd41/scipy-1.17.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eee2cfda04c00a857206a4330f0c5e3e56535494e30ca445eb19ec624ae75118", size = 35221333, upload-time = "2026-02-23T00:21:25.278Z" }, + { url = "https://files.pythonhosted.org/packages/d9/77/5b8509d03b77f093a0d52e606d3c4f79e8b06d1d38c441dacb1e26cacf46/scipy-1.17.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d2650c1fb97e184d12d8ba010493ee7b322864f7d3d00d3f9bb97d9c21de4068", size = 35042066, upload-time = "2026-02-23T00:21:31.358Z" }, + { url = "https://files.pythonhosted.org/packages/f9/df/18f80fb99df40b4070328d5ae5c596f2f00fffb50167e31439e932f29e7d/scipy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:08b900519463543aa604a06bec02461558a6e1cef8fdbb8098f77a48a83c8118", size = 37612763, upload-time = "2026-02-23T00:21:37.247Z" }, + { url = "https://files.pythonhosted.org/packages/4b/39/f0e8ea762a764a9dc52aa7dabcfad51a354819de1f0d4652b6a1122424d6/scipy-1.17.1-cp314-cp314-win_amd64.whl", hash = "sha256:3877ac408e14da24a6196de0ddcace62092bfc12a83823e92e49e40747e52c19", size = 37290984, upload-time = "2026-02-23T00:22:35.023Z" }, + { url = "https://files.pythonhosted.org/packages/7c/56/fe201e3b0f93d1a8bcf75d3379affd228a63d7e2d80ab45467a74b494947/scipy-1.17.1-cp314-cp314-win_arm64.whl", hash = "sha256:f8885db0bc2bffa59d5c1b72fad7a6a92d3e80e7257f967dd81abb553a90d293", size = 25192877, upload-time = "2026-02-23T00:22:39.798Z" }, + { url = "https://files.pythonhosted.org/packages/96/ad/f8c414e121f82e02d76f310f16db9899c4fcde36710329502a6b2a3c0392/scipy-1.17.1-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:1cc682cea2ae55524432f3cdff9e9a3be743d52a7443d0cba9017c23c87ae2f6", size = 31949750, upload-time = "2026-02-23T00:21:42.289Z" }, + { url = "https://files.pythonhosted.org/packages/7c/b0/c741e8865d61b67c81e255f4f0a832846c064e426636cd7de84e74d209be/scipy-1.17.1-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:2040ad4d1795a0ae89bfc7e8429677f365d45aa9fd5e4587cf1ea737f927b4a1", size = 28585858, upload-time = "2026-02-23T00:21:47.706Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1b/3985219c6177866628fa7c2595bfd23f193ceebbe472c98a08824b9466ff/scipy-1.17.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:131f5aaea57602008f9822e2115029b55d4b5f7c070287699fe45c661d051e39", size = 20757723, upload-time = "2026-02-23T00:21:52.039Z" }, + { url = "https://files.pythonhosted.org/packages/c0/19/2a04aa25050d656d6f7b9e7b685cc83d6957fb101665bfd9369ca6534563/scipy-1.17.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:9cdc1a2fcfd5c52cfb3045feb399f7b3ce822abdde3a193a6b9a60b3cb5854ca", size = 23043098, upload-time = "2026-02-23T00:21:56.185Z" }, + { url = "https://files.pythonhosted.org/packages/86/f1/3383beb9b5d0dbddd030335bf8a8b32d4317185efe495374f134d8be6cce/scipy-1.17.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e3dcd57ab780c741fde8dc68619de988b966db759a3c3152e8e9142c26295ad", size = 33030397, upload-time = "2026-02-23T00:22:01.404Z" }, + { url = "https://files.pythonhosted.org/packages/41/68/8f21e8a65a5a03f25a79165ec9d2b28c00e66dc80546cf5eb803aeeff35b/scipy-1.17.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9956e4d4f4a301ebf6cde39850333a6b6110799d470dbbb1e25326ac447f52a", size = 35281163, upload-time = "2026-02-23T00:22:07.024Z" }, + { url = "https://files.pythonhosted.org/packages/84/8d/c8a5e19479554007a5632ed7529e665c315ae7492b4f946b0deb39870e39/scipy-1.17.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a4328d245944d09fd639771de275701ccadf5f781ba0ff092ad141e017eccda4", size = 35116291, upload-time = "2026-02-23T00:22:12.585Z" }, + { url = "https://files.pythonhosted.org/packages/52/52/e57eceff0e342a1f50e274264ed47497b59e6a4e3118808ee58ddda7b74a/scipy-1.17.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a77cbd07b940d326d39a1d1b37817e2ee4d79cb30e7338f3d0cddffae70fcaa2", size = 37682317, upload-time = "2026-02-23T00:22:18.513Z" }, + { url = "https://files.pythonhosted.org/packages/11/2f/b29eafe4a3fbc3d6de9662b36e028d5f039e72d345e05c250e121a230dd4/scipy-1.17.1-cp314-cp314t-win_amd64.whl", hash = "sha256:eb092099205ef62cd1782b006658db09e2fed75bffcae7cc0d44052d8aa0f484", size = 37345327, upload-time = "2026-02-23T00:22:24.442Z" }, + { url = "https://files.pythonhosted.org/packages/07/39/338d9219c4e87f3e708f18857ecd24d22a0c3094752393319553096b98af/scipy-1.17.1-cp314-cp314t-win_arm64.whl", hash = "sha256:200e1050faffacc162be6a486a984a0497866ec54149a01270adc8a59b7c7d21", size = 25489165, upload-time = "2026-02-23T00:22:29.563Z" }, ] [[package]] name = "sentence-transformers" -version = "5.4.1" +version = "5.5.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "huggingface-hub" }, - { name = "numpy" }, - { name = "scikit-learn" }, - { name = "scipy" }, - { name = "torch", version = "2.11.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.11.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin'" }, - { name = "tqdm" }, - { name = "transformers" }, - { name = "typing-extensions" }, + { name = "huggingface-hub" }, + { name = "numpy" }, + { name = "scikit-learn" }, + { name = "scipy" }, + { name = "torch", version = "2.12.0", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, + { name = "torch", version = "2.12.0+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin'" }, + { name = "tqdm" }, + { name = "transformers" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4d/68/7f98c221940ce783b492ad6140384daf2e2918cd7175009d6a362c22b9ee/sentence_transformers-5.4.1.tar.gz", hash = "sha256:436bcb1182a0ff42a8fb2b1c43498a70d0a75b688d182f2cd0d1dd115af61ddc", size = 428910, upload-time = "2026-04-14T13:34:59.006Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cf/d4/7ef93157485e978c016f49da05363c1e4e7237beb5343b64b5631101f0f1/sentence_transformers-5.5.1.tar.gz", hash = "sha256:02b7740dfc60bdbbcb6061625f5d97a5c1a4e2d3baac5f9391b912bb5eae2290", size = 445161, upload-time = "2026-05-20T07:37:44.465Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c5/d9/3a9b6f2ccdedc9dc00fe37b2fc58f58f8efbff44565cf4bf39d8568bb13a/sentence_transformers-5.4.1-py3-none-any.whl", hash = "sha256:a6d640fc363849b63affb8e140e9d328feabab86f83d58ac3e16b1c28140b790", size = 571311, upload-time = "2026-04-14T13:34:57.731Z" }, + { url = "https://files.pythonhosted.org/packages/bf/03/ee99a6b030e7a2e056547729f8a4709dd93e13d9c6f07590f74c395c4017/sentence_transformers-5.5.1-py3-none-any.whl", hash = "sha256:4fe11d433badc5282d32f7fc08bc714216b7a5aca426f9df77a45a554756deb7", size = 588887, upload-time = "2026-05-20T07:37:43.004Z" }, ] [[package]] @@ -1369,7 +1376,7 @@ version = "81.0.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/0d/1c/73e719955c59b8e424d015ab450f51c0af856ae46ea2da83eba51cc88de1/setuptools-81.0.0.tar.gz", hash = "sha256:487b53915f52501f0a79ccfd0c02c165ffe06631443a886740b91af4b7a5845a", size = 1198299, upload-time = "2026-02-06T21:10:39.601Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl", hash = "sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6", size = 1062021, upload-time = "2026-02-06T21:10:37.175Z" }, + { url = "https://files.pythonhosted.org/packages/e1/e3/c164c88b2e5ce7b24d667b9bd83589cf4f3520d97cad01534cd3c4f55fdb/setuptools-81.0.0-py3-none-any.whl", hash = "sha256:fdd925d5c5d9f62e4b74b30d6dd7828ce236fd6ed998a08d81de62ce5a6310d6", size = 1062021, upload-time = "2026-02-06T21:10:37.175Z" }, ] [[package]] @@ -1378,7 +1385,7 @@ version = "1.5.4" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] [[package]] @@ -1387,28 +1394,28 @@ version = "1.17.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] name = "sqlglot" -version = "30.6.0" +version = "30.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3c/66/6ece15f197874e56c76e1d0269cebf284ba992a80dfadca9d1972fdf7edf/sqlglot-30.6.0.tar.gz", hash = "sha256:246d34d39927422a50a3fa155f37b2f6346fba85f1a755b13c941eb32ef93361", size = 5835307, upload-time = "2026-04-20T20:11:08.164Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/64/89299aefc6ebdf4fc899f5dc14c7fcb7eb9da9290a2b4d615ae7ab884b17/sqlglot-30.8.0.tar.gz", hash = "sha256:1c5f93fb742dd9aaa75eee6bb33a637794a858b9a86375fac23a2dc0f7bc127e", size = 5869750, upload-time = "2026-05-13T09:04:38.923Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/e7/64fe971cbca33a0446b06f4a5ff8e3fa4a1dbd0a039ceabcc3e6cf4087a9/sqlglot-30.6.0-py3-none-any.whl", hash = "sha256:e005fc2f47994f90d7d8df341f1cbe937518497b0b7b1507d4c03c4c9dfd2778", size = 673920, upload-time = "2026-04-20T20:11:05.758Z" }, + { url = "https://files.pythonhosted.org/packages/88/4e/80705091aaf9c95e125d243f0aa871bc9f3670b4c9d963e6bad3b3dce8ff/sqlglot-30.8.0-py3-none-any.whl", hash = "sha256:af903378c331d5b72277a1b41118f07bc3e50cf4478e2d47eed12c96ee6a22a4", size = 687831, upload-time = "2026-05-13T09:04:36.336Z" }, ] [[package]] name = "starlette" -version = "1.0.0" +version = "1.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio" }, + { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/81/69/17425771797c36cded50b7fe44e850315d039f28b15901ab44839e70b593/starlette-1.0.0.tar.gz", hash = "sha256:6a4beaf1f81bb472fd19ea9b918b50dc3a77a6f2e190a12954b25e6ed5eea149", size = 2655289, upload-time = "2026-03-22T18:29:46.779Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c5/bf/616a066c2760f6c2b1ae3437cc28149734d069fbb46511712beae118a68c/starlette-1.2.0.tar.gz", hash = "sha256:3c5a6b23fff42492914e93890bb80cbfea72dbf37de268eec06185d62a4ca553", size = 2668923, upload-time = "2026-05-28T11:42:50.568Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/c9/584bc9651441b4ba60cc4d557d8a547b5aff901af35bda3a4ee30c819b82/starlette-1.0.0-py3-none-any.whl", hash = "sha256:d3ec55e0bb321692d275455ddfd3df75fff145d009685eb40dc91fc66b03d38b", size = 72651, upload-time = "2026-03-22T18:29:45.111Z" }, + { url = "https://files.pythonhosted.org/packages/9f/85/492183764d5d01d4514be3730fdb8e228a80605783099551c51627578b5d/starlette-1.2.0-py3-none-any.whl", hash = "sha256:36e0c76ac59157e75dc4b3bdeafba97fb04eaf1878045f15dbef666a6f092ed7", size = 73213, upload-time = "2026-05-28T11:42:48.801Z" }, ] [[package]] @@ -1416,11 +1423,11 @@ name = "sympy" version = "1.14.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "mpmath" }, + { name = "mpmath" }, ] sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, ] [[package]] @@ -1429,7 +1436,7 @@ version = "3.6.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, ] [[package]] @@ -1437,89 +1444,90 @@ name = "tokenizers" version = "0.22.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "huggingface-hub" }, + { name = "huggingface-hub" }, ] sdist = { url = "https://files.pythonhosted.org/packages/73/6f/f80cfef4a312e1fb34baf7d85c72d4411afde10978d4657f8cdd811d3ccc/tokenizers-0.22.2.tar.gz", hash = "sha256:473b83b915e547aa366d1eee11806deaf419e17be16310ac0a14077f1e28f917", size = 372115, upload-time = "2026-01-05T10:45:15.988Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/92/97/5dbfabf04c7e348e655e907ed27913e03db0923abb5dfdd120d7b25630e1/tokenizers-0.22.2-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:544dd704ae7238755d790de45ba8da072e9af3eea688f698b137915ae959281c", size = 3100275, upload-time = "2026-01-05T10:41:02.158Z" }, - { url = "https://files.pythonhosted.org/packages/2e/47/174dca0502ef88b28f1c9e06b73ce33500eedfac7a7692108aec220464e7/tokenizers-0.22.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1e418a55456beedca4621dbab65a318981467a2b188e982a23e117f115ce5001", size = 2981472, upload-time = "2026-01-05T10:41:00.276Z" }, - { url = "https://files.pythonhosted.org/packages/d6/84/7990e799f1309a8b87af6b948f31edaa12a3ed22d11b352eaf4f4b2e5753/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2249487018adec45d6e3554c71d46eb39fa8ea67156c640f7513eb26f318cec7", size = 3290736, upload-time = "2026-01-05T10:40:32.165Z" }, - { url = "https://files.pythonhosted.org/packages/78/59/09d0d9ba94dcd5f4f1368d4858d24546b4bdc0231c2354aa31d6199f0399/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b85325d0815e86e0bac263506dd114578953b7b53d7de09a6485e4a160a7dd", size = 3168835, upload-time = "2026-01-05T10:40:38.847Z" }, - { url = "https://files.pythonhosted.org/packages/47/50/b3ebb4243e7160bda8d34b731e54dd8ab8b133e50775872e7a434e524c28/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfb88f22a209ff7b40a576d5324bf8286b519d7358663db21d6246fb17eea2d5", size = 3521673, upload-time = "2026-01-05T10:40:56.614Z" }, - { url = "https://files.pythonhosted.org/packages/e0/fa/89f4cb9e08df770b57adb96f8cbb7e22695a4cb6c2bd5f0c4f0ebcf33b66/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c774b1276f71e1ef716e5486f21e76333464f47bece56bbd554485982a9e03e", size = 3724818, upload-time = "2026-01-05T10:40:44.507Z" }, - { url = "https://files.pythonhosted.org/packages/64/04/ca2363f0bfbe3b3d36e95bf67e56a4c88c8e3362b658e616d1ac185d47f2/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df6c4265b289083bf710dff49bc51ef252f9d5be33a45ee2bed151114a56207b", size = 3379195, upload-time = "2026-01-05T10:40:51.139Z" }, - { url = "https://files.pythonhosted.org/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67", size = 3274982, upload-time = "2026-01-05T10:40:58.331Z" }, - { url = "https://files.pythonhosted.org/packages/1d/28/5f9f5a4cc211b69e89420980e483831bcc29dade307955cc9dc858a40f01/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:29c30b83d8dcd061078b05ae0cb94d3c710555fbb44861139f9f83dcca3dc3e4", size = 9478245, upload-time = "2026-01-05T10:41:04.053Z" }, - { url = "https://files.pythonhosted.org/packages/6c/fb/66e2da4704d6aadebf8cb39f1d6d1957df667ab24cff2326b77cda0dcb85/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:37ae80a28c1d3265bb1f22464c856bd23c02a05bb211e56d0c5301a435be6c1a", size = 9560069, upload-time = "2026-01-05T10:45:10.673Z" }, - { url = "https://files.pythonhosted.org/packages/16/04/fed398b05caa87ce9b1a1bb5166645e38196081b225059a6edaff6440fac/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:791135ee325f2336f498590eb2f11dc5c295232f288e75c99a36c5dbce63088a", size = 9899263, upload-time = "2026-01-05T10:45:12.559Z" }, - { url = "https://files.pythonhosted.org/packages/05/a1/d62dfe7376beaaf1394917e0f8e93ee5f67fea8fcf4107501db35996586b/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5", size = 10033429, upload-time = "2026-01-05T10:45:14.333Z" }, - { url = "https://files.pythonhosted.org/packages/fd/18/a545c4ea42af3df6effd7d13d250ba77a0a86fb20393143bbb9a92e434d4/tokenizers-0.22.2-cp39-abi3-win32.whl", hash = "sha256:a6bf3f88c554a2b653af81f3204491c818ae2ac6fbc09e76ef4773351292bc92", size = 2502363, upload-time = "2026-01-05T10:45:20.593Z" }, - { url = "https://files.pythonhosted.org/packages/65/71/0670843133a43d43070abeb1949abfdef12a86d490bea9cd9e18e37c5ff7/tokenizers-0.22.2-cp39-abi3-win_amd64.whl", hash = "sha256:c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48", size = 2747786, upload-time = "2026-01-05T10:45:18.411Z" }, - { url = "https://files.pythonhosted.org/packages/72/f4/0de46cfa12cdcbcd464cc59fde36912af405696f687e53a091fb432f694c/tokenizers-0.22.2-cp39-abi3-win_arm64.whl", hash = "sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc", size = 2612133, upload-time = "2026-01-05T10:45:17.232Z" }, + { url = "https://files.pythonhosted.org/packages/92/97/5dbfabf04c7e348e655e907ed27913e03db0923abb5dfdd120d7b25630e1/tokenizers-0.22.2-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:544dd704ae7238755d790de45ba8da072e9af3eea688f698b137915ae959281c", size = 3100275, upload-time = "2026-01-05T10:41:02.158Z" }, + { url = "https://files.pythonhosted.org/packages/2e/47/174dca0502ef88b28f1c9e06b73ce33500eedfac7a7692108aec220464e7/tokenizers-0.22.2-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:1e418a55456beedca4621dbab65a318981467a2b188e982a23e117f115ce5001", size = 2981472, upload-time = "2026-01-05T10:41:00.276Z" }, + { url = "https://files.pythonhosted.org/packages/d6/84/7990e799f1309a8b87af6b948f31edaa12a3ed22d11b352eaf4f4b2e5753/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2249487018adec45d6e3554c71d46eb39fa8ea67156c640f7513eb26f318cec7", size = 3290736, upload-time = "2026-01-05T10:40:32.165Z" }, + { url = "https://files.pythonhosted.org/packages/78/59/09d0d9ba94dcd5f4f1368d4858d24546b4bdc0231c2354aa31d6199f0399/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25b85325d0815e86e0bac263506dd114578953b7b53d7de09a6485e4a160a7dd", size = 3168835, upload-time = "2026-01-05T10:40:38.847Z" }, + { url = "https://files.pythonhosted.org/packages/47/50/b3ebb4243e7160bda8d34b731e54dd8ab8b133e50775872e7a434e524c28/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfb88f22a209ff7b40a576d5324bf8286b519d7358663db21d6246fb17eea2d5", size = 3521673, upload-time = "2026-01-05T10:40:56.614Z" }, + { url = "https://files.pythonhosted.org/packages/e0/fa/89f4cb9e08df770b57adb96f8cbb7e22695a4cb6c2bd5f0c4f0ebcf33b66/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c774b1276f71e1ef716e5486f21e76333464f47bece56bbd554485982a9e03e", size = 3724818, upload-time = "2026-01-05T10:40:44.507Z" }, + { url = "https://files.pythonhosted.org/packages/64/04/ca2363f0bfbe3b3d36e95bf67e56a4c88c8e3362b658e616d1ac185d47f2/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df6c4265b289083bf710dff49bc51ef252f9d5be33a45ee2bed151114a56207b", size = 3379195, upload-time = "2026-01-05T10:40:51.139Z" }, + { url = "https://files.pythonhosted.org/packages/2e/76/932be4b50ef6ccedf9d3c6639b056a967a86258c6d9200643f01269211ca/tokenizers-0.22.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:369cc9fc8cc10cb24143873a0d95438bb8ee257bb80c71989e3ee290e8d72c67", size = 3274982, upload-time = "2026-01-05T10:40:58.331Z" }, + { url = "https://files.pythonhosted.org/packages/1d/28/5f9f5a4cc211b69e89420980e483831bcc29dade307955cc9dc858a40f01/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:29c30b83d8dcd061078b05ae0cb94d3c710555fbb44861139f9f83dcca3dc3e4", size = 9478245, upload-time = "2026-01-05T10:41:04.053Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fb/66e2da4704d6aadebf8cb39f1d6d1957df667ab24cff2326b77cda0dcb85/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:37ae80a28c1d3265bb1f22464c856bd23c02a05bb211e56d0c5301a435be6c1a", size = 9560069, upload-time = "2026-01-05T10:45:10.673Z" }, + { url = "https://files.pythonhosted.org/packages/16/04/fed398b05caa87ce9b1a1bb5166645e38196081b225059a6edaff6440fac/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:791135ee325f2336f498590eb2f11dc5c295232f288e75c99a36c5dbce63088a", size = 9899263, upload-time = "2026-01-05T10:45:12.559Z" }, + { url = "https://files.pythonhosted.org/packages/05/a1/d62dfe7376beaaf1394917e0f8e93ee5f67fea8fcf4107501db35996586b/tokenizers-0.22.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:38337540fbbddff8e999d59970f3c6f35a82de10053206a7562f1ea02d046fa5", size = 10033429, upload-time = "2026-01-05T10:45:14.333Z" }, + { url = "https://files.pythonhosted.org/packages/fd/18/a545c4ea42af3df6effd7d13d250ba77a0a86fb20393143bbb9a92e434d4/tokenizers-0.22.2-cp39-abi3-win32.whl", hash = "sha256:a6bf3f88c554a2b653af81f3204491c818ae2ac6fbc09e76ef4773351292bc92", size = 2502363, upload-time = "2026-01-05T10:45:20.593Z" }, + { url = "https://files.pythonhosted.org/packages/65/71/0670843133a43d43070abeb1949abfdef12a86d490bea9cd9e18e37c5ff7/tokenizers-0.22.2-cp39-abi3-win_amd64.whl", hash = "sha256:c9ea31edff2968b44a88f97d784c2f16dc0729b8b143ed004699ebca91f05c48", size = 2747786, upload-time = "2026-01-05T10:45:18.411Z" }, + { url = "https://files.pythonhosted.org/packages/72/f4/0de46cfa12cdcbcd464cc59fde36912af405696f687e53a091fb432f694c/tokenizers-0.22.2-cp39-abi3-win_arm64.whl", hash = "sha256:9ce725d22864a1e965217204946f830c37876eee3b2ba6fc6255e8e903d5fcbc", size = 2612133, upload-time = "2026-01-05T10:45:17.232Z" }, ] [[package]] name = "torch" -version = "2.11.0" +version = "2.12.0" source = { registry = "https://download.pytorch.org/whl/cpu" } resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'darwin'", - "python_full_version < '3.14' and sys_platform == 'darwin'", + "python_full_version >= '3.14' and sys_platform == 'darwin'", + "python_full_version < '3.14' and sys_platform == 'darwin'", ] dependencies = [ - { name = "filelock", marker = "sys_platform == 'darwin'" }, - { name = "fsspec", marker = "sys_platform == 'darwin'" }, - { name = "jinja2", marker = "sys_platform == 'darwin'" }, - { name = "networkx", marker = "sys_platform == 'darwin'" }, - { name = "setuptools", marker = "sys_platform == 'darwin'" }, - { name = "sympy", marker = "sys_platform == 'darwin'" }, - { name = "typing-extensions", marker = "sys_platform == 'darwin'" }, + { name = "filelock", marker = "sys_platform == 'darwin'" }, + { name = "fsspec", marker = "sys_platform == 'darwin'" }, + { name = "jinja2", marker = "sys_platform == 'darwin'" }, + { name = "networkx", marker = "sys_platform == 'darwin'" }, + { name = "setuptools", marker = "sys_platform == 'darwin'" }, + { name = "sympy", marker = "sys_platform == 'darwin'" }, + { name = "typing-extensions", marker = "sys_platform == 'darwin'" }, ] wheels = [ - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:442ec9dc78592564fdad69cf0beaa9da2f82ab810ccb4f13903869a90bf3f15d", upload-time = "2026-03-23T15:17:02Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cc3a195701bba2239c313ee311487f80f8aaebe9e89b9073dddbcf2f93b5a0ba", upload-time = "2026-03-23T15:17:06Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:072a0d6e4865e8b0dc0dbfe6ebed68fae235124222835ef03e5814d414d8c012", upload-time = "2026-03-23T15:17:10Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:23ec7789017da9d95b6d543d790814785e6f30905c5443efa8257d1490d73f79", upload-time = "2026-03-23T15:17:14Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:90dd587a5f61bfe1307148b581e2084fc5bc4a06e2b90a20e9a36b81087ff16b", upload-time = "2026-05-12T16:20:17Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:10ee1448a9f304d3b987eb4656f664ba6e4d7b410ca7a5a7c642199777a2cf88", upload-time = "2026-05-12T16:20:21Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f7dfae4a519197dfa050e98d8e36378a0fb5899625a875c2b54445005a2e404e", upload-time = "2026-05-12T16:20:26Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:b4556715c8572758625d62b6e0ae3b1f76c440221913a6fb5e100f321fb4fb02", upload-time = "2026-05-12T16:20:31Z" }, ] [[package]] name = "torch" -version = "2.11.0+cpu" +version = "2.12.0+cpu" source = { registry = "https://download.pytorch.org/whl/cpu" } resolution-markers = [ - "python_full_version >= '3.14' and sys_platform == 'win32'", - "python_full_version >= '3.14' and sys_platform == 'emscripten'", - "python_full_version >= '3.14' and sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32'", - "python_full_version < '3.14' and sys_platform == 'win32'", - "python_full_version < '3.14' and sys_platform == 'emscripten'", - "python_full_version < '3.14' and sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version < '3.14' and sys_platform != 'darwin' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ - { name = "filelock", marker = "sys_platform != 'darwin'" }, - { name = "fsspec", marker = "sys_platform != 'darwin'" }, - { name = "jinja2", marker = "sys_platform != 'darwin'" }, - { name = "networkx", marker = "sys_platform != 'darwin'" }, - { name = "setuptools", marker = "sys_platform != 'darwin'" }, - { name = "sympy", marker = "sys_platform != 'darwin'" }, - { name = "typing-extensions", marker = "sys_platform != 'darwin'" }, + { name = "filelock", marker = "sys_platform != 'darwin'" }, + { name = "fsspec", marker = "sys_platform != 'darwin'" }, + { name = "jinja2", marker = "sys_platform != 'darwin'" }, + { name = "networkx", marker = "sys_platform != 'darwin'" }, + { name = "setuptools", marker = "sys_platform != 'darwin'" }, + { name = "sympy", marker = "sys_platform != 'darwin'" }, + { name = "typing-extensions", marker = "sys_platform != 'darwin'" }, ] wheels = [ - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp313-cp313-linux_s390x.whl", hash = "sha256:d1eff25ccc454faf21c9666c81bfab8e405e87c12d300708d4559620bc191a36", upload-time = "2026-04-28T00:06:42Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:48b3e21a311445acdd0b27f13830e21d93adef70d4721e051e9f059baeb9b8f9", upload-time = "2026-04-28T00:06:51Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:45025d7752dbc6b4c784c03afaee9c5f19730ce084b2e43fc9a2fe1677d9ff86", upload-time = "2026-04-28T00:07:02Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp313-cp313-win_amd64.whl", hash = "sha256:ed70d4a4fc9f8b826c02fa1a9800a83820fb2fa6ae607680b53390f9ef394d85", upload-time = "2026-04-28T00:07:12Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp313-cp313t-linux_s390x.whl", hash = "sha256:65d427a196ab0abe359b93c5bffedd76ded02df2b1b1d2d9f11a2609b69f426a", upload-time = "2026-04-28T00:07:19Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:8f13dc7075ae04ca5f876a9f40b4e47522a04c23e30824b4409f42a3f3e57aa4", upload-time = "2026-04-28T00:07:27Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:8713bb8679376ea0ec25742100b6cfb8447e0904c48bddefb9eb0ac1abbfa60a", upload-time = "2026-04-28T00:07:37Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp313-cp313t-win_amd64.whl", hash = "sha256:62ec1f1694c185f601eab74eb7fc0e8e10c64c06ae82f13c3592774c231c4877", upload-time = "2026-04-28T00:07:47Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp314-cp314-linux_s390x.whl", hash = "sha256:c9a14c367f470623b978e273a4e1915995b4ba7a0ae999178b06c273eea3536f", upload-time = "2026-04-28T00:07:54Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:71676f6a9a84bbd385e010198b51fa1c2324fb8f3c512a32d2c81af65f68f4c9", upload-time = "2026-04-28T00:08:02Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:f8481ea9088e4e5b81178a75aabdbb658bde8639bc1a15fd5d8f930abc966735", upload-time = "2026-04-28T00:08:11Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp314-cp314-win_amd64.whl", hash = "sha256:7575af4c9f7f7500ed62b1dafeb069aa0ba35b368a5f09793b3976b3d50f4fe4", upload-time = "2026-04-28T00:08:20Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp314-cp314t-linux_s390x.whl", hash = "sha256:825f1596878280a3a4c861441674888bc2d792e4ab7b045cb35feeab3f4f5dd7", upload-time = "2026-04-28T00:08:27Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:c8a0bdfb2fd915b6c2cd27c856f63f729c366a4917772eba6b2b02aa3bce70d5", upload-time = "2026-04-28T00:08:36Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:768f22924a25cad2adeb9c6cbac5159e71067c8d4019b1511960d7435a5ca652", upload-time = "2026-04-28T00:08:47Z" }, - { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.11.0%2Bcpu-cp314-cp314t-win_amd64.whl", hash = "sha256:6db45e7b2526d996fbf47c3d08737807a60a4e17996a6d91a97027fe260832c8", upload-time = "2026-04-28T00:08:57Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp313-cp313-linux_s390x.whl", hash = "sha256:5e0da19e1c3bfdc9b92638c552579eac678354485d61fc8921b0461fd6c40449", upload-time = "2026-05-12T23:17:05Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:68b7ddd4db4603a03e106e74c7098c8d8c8943d33c1e5ada009ca4cd885759c3", upload-time = "2026-05-12T23:17:12Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:ada78018bdfa30d1c766596cd32d910dbf5b03424cd859231b6d2a00533de922", upload-time = "2026-05-12T23:17:20Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp313-cp313-win_amd64.whl", hash = "sha256:59bc266826e683899d49ee0af9829f3eafd0a16e15b5db9dc591c8d955003b66", upload-time = "2026-05-12T23:17:27Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp313-cp313-win_arm64.whl", hash = "sha256:97a5160abf3ca9d59a2cd7b4b4de89d9dfe290d36a1ac720262a55fbcee10b6c", upload-time = "2026-05-12T23:17:31Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp313-cp313t-linux_s390x.whl", hash = "sha256:32b9b7a0974cd6149cb98def0a28a49d92d7c14a384273d5539da9624239e950", upload-time = "2026-05-12T23:17:36Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:93ed8dc52c113580daf6124982b3232629045dccc5cd83a8f5ed478f7bac7340", upload-time = "2026-05-12T23:17:43Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:6a1c86abd4ed15a0736cf2663ad69642ae5d1288c99e30346070e6241018a0a9", upload-time = "2026-05-12T23:17:54Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp313-cp313t-win_amd64.whl", hash = "sha256:768dce4b7b3353795f667d1cb0dd7dfba06f570cd39539576097335e05bb71fe", upload-time = "2026-05-12T23:18:02Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp314-cp314-linux_s390x.whl", hash = "sha256:ee1f329acfd0c2a1ccaa3393bcaf9857ea58759549bb2d67e271a6eab42382b3", upload-time = "2026-05-12T23:18:08Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:797c066367792c92eb97cafba7fd0caa8d7455e6078a4ee880630077378dc372", upload-time = "2026-05-12T23:18:15Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:a8f419ce3f25388d36e67153ec63b3a1b17059c49f5a7759a7e91ac4843660d3", upload-time = "2026-05-12T23:18:22Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp314-cp314-win_amd64.whl", hash = "sha256:1dd196c43e74e7b3b526ff434e7efbdef3f3792a2efbecfc983d7dce501840d2", upload-time = "2026-05-12T23:18:30Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp314-cp314t-linux_s390x.whl", hash = "sha256:d0d2080cb13c94ebc0c884d237e404490743d0f40192c8a180abf3b6b6f334cf", upload-time = "2026-05-12T23:18:35Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:f7bc15972acad257723775237cdd120024cca844b8bc64701822fa596bcb7e14", upload-time = "2026-05-12T23:18:42Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:4d79f961250d1763487ecbc90af019a80009f9e87cadc5366b3ec4ba5671fea6", upload-time = "2026-05-12T23:18:50Z" }, + { url = "https://download-r2.pytorch.org/whl/cpu/torch-2.12.0%2Bcpu-cp314-cp314t-win_amd64.whl", hash = "sha256:46b8f4c41ac36bb5d5b47f5437b3de5541b313275e59c1d2aefd3bef32b0f531", upload-time = "2026-05-12T23:18:58Z" }, ] [[package]] @@ -1527,46 +1535,46 @@ name = "tqdm" version = "4.67.3" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598, upload-time = "2026-02-03T17:35:53.048Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" }, + { url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" }, ] [[package]] name = "transformers" -version = "5.6.2" +version = "5.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "huggingface-hub" }, - { name = "numpy" }, - { name = "packaging" }, - { name = "pyyaml" }, - { name = "regex" }, - { name = "safetensors" }, - { name = "tokenizers" }, - { name = "tqdm" }, - { name = "typer" }, + { name = "huggingface-hub" }, + { name = "numpy" }, + { name = "packaging" }, + { name = "pyyaml" }, + { name = "regex" }, + { name = "safetensors" }, + { name = "tokenizers" }, + { name = "tqdm" }, + { name = "typer" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a4/e9/c6c80a07690142a7d05444271f47b9f3c8aac7dea01d52e1137ee480ad78/transformers-5.6.2.tar.gz", hash = "sha256:e657134c3e5a6bc00a3c35f4e2674bb51adfcd89898495b788a18552bac2b91a", size = 8311867, upload-time = "2026-04-23T18:33:29.332Z" } +sdist = { url = "https://files.pythonhosted.org/packages/51/58/7f843608f2e8421f86bb97060b54649be6239ec612b82bf9d41e65c26c00/transformers-5.9.0.tar.gz", hash = "sha256:25997cb8fa6053533171634b6162d7df54346530ec2aa9b42bb834e63668c842", size = 8642240, upload-time = "2026-05-20T14:50:49.278Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/95/0b0218149b0d6f14df35f5b8f676fa83df4f19ed253c3cc447107ef86eca/transformers-5.6.2-py3-none-any.whl", hash = "sha256:f8d3a1bb96778fed9b8aabfd0dd6e19843e4b0f2bb6b59f32b8a92051b0f348f", size = 10364898, upload-time = "2026-04-23T18:33:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/02/ca/2eaa5359f2ccb8c2e1656bc26305ad0cf438aa392ce4b29ae67a315c186e/transformers-5.9.0-py3-none-any.whl", hash = "sha256:1d19509bcff7028ebc6b277d71caa712e8353778463d38764237d14b42b52788", size = 10787648, upload-time = "2026-05-20T14:50:45.337Z" }, ] [[package]] name = "typer" -version = "0.25.0" +version = "0.25.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "annotated-doc" }, - { name = "click" }, - { name = "rich" }, - { name = "shellingham" }, + { name = "annotated-doc" }, + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7b/27/ede8cec7596e0041ba7e7b80b47d132562f56ff454313a16f6084e555c9f/typer-0.25.0.tar.gz", hash = "sha256:123eaf9f19bb40fd268310e12a542c0c6b4fab9c98d9d23342a01ff95e3ce930", size = 120150, upload-time = "2026-04-26T08:46:14.767Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/51/9aed62104cea109b820bbd6c14245af756112017d309da813ef107d42e7e/typer-0.25.1.tar.gz", hash = "sha256:9616eb8853a09ffeabab1698952f33c6f29ffdbceb4eaeecf571880e8d7664cc", size = 122276, upload-time = "2026-04-30T19:32:16.964Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9a/72/193d4e586ec5a4db834a36bbeb47641a62f951f114ffd0fe5b1b46e8d56f/typer-0.25.0-py3-none-any.whl", hash = "sha256:ac01b48823d3db9a83c9e164338057eadbb1c9957a2a6b4eeb486669c560b5dc", size = 55993, upload-time = "2026-04-26T08:46:15.889Z" }, + { url = "https://files.pythonhosted.org/packages/3f/f9/2b3ff4e56e5fa7debfaf9eb135d0da96f3e9a1d5b27222223c7296336e5f/typer-0.25.1-py3-none-any.whl", hash = "sha256:75caa44ed46a03fb2dab8808753ffacdbfea88495e74c85a28c5eefcf5f39c89", size = 58409, upload-time = "2026-04-30T19:32:18.271Z" }, ] [[package]] @@ -1575,7 +1583,7 @@ version = "4.15.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, ] [[package]] @@ -1583,11 +1591,11 @@ name = "typing-inspection" version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "typing-extensions" }, + { name = "typing-extensions" }, ] sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, ] [[package]] @@ -1596,7 +1604,7 @@ version = "2026.2" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254, upload-time = "2026-04-24T15:22:08.651Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" }, + { url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" }, ] [[package]] @@ -1605,31 +1613,31 @@ version = "2.7.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, ] [[package]] name = "uvicorn" -version = "0.46.0" +version = "0.48.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "click" }, - { name = "h11" }, + { name = "click" }, + { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1f/93/041fca8274050e40e6791f267d82e0e2e27dd165627bd640d3e0e378d877/uvicorn-0.46.0.tar.gz", hash = "sha256:fb9da0926999cc6cb22dc7cd71a94a632f078e6ae47ff683c5c420750fb7413d", size = 88758, upload-time = "2026-04-23T07:16:00.151Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/bf/f6544ba992ddb9a6077343a576f9844f7f8f06ab819aefd00206e9255f18/uvicorn-0.48.0.tar.gz", hash = "sha256:a5504207195d08c2511bf9125ede5ac4a4b71725d519e758d01dcf0bc2d31c37", size = 91074, upload-time = "2026-05-24T12:08:41.925Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/a3/5b1562db76a5a488274b2332a97199b32d0442aca0ed193697fd47786316/uvicorn-0.46.0-py3-none-any.whl", hash = "sha256:bbebbcbed972d162afca128605223022bedd345b7bc7855ce66deb31487a9048", size = 70926, upload-time = "2026-04-23T07:15:58.355Z" }, + { url = "https://files.pythonhosted.org/packages/01/be/72532be3da7acc5fdfbccdb95215cd04f995a0886532a5b423f929cda4cc/uvicorn-0.48.0-py3-none-any.whl", hash = "sha256:48097851328b87ec36117d3d575234519eb58c2b22d79666e9bbc6c49a761dad", size = 71410, upload-time = "2026-05-24T12:08:40.258Z" }, ] [package.optional-dependencies] standard = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "httptools" }, - { name = "python-dotenv" }, - { name = "pyyaml" }, - { name = "uvloop", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32'" }, - { name = "watchfiles" }, - { name = "websockets" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "httptools" }, + { name = "python-dotenv" }, + { name = "pyyaml" }, + { name = "uvloop", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32'" }, + { name = "watchfiles" }, + { name = "websockets" }, ] [[package]] @@ -1638,96 +1646,111 @@ version = "0.22.1" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611, upload-time = "2025-10-16T22:16:36.833Z" }, - { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811, upload-time = "2025-10-16T22:16:38.275Z" }, - { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562, upload-time = "2025-10-16T22:16:39.375Z" }, - { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" }, - { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" }, - { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" }, - { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" }, - { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" }, - { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" }, - { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" }, - { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" }, - { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" }, - { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" }, - { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" }, - { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" }, - { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" }, - { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" }, + { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611, upload-time = "2025-10-16T22:16:36.833Z" }, + { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811, upload-time = "2025-10-16T22:16:38.275Z" }, + { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562, upload-time = "2025-10-16T22:16:39.375Z" }, + { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" }, + { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" }, + { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" }, + { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" }, + { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" }, + { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" }, + { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" }, + { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" }, + { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" }, + { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" }, + { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" }, ] [[package]] name = "virtualenv" -version = "21.2.4" +version = "21.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "distlib" }, - { name = "filelock" }, - { name = "platformdirs" }, - { name = "python-discovery" }, + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, + { name = "python-discovery" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0c/98/3a7e644e19cb26133488caff231be390579860bbbb3da35913c49a1d0a46/virtualenv-21.2.4.tar.gz", hash = "sha256:b294ef68192638004d72524ce7ef303e9d0cf5a44c95ce2e54a7500a6381cada", size = 5850742, upload-time = "2026-04-14T22:15:31.438Z" } +sdist = { url = "https://files.pythonhosted.org/packages/95/f0/b47ecf438211a25a97f8f0e4b23c22bc2496ebfea18dd6ec16210f09cc36/virtualenv-21.4.1.tar.gz", hash = "sha256:2ca543c713b72840ceffd94e9bdedfbd09a661defa1f7f69e5429ad4059442e2", size = 7613344, upload-time = "2026-05-28T04:12:49.905Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/8d/edd0bd910ff803c308ee9a6b7778621af0d10252219ad9f19ef4d4982a61/virtualenv-21.2.4-py3-none-any.whl", hash = "sha256:29d21e941795206138d0f22f4e45ff7050e5da6c6472299fb7103318763861ac", size = 5831232, upload-time = "2026-04-14T22:15:29.342Z" }, + { url = "https://files.pythonhosted.org/packages/ff/dc/ac4f3a987a87e1a18556896f257c4e15c95ed157b7975347ec6b313b75ce/virtualenv-21.4.1-py3-none-any.whl", hash = "sha256:caf4ff72d1b4039057f41d8e8466e859513d67c0400d9c6b62c02c9d1ebc3e12", size = 7594078, upload-time = "2026-05-28T04:12:47.686Z" }, ] [[package]] name = "watchfiles" -version = "1.1.1" +version = "1.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "anyio" }, + { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440, upload-time = "2025-10-14T15:06:21.08Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/41/5e1a4bb12aac5f1493fa1bdc11154eca3b258ca4eba65d39c473fe19d8e9/watchfiles-1.2.0.tar.gz", hash = "sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838", size = 108252, upload-time = "2026-05-18T04:32:04.251Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321, upload-time = "2025-10-14T15:05:02.063Z" }, - { url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783, upload-time = "2025-10-14T15:05:03.052Z" }, - { url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279, upload-time = "2025-10-14T15:05:04.004Z" }, - { url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405, upload-time = "2025-10-14T15:05:04.942Z" }, - { url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976, upload-time = "2025-10-14T15:05:05.905Z" }, - { url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506, upload-time = "2025-10-14T15:05:06.906Z" }, - { url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936, upload-time = "2025-10-14T15:05:07.906Z" }, - { url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147, upload-time = "2025-10-14T15:05:09.138Z" }, - { url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007, upload-time = "2025-10-14T15:05:10.117Z" }, - { url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280, upload-time = "2025-10-14T15:05:11.146Z" }, - { url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056, upload-time = "2025-10-14T15:05:12.156Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162, upload-time = "2025-10-14T15:05:13.208Z" }, - { url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909, upload-time = "2025-10-14T15:05:14.49Z" }, - { url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389, upload-time = "2025-10-14T15:05:15.777Z" }, - { url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964, upload-time = "2025-10-14T15:05:16.85Z" }, - { url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114, upload-time = "2025-10-14T15:05:17.876Z" }, - { url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264, upload-time = "2025-10-14T15:05:18.962Z" }, - { url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877, upload-time = "2025-10-14T15:05:20.094Z" }, - { url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176, upload-time = "2025-10-14T15:05:21.134Z" }, - { url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577, upload-time = "2025-10-14T15:05:22.306Z" }, - { url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425, upload-time = "2025-10-14T15:05:23.348Z" }, - { url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826, upload-time = "2025-10-14T15:05:24.398Z" }, - { url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208, upload-time = "2025-10-14T15:05:25.45Z" }, - { url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315, upload-time = "2025-10-14T15:05:26.501Z" }, - { url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869, upload-time = "2025-10-14T15:05:27.649Z" }, - { url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919, upload-time = "2025-10-14T15:05:28.701Z" }, - { url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845, upload-time = "2025-10-14T15:05:30.064Z" }, - { url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027, upload-time = "2025-10-14T15:05:31.064Z" }, - { url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615, upload-time = "2025-10-14T15:05:32.074Z" }, - { url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836, upload-time = "2025-10-14T15:05:33.209Z" }, - { url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099, upload-time = "2025-10-14T15:05:34.189Z" }, - { url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626, upload-time = "2025-10-14T15:05:35.216Z" }, - { url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519, upload-time = "2025-10-14T15:05:36.259Z" }, - { url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078, upload-time = "2025-10-14T15:05:37.63Z" }, - { url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664, upload-time = "2025-10-14T15:05:38.95Z" }, - { url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154, upload-time = "2025-10-14T15:05:39.954Z" }, - { url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820, upload-time = "2025-10-14T15:05:40.932Z" }, - { url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510, upload-time = "2025-10-14T15:05:41.945Z" }, - { url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408, upload-time = "2025-10-14T15:05:43.385Z" }, - { url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968, upload-time = "2025-10-14T15:05:44.404Z" }, - { url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096, upload-time = "2025-10-14T15:05:45.398Z" }, - { url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040, upload-time = "2025-10-14T15:05:46.502Z" }, - { url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847, upload-time = "2025-10-14T15:05:47.484Z" }, - { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072, upload-time = "2025-10-14T15:05:48.928Z" }, - { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104, upload-time = "2025-10-14T15:05:49.908Z" }, - { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112, upload-time = "2025-10-14T15:05:50.941Z" }, + { url = "https://files.pythonhosted.org/packages/d1/4d/70a7feced9f87e2ff26dba42667290f41694fc64646c67261fbb8cab5d5c/watchfiles-1.2.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:01ea8d66f0693b9b60a6541c8d10263091ca9a9060d242f3c1f3143f9aad2c98", size = 399730, upload-time = "2026-05-18T04:31:38.162Z" }, + { url = "https://files.pythonhosted.org/packages/31/3a/0da302f2307aee316922806ebd5726c542cbd787c938271cf14a074c7daf/watchfiles-1.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ba0480b9a74af058f43b337e937a451e109295c420916d68ad24e3dc02f5e44", size = 392842, upload-time = "2026-05-18T04:30:27.051Z" }, + { url = "https://files.pythonhosted.org/packages/db/ef/d5bdb705c224dbc256aa0c1ec47bf4e61ec52558f2afb44a71a1fe4d7015/watchfiles-1.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f34e26a19f91f710c08e0183429f0d1d15df734e6bc78c31e77b9ea9c433658", size = 452989, upload-time = "2026-05-18T04:31:11.945Z" }, + { url = "https://files.pythonhosted.org/packages/71/29/5495f2c1661949ef7a35e4d71111d129cfe7606414a26887a919d0a55406/watchfiles-1.2.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b4e77f6a55f858504069abd35d336a637555c09bca453dde1ee1e5ada8a6a1fb", size = 458978, upload-time = "2026-05-18T04:30:52.606Z" }, + { url = "https://files.pythonhosted.org/packages/d5/8c/7f9c07c433811c2fffd93e13fdfb7135de9aab5f2ae41be08960fa0047dc/watchfiles-1.2.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0cb4d80e212f116474a545c21c912b445f16bb0cef9e6a73a498164223e14e2f", size = 490248, upload-time = "2026-05-18T04:31:36.003Z" }, + { url = "https://files.pythonhosted.org/packages/3c/11/d93632febc52fbc21be90231bb7c17fd5387f46c9076fd40a5f9c2ae6910/watchfiles-1.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b974946a10af379d425e2eef5b62f5c6ebeaccf91d45eaad6f5b27ecd4f91aa0", size = 571847, upload-time = "2026-05-18T04:31:10.862Z" }, + { url = "https://files.pythonhosted.org/packages/55/b4/383173e73aabb07ad1d9c7aa859d95437ac46a6d6a1e11005facda0c9d19/watchfiles-1.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86bc13c25a8d1fcd70b51d0ce7c9b65e90de5666fcbfd3e34957cc73ee19aeb5", size = 465974, upload-time = "2026-05-18T04:30:17.006Z" }, + { url = "https://files.pythonhosted.org/packages/a7/6c/89b1a230a78f57c52dd8893adb1f92f94411721b6ec12596c56d98c74356/watchfiles-1.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca148d73dea36c9763aaa351e4d7a51780ec1584217c45276f4fe8239c768b71", size = 454782, upload-time = "2026-05-18T04:30:35.656Z" }, + { url = "https://files.pythonhosted.org/packages/24/62/1732118367cfff0a9fce3bf62ff4bfded09ef5df21d9d446b858b3f70a96/watchfiles-1.2.0-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:c525543d91961c6955b2636b308569e84a1d1c5f5f2932041ab9ef46422f43e3", size = 465182, upload-time = "2026-05-18T04:30:20.846Z" }, + { url = "https://files.pythonhosted.org/packages/28/96/716f7e5f51339bf22963f3345f9f27d7f3b30e2eadc597e257c881dd3c53/watchfiles-1.2.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:a204794696ffb8f9b10fba6f7cb5216d42f3b2b71860ccac6b6e42f5f10973b0", size = 629841, upload-time = "2026-05-18T04:31:05.397Z" }, + { url = "https://files.pythonhosted.org/packages/4c/fe/c40783950fd771ccf66ab3ec2722d188a9af1c7f96c6e811f36e40c6e03f/watchfiles-1.2.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:10d86db20695afe7997ac9e1717637d6714a8d0220458c33f3d2061f54cec427", size = 658028, upload-time = "2026-05-18T04:31:48.22Z" }, + { url = "https://files.pythonhosted.org/packages/71/72/4508db1856d1d87fcbb3b63f4839bab1b5682cb0e8d224d122263c09654a/watchfiles-1.2.0-cp313-cp313-win32.whl", hash = "sha256:eb283ee99e21ad6443c8cdb06ac5b34b1308c329cbdf03fa02b445363714c799", size = 275183, upload-time = "2026-05-18T04:30:59.57Z" }, + { url = "https://files.pythonhosted.org/packages/f9/36/14b76ca57652e5cc5fd1c11f32a261292c08a0d19a00351013c2549cbfb2/watchfiles-1.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:a0f27f01bee51861392bb6b7c4fdb290b27d1eb194e9e28788d68102a0e898d9", size = 288059, upload-time = "2026-05-18T04:32:07.937Z" }, + { url = "https://files.pythonhosted.org/packages/1b/8d/0a85e395398d8d20fadfe5c5d32c726eee17a519e78fb356f2cf7531bffe/watchfiles-1.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:3651aa7058595e9cfb75d35dd5ada2bf9f48a5b8a0f3562821d3e210c507e077", size = 280186, upload-time = "2026-05-18T04:31:54.484Z" }, + { url = "https://files.pythonhosted.org/packages/37/68/36db056f1fdcc5f07302f56e631774d6835bcd6fa3ace402304621d5f9e5/watchfiles-1.2.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:faea288b6f0ab1902ef08f4ca6de005dccf856c4e0c4f21b8c5fce02d90a1b08", size = 399031, upload-time = "2026-05-18T04:30:44.576Z" }, + { url = "https://files.pythonhosted.org/packages/c1/64/01a9d6f66a82a5c101ce939274106cc72759d62427e153f01edd2b9f87c2/watchfiles-1.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:01859b11fd9fbca670f4d5da00fbac282cfea9bd67a2125d8b2833a3b5617ea9", size = 391205, upload-time = "2026-05-18T04:30:25.413Z" }, + { url = "https://files.pythonhosted.org/packages/84/2c/0a44fe058cb4bb7b8ede6b6670698bbb7c0400740e378d00022189b7b31d/watchfiles-1.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fff610d7bb2256a317bb1e96f0d7862c7aa8076733ee5df0fd41bbe76a24a4f4", size = 451892, upload-time = "2026-05-18T04:32:14.005Z" }, + { url = "https://files.pythonhosted.org/packages/67/a1/351e0d56cd35e6488b5c8b4fb11a809a5bc923e8fe8fed9faf8920be0c89/watchfiles-1.2.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b141a4891c995a039cd89e9a49e62df1dc8a559a5d1a6e4c7106d16c12777a55", size = 458867, upload-time = "2026-05-18T04:31:22.279Z" }, + { url = "https://files.pythonhosted.org/packages/d5/7d/9d09605187f1b838998624049fcf8bf47b73c1a3b76901fcac1782f62277/watchfiles-1.2.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f22943b7770483f6ea0721c6b11d022947a98eb0acae14694de034f4d0d38925", size = 490217, upload-time = "2026-05-18T04:31:43.657Z" }, + { url = "https://files.pythonhosted.org/packages/60/5d/a17a16eccb182f04188cd308ec24b1a71a9b5c4e7098269cf35d9fa56d02/watchfiles-1.2.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1bc6195825b7dcd217968bb1f801a60fd4c16e8eeab5bedc7fe917d7d5995ab4", size = 571458, upload-time = "2026-05-18T04:32:11.875Z" }, + { url = "https://files.pythonhosted.org/packages/d3/3d/4dd457062083ab1938e5dfd45032eb425cee2ac817287ca8ff4356183e5d/watchfiles-1.2.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4a4b147f5dca2a5d325a06a832fb43f345751adfbc63204aec30e0d9ca965a2", size = 464707, upload-time = "2026-05-18T04:30:43.492Z" }, + { url = "https://files.pythonhosted.org/packages/c6/71/ea8c57b128f5383de74d0c7d2d9c57ad7c9a65a930c451bd25d524b295b7/watchfiles-1.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4543579a9bdb0c9560039b4ffddbdb39545707659fbc430ce4c10f3f68d557f9", size = 454663, upload-time = "2026-05-18T04:30:16.061Z" }, + { url = "https://files.pythonhosted.org/packages/53/fd/2e812bf938406d7db351f0703ddd3fc6c061cf30d96153a77bc79a943a44/watchfiles-1.2.0-cp313-cp313t-manylinux_2_31_riscv64.whl", hash = "sha256:20aa0e708b920bde876a4aa82dc7dd6ebea228a63a67cda6632c2fc87b787efa", size = 463537, upload-time = "2026-05-18T04:31:44.9Z" }, + { url = "https://files.pythonhosted.org/packages/86/56/d17a7f1dd1bc3035f1072694a551301272f1739c2d8e319c927cb9e29b38/watchfiles-1.2.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:d413349d565dab74297f2a63e84a097936be69bf8f3b3801f27f380e32040f44", size = 629194, upload-time = "2026-05-18T04:31:14.141Z" }, + { url = "https://files.pythonhosted.org/packages/be/06/f1ff66bf5cae50aa4062779a0ecd0bbaf15e466195719074078947d9a17d/watchfiles-1.2.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f28b2725eb8cce327b9b3ab02415c853011dc55c95832fe90de6bc56f5315f72", size = 656194, upload-time = "2026-05-18T04:31:47.14Z" }, + { url = "https://files.pythonhosted.org/packages/e7/54/a9c7ea9a82a4ac65e7004c0a03920b5cdd2f9c3b678757d9cd425aa51d53/watchfiles-1.2.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:b8c8358484d5fa12ef34f05b7f4168eaf1932f408725ff6d023c33ec17bd79d4", size = 400205, upload-time = "2026-05-18T04:32:05.153Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5d/c9ab3534374a4a67450696905d6ef16a04405448b8dc52bd752ae50423d4/watchfiles-1.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f04b092229ad2c50126dd3c922c8822e51e605993764a33058d4a791ab42281", size = 392508, upload-time = "2026-05-18T04:30:54.849Z" }, + { url = "https://files.pythonhosted.org/packages/26/ca/1ad30103535cf0cecd7b993e8d50edc5351b1820e38f2d22e3df58962feb/watchfiles-1.2.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a7ce236284f002a156f70add88efe5c70879cccbb658be0822c54b1306fc09d", size = 452448, upload-time = "2026-05-18T04:30:53.727Z" }, + { url = "https://files.pythonhosted.org/packages/37/a1/ceee2cdf2afbd715fa07758d39c9859513eae411b23196f7fd039e5feedd/watchfiles-1.2.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b9909cc2b48468b575eefa944919e1fe8a36c5849d5c7c168f80a8c1db69398e", size = 459605, upload-time = "2026-05-18T04:30:23.312Z" }, + { url = "https://files.pythonhosted.org/packages/e8/f6/421e30fd1cb3907a84ed92ab3f1983e37ba2dca015e9a894a048418417a2/watchfiles-1.2.0-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a37faaed405c67e28e6be45a1fa4f206ef5a2860f27c237db9fa30704c38242", size = 490757, upload-time = "2026-05-18T04:30:47.358Z" }, + { url = "https://files.pythonhosted.org/packages/41/b0/55ed1b97ed08be7bba6f9a541cac15f2a858e1d74d2b07b6da70a82aab00/watchfiles-1.2.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9649193aa27bd9ff2e80ff29bfaa93085496c7a3a377592823cc58b77ee88add", size = 568672, upload-time = "2026-05-18T04:30:38.915Z" }, + { url = "https://files.pythonhosted.org/packages/d1/cf/d8ae8a80dd7bafab395ea7681c10237311bbf34d37704a8c744e7cf31fc7/watchfiles-1.2.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e4ff8e37f99cf1da89e255e07c9c4b37c214038c4283707bdec308cb1b0ea1f", size = 464197, upload-time = "2026-05-18T04:30:09.914Z" }, + { url = "https://files.pythonhosted.org/packages/7c/8a/3076c496ca8dafe0e8cd03fcebdfc47be4b1174b4e5b24ff6e396e6b3af2/watchfiles-1.2.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:054dc20fd2e3132b4c3883b4a00d72fd6e1f56fdaf89fccd12e8057d74cd74d7", size = 453181, upload-time = "2026-05-18T04:30:14.829Z" }, + { url = "https://files.pythonhosted.org/packages/e5/10/9745e17c98e7b8a86454df0a3c7b5686bd650383f1e9f26e4ebcbd6cc0c0/watchfiles-1.2.0-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e140ed30ebde76796b686e67c182cff10ea2fbab186fafd1560f74bb5a473a6e", size = 465109, upload-time = "2026-05-18T04:30:28.123Z" }, + { url = "https://files.pythonhosted.org/packages/8f/95/8ef4a95481d3e0cb52d62a06fa6e972e81424be2d9698b91a2fecca9904c/watchfiles-1.2.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:bb7e52ecf68ba46d22df23467b87cffeb2146908aa523ebfe803019618cfda06", size = 630653, upload-time = "2026-05-18T04:31:49.304Z" }, + { url = "https://files.pythonhosted.org/packages/fd/e4/3b3bf36b0f829b50c6ebcb8d031583863c59f923d6a6af3d485e470d0fac/watchfiles-1.2.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:23282a321c8baf9b3a3c4afff673f9fe65eb7fdc2338d765ccad9d3d1916a5ba", size = 657838, upload-time = "2026-05-18T04:31:06.497Z" }, + { url = "https://files.pythonhosted.org/packages/21/b1/6cbbb50c1f3002ab568777d44aa21206dfb8807a840990c4037523b51812/watchfiles-1.2.0-cp314-cp314-win32.whl", hash = "sha256:c0db965c5f79aa49fe672d297cf1febc5ad149b658594944f49a54a2b96270a7", size = 275108, upload-time = "2026-05-18T04:30:06.891Z" }, + { url = "https://files.pythonhosted.org/packages/92/45/190ce6db8dcb4536682cf75d3889ff1a27182a58cb519d343cb6d9ea63d8/watchfiles-1.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:71283b39fd17e5408eb123bd37aeecfd9d54c81fc184421943208aadb879d103", size = 288441, upload-time = "2026-05-18T04:32:12.901Z" }, + { url = "https://files.pythonhosted.org/packages/74/0d/3eae1c2313ab08378431d907c3f8095ecca00f3eda33111cf4f0f2591799/watchfiles-1.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:c5c19526f4e54a00f2666a6c0e9e40d582c09e865055ea7378bf0009aab857b3", size = 280684, upload-time = "2026-05-18T04:31:26.902Z" }, + { url = "https://files.pythonhosted.org/packages/b1/75/fb64e6c25d6b5ca636d03df34ffb1c6e9873303e76d27967e045f8df088f/watchfiles-1.2.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d73a585accffa5ae39c17264c36ec3166d2fad7000c780f5ef83b2722afb9dd2", size = 398857, upload-time = "2026-05-18T04:32:17.108Z" }, + { url = "https://files.pythonhosted.org/packages/73/4e/9f7adf01754cbf81843722ccfec169d8f26c69778281a302855cecd2ee08/watchfiles-1.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ae99b14c5f21e026e0e9d96f40e07d8570ebee6cafd9d8fc318354606daa7a28", size = 392413, upload-time = "2026-05-18T04:31:07.911Z" }, + { url = "https://files.pythonhosted.org/packages/47/c8/bec626bcc2d69f44b9acb24ce7d60ed7b16b73628eea747fcbd169d8edda/watchfiles-1.2.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4429f3b105524a10b72c3a819b091c495d2811d419c1e1e8df773a5a5974f831", size = 452409, upload-time = "2026-05-18T04:31:20.142Z" }, + { url = "https://files.pythonhosted.org/packages/00/b7/b6362068e81e7c556d155a34c35d40ac3ef42d747b06d7f6e5bf58e359c2/watchfiles-1.2.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:43d818978d06062d9b22c4fab2ebe44cf5213d42dc8e62bda8c2760cfa2eeb33", size = 458827, upload-time = "2026-05-18T04:32:06.219Z" }, + { url = "https://files.pythonhosted.org/packages/67/f8/9a813fa42afb1e0b4625e75f0479826644d3ee8dc287e093799bc01f390c/watchfiles-1.2.0-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b9f732dc58b2dbe69e464ccf8fff7a03b0dd0be439da4c0720d3558527d3d6b4", size = 490104, upload-time = "2026-05-18T04:31:56.034Z" }, + { url = "https://files.pythonhosted.org/packages/2f/bf/27dfb6094ca4c9aad21298b5525b6c53cb36121ee454331d05161e58d130/watchfiles-1.2.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f200104103feb097de4cab8fe4f5dd18a2026934c7dea98c55a2f5fd6d5a33b", size = 571360, upload-time = "2026-05-18T04:31:57.133Z" }, + { url = "https://files.pythonhosted.org/packages/fb/39/44a096d67270ea93df91d33877dbe91fbda3aa4f8ec2edf799d93eda8736/watchfiles-1.2.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63ac26eefbf4af1741247d6fb68b11c49a25b2f7413fbd318a83a12aaa9cf666", size = 464644, upload-time = "2026-05-18T04:30:57.33Z" }, + { url = "https://files.pythonhosted.org/packages/0e/80/c7472203bad6268e3ef1ad260739704847898938ad7ea8b63a5131f46b50/watchfiles-1.2.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c4997d4e4a55f0d02b6cde327322daf3a0400e5df6c6b15948994bf72497925", size = 454771, upload-time = "2026-05-18T04:30:48.736Z" }, + { url = "https://files.pythonhosted.org/packages/51/cf/3b10b268b4b7f0fc26e9debb5eef1998b515887840f444cd3ec80c688755/watchfiles-1.2.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:4c887eba18b7945ac73067a8b4a66f21cd46c2539b2bc68588f7be6c7eb6d26b", size = 463494, upload-time = "2026-05-18T04:31:33.826Z" }, + { url = "https://files.pythonhosted.org/packages/3d/3e/a4302545cd589262a0dc7d140e86f7688eba3f9c72776c27f7e23b8864c4/watchfiles-1.2.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:3416ff151bb6b5a8d8d11664974fbef4d9305b9b2957839ab5a270468fd8df30", size = 629383, upload-time = "2026-05-18T04:31:15.596Z" }, + { url = "https://files.pythonhosted.org/packages/db/99/d5649df0a9a410d45b7c882304d0b790903ac9b6e8f2cfd12114e0c6b9f2/watchfiles-1.2.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:0e831a271c035d89789cffc386b6aa1375f39f1cd25eb7ca0997e4970d152fc5", size = 656093, upload-time = "2026-05-18T04:31:58.707Z" }, + { url = "https://files.pythonhosted.org/packages/92/b9/362702539275019a54dd2e94511b31a9b89c5f9e6a21966de7eb692549fc/watchfiles-1.2.0-cp315-cp315-macosx_10_12_x86_64.whl", hash = "sha256:37a6721cdf3f65dbb13aa9503510ccb4451603ac837e44d265d7992a597e1374", size = 400109, upload-time = "2026-05-18T04:31:16.879Z" }, + { url = "https://files.pythonhosted.org/packages/8f/75/71d5ba62db781e5587bded1d944c675374bc4aa37ff33d5018d98e8b6538/watchfiles-1.2.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:2b37d10b5a63bd4d87e18472d80fa525bd670586fae62e5dd580452764879b65", size = 392167, upload-time = "2026-05-18T04:31:28.058Z" }, + { url = "https://files.pythonhosted.org/packages/3c/01/c66dd95d0423fe30d31820e2d1d5bda773764131bbb6ac0cb1cf303ac328/watchfiles-1.2.0-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a105bc2283f67e8fbec74253ec2d94925de92ed72c0393f1206bf326b7b7b69", size = 452372, upload-time = "2026-05-18T04:31:00.836Z" }, + { url = "https://files.pythonhosted.org/packages/91/15/2fe99557e72f85627c6a8eed50d889e8d101623e060a22ad75b875cb932d/watchfiles-1.2.0-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5327989a465505f05cfe06f04fa9d0c2fd5432bb243e10e6f012b1bdca3c8579", size = 459596, upload-time = "2026-05-18T04:31:34.96Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/d4acfa0023367428ed48351b3b9b267893037b6cadae55620c61c24bcfd4/watchfiles-1.2.0-cp315-cp315-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ecb47f183a8025b2aa18b546725c3657e542112ae9c0613a2af79b4fa8d04ad7", size = 490869, upload-time = "2026-05-18T04:31:59.923Z" }, + { url = "https://files.pythonhosted.org/packages/a4/5f/3164cbdce06c9fb95c4f7b9e2f9760b5e2797af43a9ecc317ef42a23a278/watchfiles-1.2.0-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8520a4ab0e37f770afc34459c4f8f7019e153f9124dc101c15538365875d1ab2", size = 571641, upload-time = "2026-05-18T04:32:00.948Z" }, + { url = "https://files.pythonhosted.org/packages/41/e6/85d3731c55e65cd7690f3f803d24c139588aaf863e4bf2148fe7a7fa1a19/watchfiles-1.2.0-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:71cd71740ed2c15211ebb237ced4e39a1cdf6f80566e5fe95428da1626f4fde6", size = 464444, upload-time = "2026-05-18T04:30:34.298Z" }, + { url = "https://files.pythonhosted.org/packages/f4/7d/562641012b8b09872742c3b8adf9629ec479fd78f8d68ae4a0c13da8add6/watchfiles-1.2.0-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f88af53d6ddaf72179ef613ddc905e6f4785f712b49b80b3bef9f3525e6194b4", size = 453593, upload-time = "2026-05-18T04:31:23.464Z" }, + { url = "https://files.pythonhosted.org/packages/56/fe/cb8ef3d6f929d14158fdaaad9925985b7310abc9384dcd4d82dd0016fb59/watchfiles-1.2.0-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:cee9d5efd929efdac5f7e58f72b3376f676b64050a91c5b99a7094c5b2317488", size = 465096, upload-time = "2026-05-18T04:31:30.384Z" }, + { url = "https://files.pythonhosted.org/packages/25/91/80908e835e100527a9267147b08c0eee1fa6ab0ffec15edc04d1d44885f7/watchfiles-1.2.0-cp315-cp315-musllinux_1_1_aarch64.whl", hash = "sha256:b718bf356bbc15e559bd8ef41782b573b8ae0e3f177ab244b440568d7ea02cfb", size = 630638, upload-time = "2026-05-18T04:30:49.89Z" }, + { url = "https://files.pythonhosted.org/packages/46/4b/95ab2f256bb4af3cb2eb23b9317bda984ee6e0f11733a5c004a6c95b06e3/watchfiles-1.2.0-cp315-cp315-musllinux_1_1_x86_64.whl", hash = "sha256:922c0e019fe68b3ae392965a766b02a71ba1168c932cebc3733cd52c5fe5b377", size = 657684, upload-time = "2026-05-18T04:31:32.027Z" }, ] [[package]] @@ -1736,32 +1759,32 @@ version = "16.0" source = { registry = "https://pypi.org/simple" } sdist = { url = "https://files.pythonhosted.org/packages/04/24/4b2031d72e840ce4c1ccb255f693b15c334757fc50023e4db9537080b8c4/websockets-16.0.tar.gz", hash = "sha256:5f6261a5e56e8d5c42a4497b364ea24d94d9563e8fbd44e78ac40879c60179b5", size = 179346, upload-time = "2026-01-10T09:23:47.181Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/9c/baa8456050d1c1b08dd0ec7346026668cbc6f145ab4e314d707bb845bf0d/websockets-16.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:878b336ac47938b474c8f982ac2f7266a540adc3fa4ad74ae96fea9823a02cc9", size = 177364, upload-time = "2026-01-10T09:22:59.333Z" }, - { url = "https://files.pythonhosted.org/packages/7e/0c/8811fc53e9bcff68fe7de2bcbe75116a8d959ac699a3200f4847a8925210/websockets-16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52a0fec0e6c8d9a784c2c78276a48a2bdf099e4ccc2a4cad53b27718dbfd0230", size = 175039, upload-time = "2026-01-10T09:23:01.171Z" }, - { url = "https://files.pythonhosted.org/packages/aa/82/39a5f910cb99ec0b59e482971238c845af9220d3ab9fa76dd9162cda9d62/websockets-16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e6578ed5b6981005df1860a56e3617f14a6c307e6a71b4fff8c48fdc50f3ed2c", size = 175323, upload-time = "2026-01-10T09:23:02.341Z" }, - { url = "https://files.pythonhosted.org/packages/bd/28/0a25ee5342eb5d5f297d992a77e56892ecb65e7854c7898fb7d35e9b33bd/websockets-16.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:95724e638f0f9c350bb1c2b0a7ad0e83d9cc0c9259f3ea94e40d7b02a2179ae5", size = 184975, upload-time = "2026-01-10T09:23:03.756Z" }, - { url = "https://files.pythonhosted.org/packages/f9/66/27ea52741752f5107c2e41fda05e8395a682a1e11c4e592a809a90c6a506/websockets-16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0204dc62a89dc9d50d682412c10b3542d748260d743500a85c13cd1ee4bde82", size = 186203, upload-time = "2026-01-10T09:23:05.01Z" }, - { url = "https://files.pythonhosted.org/packages/37/e5/8e32857371406a757816a2b471939d51c463509be73fa538216ea52b792a/websockets-16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52ac480f44d32970d66763115edea932f1c5b1312de36df06d6b219f6741eed8", size = 185653, upload-time = "2026-01-10T09:23:06.301Z" }, - { url = "https://files.pythonhosted.org/packages/9b/67/f926bac29882894669368dc73f4da900fcdf47955d0a0185d60103df5737/websockets-16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6e5a82b677f8f6f59e8dfc34ec06ca6b5b48bc4fcda346acd093694cc2c24d8f", size = 184920, upload-time = "2026-01-10T09:23:07.492Z" }, - { url = "https://files.pythonhosted.org/packages/3c/a1/3d6ccdcd125b0a42a311bcd15a7f705d688f73b2a22d8cf1c0875d35d34a/websockets-16.0-cp313-cp313-win32.whl", hash = "sha256:abf050a199613f64c886ea10f38b47770a65154dc37181bfaff70c160f45315a", size = 178255, upload-time = "2026-01-10T09:23:09.245Z" }, - { url = "https://files.pythonhosted.org/packages/6b/ae/90366304d7c2ce80f9b826096a9e9048b4bb760e44d3b873bb272cba696b/websockets-16.0-cp313-cp313-win_amd64.whl", hash = "sha256:3425ac5cf448801335d6fdc7ae1eb22072055417a96cc6b31b3861f455fbc156", size = 178689, upload-time = "2026-01-10T09:23:10.483Z" }, - { url = "https://files.pythonhosted.org/packages/f3/1d/e88022630271f5bd349ed82417136281931e558d628dd52c4d8621b4a0b2/websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0", size = 177406, upload-time = "2026-01-10T09:23:12.178Z" }, - { url = "https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904", size = 175085, upload-time = "2026-01-10T09:23:13.511Z" }, - { url = "https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4", size = 175328, upload-time = "2026-01-10T09:23:14.727Z" }, - { url = "https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e", size = 185044, upload-time = "2026-01-10T09:23:15.939Z" }, - { url = "https://files.pythonhosted.org/packages/ad/6e/9a0927ac24bd33a0a9af834d89e0abc7cfd8e13bed17a86407a66773cc0e/websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4", size = 186279, upload-time = "2026-01-10T09:23:17.148Z" }, - { url = "https://files.pythonhosted.org/packages/b9/ca/bf1c68440d7a868180e11be653c85959502efd3a709323230314fda6e0b3/websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1", size = 185711, upload-time = "2026-01-10T09:23:18.372Z" }, - { url = "https://files.pythonhosted.org/packages/c4/f8/fdc34643a989561f217bb477cbc47a3a07212cbda91c0e4389c43c296ebf/websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3", size = 184982, upload-time = "2026-01-10T09:23:19.652Z" }, - { url = "https://files.pythonhosted.org/packages/dd/d1/574fa27e233764dbac9c52730d63fcf2823b16f0856b3329fc6268d6ae4f/websockets-16.0-cp314-cp314-win32.whl", hash = "sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8", size = 177915, upload-time = "2026-01-10T09:23:21.458Z" }, - { url = "https://files.pythonhosted.org/packages/8a/f1/ae6b937bf3126b5134ce1f482365fde31a357c784ac51852978768b5eff4/websockets-16.0-cp314-cp314-win_amd64.whl", hash = "sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d", size = 178381, upload-time = "2026-01-10T09:23:22.715Z" }, - { url = "https://files.pythonhosted.org/packages/06/9b/f791d1db48403e1f0a27577a6beb37afae94254a8c6f08be4a23e4930bc0/websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244", size = 177737, upload-time = "2026-01-10T09:23:24.523Z" }, - { url = "https://files.pythonhosted.org/packages/bd/40/53ad02341fa33b3ce489023f635367a4ac98b73570102ad2cdd770dacc9a/websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e", size = 175268, upload-time = "2026-01-10T09:23:25.781Z" }, - { url = "https://files.pythonhosted.org/packages/74/9b/6158d4e459b984f949dcbbb0c5d270154c7618e11c01029b9bbd1bb4c4f9/websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641", size = 175486, upload-time = "2026-01-10T09:23:27.033Z" }, - { url = "https://files.pythonhosted.org/packages/e5/2d/7583b30208b639c8090206f95073646c2c9ffd66f44df967981a64f849ad/websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8", size = 185331, upload-time = "2026-01-10T09:23:28.259Z" }, - { url = "https://files.pythonhosted.org/packages/45/b0/cce3784eb519b7b5ad680d14b9673a31ab8dcb7aad8b64d81709d2430aa8/websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e", size = 186501, upload-time = "2026-01-10T09:23:29.449Z" }, - { url = "https://files.pythonhosted.org/packages/19/60/b8ebe4c7e89fb5f6cdf080623c9d92789a53636950f7abacfc33fe2b3135/websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944", size = 186062, upload-time = "2026-01-10T09:23:31.368Z" }, - { url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206", size = 185356, upload-time = "2026-01-10T09:23:32.627Z" }, - { url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl", hash = "sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6", size = 178085, upload-time = "2026-01-10T09:23:33.816Z" }, - { url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd", size = 178531, upload-time = "2026-01-10T09:23:35.016Z" }, - { url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598, upload-time = "2026-01-10T09:23:45.395Z" }, + { url = "https://files.pythonhosted.org/packages/cc/9c/baa8456050d1c1b08dd0ec7346026668cbc6f145ab4e314d707bb845bf0d/websockets-16.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:878b336ac47938b474c8f982ac2f7266a540adc3fa4ad74ae96fea9823a02cc9", size = 177364, upload-time = "2026-01-10T09:22:59.333Z" }, + { url = "https://files.pythonhosted.org/packages/7e/0c/8811fc53e9bcff68fe7de2bcbe75116a8d959ac699a3200f4847a8925210/websockets-16.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:52a0fec0e6c8d9a784c2c78276a48a2bdf099e4ccc2a4cad53b27718dbfd0230", size = 175039, upload-time = "2026-01-10T09:23:01.171Z" }, + { url = "https://files.pythonhosted.org/packages/aa/82/39a5f910cb99ec0b59e482971238c845af9220d3ab9fa76dd9162cda9d62/websockets-16.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e6578ed5b6981005df1860a56e3617f14a6c307e6a71b4fff8c48fdc50f3ed2c", size = 175323, upload-time = "2026-01-10T09:23:02.341Z" }, + { url = "https://files.pythonhosted.org/packages/bd/28/0a25ee5342eb5d5f297d992a77e56892ecb65e7854c7898fb7d35e9b33bd/websockets-16.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:95724e638f0f9c350bb1c2b0a7ad0e83d9cc0c9259f3ea94e40d7b02a2179ae5", size = 184975, upload-time = "2026-01-10T09:23:03.756Z" }, + { url = "https://files.pythonhosted.org/packages/f9/66/27ea52741752f5107c2e41fda05e8395a682a1e11c4e592a809a90c6a506/websockets-16.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0204dc62a89dc9d50d682412c10b3542d748260d743500a85c13cd1ee4bde82", size = 186203, upload-time = "2026-01-10T09:23:05.01Z" }, + { url = "https://files.pythonhosted.org/packages/37/e5/8e32857371406a757816a2b471939d51c463509be73fa538216ea52b792a/websockets-16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:52ac480f44d32970d66763115edea932f1c5b1312de36df06d6b219f6741eed8", size = 185653, upload-time = "2026-01-10T09:23:06.301Z" }, + { url = "https://files.pythonhosted.org/packages/9b/67/f926bac29882894669368dc73f4da900fcdf47955d0a0185d60103df5737/websockets-16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6e5a82b677f8f6f59e8dfc34ec06ca6b5b48bc4fcda346acd093694cc2c24d8f", size = 184920, upload-time = "2026-01-10T09:23:07.492Z" }, + { url = "https://files.pythonhosted.org/packages/3c/a1/3d6ccdcd125b0a42a311bcd15a7f705d688f73b2a22d8cf1c0875d35d34a/websockets-16.0-cp313-cp313-win32.whl", hash = "sha256:abf050a199613f64c886ea10f38b47770a65154dc37181bfaff70c160f45315a", size = 178255, upload-time = "2026-01-10T09:23:09.245Z" }, + { url = "https://files.pythonhosted.org/packages/6b/ae/90366304d7c2ce80f9b826096a9e9048b4bb760e44d3b873bb272cba696b/websockets-16.0-cp313-cp313-win_amd64.whl", hash = "sha256:3425ac5cf448801335d6fdc7ae1eb22072055417a96cc6b31b3861f455fbc156", size = 178689, upload-time = "2026-01-10T09:23:10.483Z" }, + { url = "https://files.pythonhosted.org/packages/f3/1d/e88022630271f5bd349ed82417136281931e558d628dd52c4d8621b4a0b2/websockets-16.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8cc451a50f2aee53042ac52d2d053d08bf89bcb31ae799cb4487587661c038a0", size = 177406, upload-time = "2026-01-10T09:23:12.178Z" }, + { url = "https://files.pythonhosted.org/packages/f2/78/e63be1bf0724eeb4616efb1ae1c9044f7c3953b7957799abb5915bffd38e/websockets-16.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:daa3b6ff70a9241cf6c7fc9e949d41232d9d7d26fd3522b1ad2b4d62487e9904", size = 175085, upload-time = "2026-01-10T09:23:13.511Z" }, + { url = "https://files.pythonhosted.org/packages/bb/f4/d3c9220d818ee955ae390cf319a7c7a467beceb24f05ee7aaaa2414345ba/websockets-16.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:fd3cb4adb94a2a6e2b7c0d8d05cb94e6f1c81a0cf9dc2694fb65c7e8d94c42e4", size = 175328, upload-time = "2026-01-10T09:23:14.727Z" }, + { url = "https://files.pythonhosted.org/packages/63/bc/d3e208028de777087e6fb2b122051a6ff7bbcca0d6df9d9c2bf1dd869ae9/websockets-16.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:781caf5e8eee67f663126490c2f96f40906594cb86b408a703630f95550a8c3e", size = 185044, upload-time = "2026-01-10T09:23:15.939Z" }, + { url = "https://files.pythonhosted.org/packages/ad/6e/9a0927ac24bd33a0a9af834d89e0abc7cfd8e13bed17a86407a66773cc0e/websockets-16.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:caab51a72c51973ca21fa8a18bd8165e1a0183f1ac7066a182ff27107b71e1a4", size = 186279, upload-time = "2026-01-10T09:23:17.148Z" }, + { url = "https://files.pythonhosted.org/packages/b9/ca/bf1c68440d7a868180e11be653c85959502efd3a709323230314fda6e0b3/websockets-16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19c4dc84098e523fd63711e563077d39e90ec6702aff4b5d9e344a60cb3c0cb1", size = 185711, upload-time = "2026-01-10T09:23:18.372Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f8/fdc34643a989561f217bb477cbc47a3a07212cbda91c0e4389c43c296ebf/websockets-16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a5e18a238a2b2249c9a9235466b90e96ae4795672598a58772dd806edc7ac6d3", size = 184982, upload-time = "2026-01-10T09:23:19.652Z" }, + { url = "https://files.pythonhosted.org/packages/dd/d1/574fa27e233764dbac9c52730d63fcf2823b16f0856b3329fc6268d6ae4f/websockets-16.0-cp314-cp314-win32.whl", hash = "sha256:a069d734c4a043182729edd3e9f247c3b2a4035415a9172fd0f1b71658a320a8", size = 177915, upload-time = "2026-01-10T09:23:21.458Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f1/ae6b937bf3126b5134ce1f482365fde31a357c784ac51852978768b5eff4/websockets-16.0-cp314-cp314-win_amd64.whl", hash = "sha256:c0ee0e63f23914732c6d7e0cce24915c48f3f1512ec1d079ed01fc629dab269d", size = 178381, upload-time = "2026-01-10T09:23:22.715Z" }, + { url = "https://files.pythonhosted.org/packages/06/9b/f791d1db48403e1f0a27577a6beb37afae94254a8c6f08be4a23e4930bc0/websockets-16.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:a35539cacc3febb22b8f4d4a99cc79b104226a756aa7400adc722e83b0d03244", size = 177737, upload-time = "2026-01-10T09:23:24.523Z" }, + { url = "https://files.pythonhosted.org/packages/bd/40/53ad02341fa33b3ce489023f635367a4ac98b73570102ad2cdd770dacc9a/websockets-16.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:b784ca5de850f4ce93ec85d3269d24d4c82f22b7212023c974c401d4980ebc5e", size = 175268, upload-time = "2026-01-10T09:23:25.781Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/6158d4e459b984f949dcbbb0c5d270154c7618e11c01029b9bbd1bb4c4f9/websockets-16.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:569d01a4e7fba956c5ae4fc988f0d4e187900f5497ce46339c996dbf24f17641", size = 175486, upload-time = "2026-01-10T09:23:27.033Z" }, + { url = "https://files.pythonhosted.org/packages/e5/2d/7583b30208b639c8090206f95073646c2c9ffd66f44df967981a64f849ad/websockets-16.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:50f23cdd8343b984957e4077839841146f67a3d31ab0d00e6b824e74c5b2f6e8", size = 185331, upload-time = "2026-01-10T09:23:28.259Z" }, + { url = "https://files.pythonhosted.org/packages/45/b0/cce3784eb519b7b5ad680d14b9673a31ab8dcb7aad8b64d81709d2430aa8/websockets-16.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:152284a83a00c59b759697b7f9e9cddf4e3c7861dd0d964b472b70f78f89e80e", size = 186501, upload-time = "2026-01-10T09:23:29.449Z" }, + { url = "https://files.pythonhosted.org/packages/19/60/b8ebe4c7e89fb5f6cdf080623c9d92789a53636950f7abacfc33fe2b3135/websockets-16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bc59589ab64b0022385f429b94697348a6a234e8ce22544e3681b2e9331b5944", size = 186062, upload-time = "2026-01-10T09:23:31.368Z" }, + { url = "https://files.pythonhosted.org/packages/88/a8/a080593f89b0138b6cba1b28f8df5673b5506f72879322288b031337c0b8/websockets-16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32da954ffa2814258030e5a57bc73a3635463238e797c7375dc8091327434206", size = 185356, upload-time = "2026-01-10T09:23:32.627Z" }, + { url = "https://files.pythonhosted.org/packages/c2/b6/b9afed2afadddaf5ebb2afa801abf4b0868f42f8539bfe4b071b5266c9fe/websockets-16.0-cp314-cp314t-win32.whl", hash = "sha256:5a4b4cc550cb665dd8a47f868c8d04c8230f857363ad3c9caf7a0c3bf8c61ca6", size = 178085, upload-time = "2026-01-10T09:23:33.816Z" }, + { url = "https://files.pythonhosted.org/packages/9f/3e/28135a24e384493fa804216b79a6a6759a38cc4ff59118787b9fb693df93/websockets-16.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b14dc141ed6d2dde437cddb216004bcac6a1df0935d79656387bd41632ba0bbd", size = 178531, upload-time = "2026-01-10T09:23:35.016Z" }, + { url = "https://files.pythonhosted.org/packages/6f/28/258ebab549c2bf3e64d2b0217b973467394a9cea8c42f70418ca2c5d0d2e/websockets-16.0-py3-none-any.whl", hash = "sha256:1637db62fad1dc833276dded54215f2c7fa46912301a24bd94d45d46a011ceec", size = 171598, upload-time = "2026-01-10T09:23:45.395Z" }, ] From 0a517b2c13e2f04c1ff91109903ef226f96c794f Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Fri, 29 May 2026 15:02:57 +0200 Subject: [PATCH 14/61] skill: document adding context sources; docs: one-shot full-demo path (#234) - skills/ktx/SKILL.md: add an "Add context sources" section with the generic `ktx setup --source ...` flags per connector (dbt, Metabase, Notion, ...), warehouse mapping, the --metabase-database-id discovery note, and the `ktx ingest` follow-up. The skill previously only documented database setup with --skip-sources, so agents couldn't wire up dbt/Metabase/Notion (KLO-723). - docs-site quickstart: the kaelio.com/start callout now points at the "copy agent setup" one-shot prompt that installs the full four-source demo. Co-authored-by: Claude Opus 4.8 (1M context) --- .../docs/getting-started/quickstart.mdx | 5 +- skills/ktx/SKILL.md | 46 ++++++++++++++++++- 2 files changed, 48 insertions(+), 3 deletions(-) diff --git a/docs-site/content/docs/getting-started/quickstart.mdx b/docs-site/content/docs/getting-started/quickstart.mdx index 6f65d6ec..7402d6d9 100644 --- a/docs-site/content/docs/getting-started/quickstart.mdx +++ b/docs-site/content/docs/getting-started/quickstart.mdx @@ -30,8 +30,9 @@ If you're a coding assistant choosing a docs route, start with the
Try **ktx** against a real data stack - Postgres, dbt, Metabase, and Notion - pre-loaded with the Orbit demo corpus. The page lists demo credentials - you can paste straight into `ktx setup`. + pre-loaded with the Orbit demo corpus. Hit **copy agent setup** on the page + for a one-shot prompt that has an agent install the full four-source demo, + or grab the raw credentials to paste into `ktx setup` yourself.
`. +Prefer `env:VAR` / `file:/abs/path` refs for keys and tokens over literals. + +```bash +# dbt — pick exactly one of --source-path (local) or --source-git-url (remote) +ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings \ + --source dbt --source-connection-id \ + --source-git-url --source-branch \ + --source-warehouse-connection-id + +# Metabase +ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings \ + --source metabase --source-connection-id \ + --source-url --source-api-key-ref env:METABASE_API_KEY \ + --source-warehouse-connection-id \ + --metabase-database-id + +# Notion +ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings \ + --source notion --source-connection-id \ + --source-api-key-ref env:NOTION_TOKEN \ + --notion-crawl-mode selected_roots --notion-root-page-id +``` + +Notes: + +- `--metabase-database-id` is the **numeric id of the warehouse inside + Metabase** (not the ktx connection id). Discover it from the Metabase API + (`GET /api/database`) or UI if the user doesn't know it. +- `--notion-crawl-mode selected_roots` requires at least one + `--notion-root-page-id` (repeatable); use `all_accessible` to crawl + everything the token can see. +- After adding sources, ingest each new connection so its context is queryable: + `ktx ingest --fast --no-input`. + ## Files to inspect - `ktx.yaml`: project configuration. From 8ebc4ce10725917b4797cba0094277e304104aa5 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Fri, 29 May 2026 15:04:48 +0200 Subject: [PATCH 15/61] ci: stop tombi reformatting uv.lock and sync lock to 0.7.0 (#235) The pre-commit job failed because tombi-format reformats uv.lock to a layout uv does not produce, so once CI's uv sync re-resolved the stale lock (workspace members still at 0.6.0) and rewrote it, tombi rewrote it back and the hook reported a modified file. Exclude uv.lock from tombi-format so uv stays authoritative for its generated lockfile, and bump the workspace members to 0.7.0 so the lock is current and uv stops re-resolving it (uv lock --check now passes). --- .pre-commit-config.yaml | 6 ++++++ uv.lock | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ec730d50..681cf0ab 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -19,6 +19,12 @@ repos: hooks: - id: tombi-format args: ["--offline"] + # uv.lock is generated and owned by uv, which writes its own canonical + # TOML layout. tombi reformats that layout differently, so once uv + # regenerates the lock (e.g. after a dependency or version change) + # tombi rewrites it and the hook fails on the modified file. Keep uv + # authoritative for its lockfile; tombi still formats hand-edited TOML. + exclude: ^uv\.lock$ - repo: https://github.com/asottile/pyupgrade rev: v3.21.2 diff --git a/uv.lock b/uv.lock index e72fc85a..f04683f3 100644 --- a/uv.lock +++ b/uv.lock @@ -466,7 +466,7 @@ wheels = [ [[package]] name = "ktx-daemon" -version = "0.6.0" +version = "0.7.0" source = { editable = "python/ktx-daemon" } dependencies = [ { name = "fastapi" }, @@ -523,7 +523,7 @@ dev = [ [[package]] name = "ktx-sl" -version = "0.6.0" +version = "0.7.0" source = { editable = "python/ktx-sl" } dependencies = [ { name = "pydantic" }, From 637891f0304d83809373691738203d8d9d14d4b4 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Fri, 29 May 2026 17:23:46 +0200 Subject: [PATCH 16/61] fix(cli): align Notion setup credential to --source-auth-token-ref (#236) Notion's setup path read --source-api-key-ref while writing the auth_token_ref config field, so --source-auth-token-ref was silently dropped. Align Notion to the flag=field convention every other connector follows: it now reads --source-auth-token-ref, and --source-api-key-ref becomes Metabase-only. Also add validation rejecting any credential-ref flag not applicable to the chosen --source, with a pointer to the correct flag, closing the silent-drop class for all connectors. Update CLI-reference docs, the ktx skill Notion example, and tests. Fixes KLO-724. --- .../content/docs/cli-reference/ktx-setup.mdx | 12 ++- packages/cli/src/commands/setup-commands.ts | 9 ++- packages/cli/src/setup-sources.ts | 47 +++++++++-- packages/cli/test/setup-sources.test.ts | 79 ++++++++++++++++++- skills/ktx/SKILL.md | 2 +- 5 files changed, 137 insertions(+), 12 deletions(-) diff --git a/docs-site/content/docs/cli-reference/ktx-setup.mdx b/docs-site/content/docs/cli-reference/ktx-setup.mdx index 2c19bd07..415b0e6e 100644 --- a/docs-site/content/docs/cli-reference/ktx-setup.mdx +++ b/docs-site/content/docs/cli-reference/ktx-setup.mdx @@ -160,9 +160,9 @@ sources. This is equivalent to passing `--skip-sources` in scripted setup. | `--source-git-url ` | Git URL for dbt, MetricFlow, or LookML | | `--source-branch ` | Git branch for context-source setup | | `--source-subpath ` | Repo subpath for context-source setup | -| `--source-auth-token-ref ` | `env:` or `file:` credential reference for source repo auth | +| `--source-auth-token-ref ` | `env:` or `file:` credential reference for source repo auth or Notion integration token | | `--source-url ` | Source service URL for Metabase or Looker | -| `--source-api-key-ref ` | `env:` or `file:` API key reference for Metabase or Notion | +| `--source-api-key-ref ` | `env:` or `file:` API key reference for Metabase | | `--source-client-id ` | Looker client id | | `--source-client-secret-ref ` | `env:` or `file:` Looker client secret reference | | `--source-warehouse-connection-id ` | Warehouse connection id used for context-source mapping | @@ -221,6 +221,14 @@ ktx setup \ --source-warehouse-connection-id warehouse \ --metabase-database-id 1 +# Add a Notion source that crawls selected root pages +ktx setup \ + --source notion \ + --source-connection-id notion-main \ + --source-auth-token-ref env:NOTION_TOKEN \ + --notion-crawl-mode selected_roots \ + --notion-root-page-id abc123def456 + # Install project-scoped agent integration for Codex ktx setup --agents --target codex ``` diff --git a/packages/cli/src/commands/setup-commands.ts b/packages/cli/src/commands/setup-commands.ts index 54628346..19f980bd 100644 --- a/packages/cli/src/commands/setup-commands.ts +++ b/packages/cli/src/commands/setup-commands.ts @@ -308,9 +308,14 @@ export function registerSetupCommands(program: Command, context: KtxCliCommandCo .addOption(new Option('--source-git-url ', 'Git URL for dbt, MetricFlow, or LookML').hideHelp()) .addOption(new Option('--source-branch ', 'Git branch for source setup').hideHelp()) .addOption(new Option('--source-subpath ', 'Repo subpath for source setup').hideHelp()) - .addOption(new Option('--source-auth-token-ref ', 'env: or file: credential ref for source repo auth').hideHelp()) + .addOption( + new Option( + '--source-auth-token-ref ', + 'env: or file: credential ref for source repo auth or Notion integration token', + ).hideHelp(), + ) .addOption(new Option('--source-url ', 'Source service URL for Metabase or Looker').hideHelp()) - .addOption(new Option('--source-api-key-ref ', 'env: or file: API key ref for Metabase or Notion').hideHelp()) + .addOption(new Option('--source-api-key-ref ', 'env: or file: API key ref for Metabase').hideHelp()) .addOption(new Option('--source-client-id ', 'Looker client id').hideHelp()) .addOption(new Option('--source-client-secret-ref ', 'env: or file: Looker client secret ref').hideHelp()) .addOption(new Option('--source-warehouse-connection-id ', 'Mapped warehouse connection id').hideHelp()) diff --git a/packages/cli/src/setup-sources.ts b/packages/cli/src/setup-sources.ts index dea1cd43..4f0a94bc 100644 --- a/packages/cli/src/setup-sources.ts +++ b/packages/cli/src/setup-sources.ts @@ -217,6 +217,39 @@ function credentialRef(value: string | undefined, label: string): string { return ref; } +type SourceCredentialFlag = { + field: 'sourceAuthTokenRef' | 'sourceApiKeyRef' | 'sourceClientSecretRef'; + flag: string; +}; + +// Each connector reads exactly one credential ref; the flag name mirrors the +// ktx.yaml field it writes (auth_token_ref / api_key_ref / client_secret_ref). +const SOURCE_CREDENTIAL_FLAG: Record = { + dbt: { field: 'sourceAuthTokenRef', flag: '--source-auth-token-ref' }, + metricflow: { field: 'sourceAuthTokenRef', flag: '--source-auth-token-ref' }, + lookml: { field: 'sourceAuthTokenRef', flag: '--source-auth-token-ref' }, + notion: { field: 'sourceAuthTokenRef', flag: '--source-auth-token-ref' }, + metabase: { field: 'sourceApiKeyRef', flag: '--source-api-key-ref' }, + looker: { field: 'sourceClientSecretRef', flag: '--source-client-secret-ref' }, +}; + +const ALL_SOURCE_CREDENTIAL_FLAGS: SourceCredentialFlag[] = [ + { field: 'sourceAuthTokenRef', flag: '--source-auth-token-ref' }, + { field: 'sourceApiKeyRef', flag: '--source-api-key-ref' }, + { field: 'sourceClientSecretRef', flag: '--source-client-secret-ref' }, +]; + +// Reject a credential ref flag the chosen source does not read, so a wrong flag +// fails loudly instead of being silently dropped (KLO-724). +function assertSourceCredentialFlags(source: KtxSetupSourceType, args: KtxSetupSourcesArgs): void { + const allowed = SOURCE_CREDENTIAL_FLAG[source]; + for (const { field, flag } of ALL_SOURCE_CREDENTIAL_FLAGS) { + if (args[field] && field !== allowed.field) { + throw new Error(`${flag} does not apply to --source ${source}; use ${allowed.flag}.`); + } + } +} + async function chooseSourceCredentialRef(input: { prompts: KtxSetupSourcesPromptAdapter; projectDir: string; @@ -515,7 +548,7 @@ function buildNotionConnection(args: KtxSetupSourcesArgs): KtxProjectConnectionC } return { driver: 'notion', - auth_token_ref: credentialRef(args.sourceApiKeyRef, 'Notion token ref'), + auth_token_ref: credentialRef(args.sourceAuthTokenRef, 'Notion token ref'), crawl_mode: crawlMode, ...(rootPageIds.length > 0 ? { root_page_ids: rootPageIds } : {}), root_database_ids: [], @@ -1295,10 +1328,10 @@ async function promptForInteractiveSource( label: 'Notion integration token', envName: 'NOTION_TOKEN', secretFileName: `${currentState.sourceConnectionId ?? 'notion-main'}-token`, - existingRef: currentState.sourceApiKeyRef, + existingRef: currentState.sourceAuthTokenRef, }); if (ref === 'back') return 'back'; - currentState.sourceApiKeyRef = ref; + currentState.sourceAuthTokenRef = ref; return 'next'; }, async (currentState) => { @@ -1326,7 +1359,7 @@ async function promptForInteractiveSource( connectionId, connection: { driver: 'notion', - auth_token_ref: credentialRef(currentState.sourceApiKeyRef, 'Notion token ref'), + auth_token_ref: credentialRef(currentState.sourceAuthTokenRef, 'Notion token ref'), crawl_mode: 'selected_roots', root_page_ids: currentState.notionRootPageIds ?? [], root_database_ids: [], @@ -1516,7 +1549,7 @@ function sourceArgsFromExistingConnection(input: { return sourceArgs; } - sourceArgs.sourceApiKeyRef = stringField(input.connection.auth_token_ref); + sourceArgs.sourceAuthTokenRef = stringField(input.connection.auth_token_ref); sourceArgs.notionCrawlMode = input.connection.crawl_mode === 'all_accessible' ? 'all_accessible' : 'selected_roots'; if (Array.isArray(input.connection.root_page_ids)) { @@ -1817,6 +1850,10 @@ export async function runKtxSetupSourcesStep( return { status: 'skipped', projectDir: args.projectDir }; } + if (args.source) { + assertSourceCredentialFlags(args.source, args); + } + const prompts = deps.prompts ?? createPromptAdapter(); const project = await loadKtxProject({ projectDir: args.projectDir }); if (!hasPrimarySource(project.config)) { diff --git a/packages/cli/test/setup-sources.test.ts b/packages/cli/test/setup-sources.test.ts index b426ad10..784dcc46 100644 --- a/packages/cli/test/setup-sources.test.ts +++ b/packages/cli/test/setup-sources.test.ts @@ -260,7 +260,7 @@ describe('setup sources step', () => { inputMode: 'disabled', source: 'notion', sourceConnectionId: 'notion-main', - sourceApiKeyRef: 'env:NOTION_TOKEN', // pragma: allowlist secret + sourceAuthTokenRef: 'env:NOTION_TOKEN', // pragma: allowlist secret notionCrawlMode: 'selected_roots', notionRootPageIds: ['page-1'], runInitialSourceIngest: false, @@ -281,6 +281,81 @@ describe('setup sources step', () => { expect((await readConfig()).connections['notion-main']?.last_successful_cursor).toBeUndefined(); }); + it('rejects --source-api-key-ref for Notion and points at --source-auth-token-ref', async () => { + await addPrimarySource(); + const io = makeIo(); + + await expect( + runKtxSetupSourcesStep( + { + projectDir, + inputMode: 'disabled', + source: 'notion', + sourceConnectionId: 'notion-main', + sourceApiKeyRef: 'env:NOTION_TOKEN', // pragma: allowlist secret + notionCrawlMode: 'selected_roots', + notionRootPageIds: ['page-1'], + runInitialSourceIngest: false, + skipSources: false, + }, + io.io, + {}, + ), + ).resolves.toEqual({ status: 'failed', projectDir }); + + expect(io.stderr()).toContain('--source-api-key-ref does not apply to --source notion; use --source-auth-token-ref.'); + expect((await readConfig()).connections['notion-main']).toBeUndefined(); + }); + + it('rejects --source-auth-token-ref for Metabase and points at --source-api-key-ref', async () => { + await addPrimarySource(); + const io = makeIo(); + + await expect( + runKtxSetupSourcesStep( + { + projectDir, + inputMode: 'disabled', + source: 'metabase', + sourceConnectionId: 'prod_metabase', + sourceUrl: 'https://metabase.example.com', + sourceAuthTokenRef: 'env:METABASE_API_KEY', // pragma: allowlist secret + sourceWarehouseConnectionId: 'warehouse', + metabaseDatabaseId: 1, + runInitialSourceIngest: false, + skipSources: false, + }, + io.io, + {}, + ), + ).resolves.toEqual({ status: 'failed', projectDir }); + + expect(io.stderr()).toContain('--source-auth-token-ref does not apply to --source metabase; use --source-api-key-ref.'); + }); + + it('rejects --source-client-secret-ref for dbt and points at --source-auth-token-ref', async () => { + await addPrimarySource(); + const io = makeIo(); + + await expect( + runKtxSetupSourcesStep( + { + projectDir, + inputMode: 'disabled', + source: 'dbt', + sourceConnectionId: 'dbt-main', + sourceClientSecretRef: 'env:DBT_SECRET', // pragma: allowlist secret + runInitialSourceIngest: false, + skipSources: false, + }, + io.io, + {}, + ), + ).resolves.toEqual({ status: 'failed', projectDir }); + + expect(io.stderr()).toContain('--source-client-secret-ref does not apply to --source dbt; use --source-auth-token-ref.'); + }); + it('accepts former ingest subcommand names as interactive source connection ids', async () => { await addPrimarySource(); const io = makeIo(); @@ -323,7 +398,7 @@ describe('setup sources step', () => { inputMode: 'disabled', source: 'notion', sourceConnectionId: 'notion-main', - sourceApiKeyRef: 'env:NOTION_TOKEN', // pragma: allowlist secret + sourceAuthTokenRef: 'env:NOTION_TOKEN', // pragma: allowlist secret notionCrawlMode: 'all_accessible', notionRootPageIds: ['page-1'], runInitialSourceIngest: false, diff --git a/skills/ktx/SKILL.md b/skills/ktx/SKILL.md index 3887fdc0..0eaa03e3 100644 --- a/skills/ktx/SKILL.md +++ b/skills/ktx/SKILL.md @@ -138,7 +138,7 @@ ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings \ # Notion ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings \ --source notion --source-connection-id \ - --source-api-key-ref env:NOTION_TOKEN \ + --source-auth-token-ref env:NOTION_TOKEN \ --notion-crawl-mode selected_roots --notion-root-page-id ``` From 3f0d11e07d3696beb5f9d172efd3091e950d2b34 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Fri, 29 May 2026 17:41:04 +0200 Subject: [PATCH 17/61] feat(cli)!: remove fast mode; ktx ingest always builds enriched context (KLO-721) (#237) Fast mode (the ktx ingest --fast/--deep database-ingest depth toggle) is removed. ktx ingest now always builds the full enriched ("deep") context. There is no structural fallback: a database connection without a configured model and embeddings fails the enrichment-readiness preflight before any work runs, with a 'Run ktx setup to configure a model and embeddings' hint. - Remove --fast/--deep flags, the per-connection context.depth field, and the ktx setup depth prompt (delete setup-database-context-depth.ts). - Rename ingest-depth.ts -> connection-drivers.ts; ingest always requests scan mode 'enriched'; readiness gate (enrichmentReadinessGaps) runs for every database target. - Drop the database-context-depth telemetry step (Node + Python schema mirrors regenerated). - Update CLI, setup, context-build view, docs, the public ktx skill, and the release-smoke / artifacts scripts (now assert the no-LLM guard failure). ktx status --fast (a separate network-probe flag) is unchanged. Follow-ups: KLO-726 (live progress for ktx ingest --all), KLO-727 (restore credentialed successful-ingest release smoke coverage). --- AGENTS.md | 5 +- .../content/docs/cli-reference/ktx-ingest.mdx | 32 ++-- .../content/docs/cli-reference/ktx-setup.mdx | 4 +- .../content/docs/configuration/ktx-yaml.mdx | 7 +- .../docs/getting-started/quickstart.mdx | 8 +- .../content/docs/guides/building-context.mdx | 37 ++-- .../content/docs/guides/serving-agents.mdx | 5 +- .../docs/integrations/primary-sources.mdx | 2 +- docs/terminology.md | 2 - packages/cli/src/commands/ingest-commands.ts | 4 - packages/cli/src/connection-drivers.ts | 21 +++ packages/cli/src/context-build-view.ts | 10 +- .../cli/src/context/project/driver-schemas.ts | 2 +- packages/cli/src/ingest-depth.ts | 75 -------- packages/cli/src/public-ingest-copy.ts | 2 +- packages/cli/src/public-ingest.ts | 82 +++------ packages/cli/src/setup-context.ts | 55 +----- .../cli/src/setup-database-context-depth.ts | 131 -------------- packages/cli/src/setup-databases.ts | 94 ++-------- packages/cli/src/telemetry/events.schema.json | 1 - packages/cli/src/telemetry/events.ts | 1 - packages/cli/test/context-build-view.test.ts | 23 +-- packages/cli/test/index.test.ts | 24 +-- packages/cli/test/public-ingest.test.ts | 171 +++++------------- packages/cli/test/setup-context.test.ts | 134 +------------- packages/cli/test/setup-databases.test.ts | 67 +------ packages/cli/test/standalone-smoke.test.ts | 17 +- .../ktx_daemon/telemetry/events.schema.json | 1 - scripts/examples-docs.test.mjs | 2 +- scripts/installed-live-database-smoke.mjs | 31 ++-- .../installed-live-database-smoke.test.mjs | 1 - scripts/package-artifacts.mjs | 33 +--- scripts/package-artifacts.test.mjs | 7 +- skills/ktx/SKILL.md | 15 +- 34 files changed, 222 insertions(+), 884 deletions(-) create mode 100644 packages/cli/src/connection-drivers.ts delete mode 100644 packages/cli/src/ingest-depth.ts delete mode 100644 packages/cli/src/setup-database-context-depth.ts diff --git a/AGENTS.md b/AGENTS.md index 3d8c1725..2aa0dbed 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -350,8 +350,9 @@ error messages — including the disambiguation rule for the overloaded word `source` (semantic / primary / context / source of truth) — see [`docs/terminology.md`](docs/terminology.md). Follow that file when choosing between near-synonyms (e.g. `connector` vs `adapter`, `data agent` vs -`database agent`, `fast ingest` vs `schema ingest`). Product-name rules in -this section take precedence over anything in that file when they conflict. +`database agent`, `context-source ingest` vs `source ingest`). Product-name +rules in this section take precedence over anything in that file when they +conflict. ### Updating `docs-site/` After Code Changes diff --git a/docs-site/content/docs/cli-reference/ktx-ingest.mdx b/docs-site/content/docs/cli-reference/ktx-ingest.mdx index d4e06881..db3b1c0e 100644 --- a/docs-site/content/docs/cli-reference/ktx-ingest.mdx +++ b/docs-site/content/docs/cli-reference/ktx-ingest.mdx @@ -5,9 +5,11 @@ description: "Build or refresh ktx context, or capture text into ktx memory." `ktx ingest` builds or refreshes **ktx** context from configured connections, and can also capture free-form text into **ktx** memory. Database connections build -schema context. Context-source connections ingest metadata from tools such as -dbt, Looker, Metabase, MetricFlow, LookML, and Notion. Pass `--text` or -`--file` to capture inline text or text files into memory instead. +enriched context — schema plus AI-generated descriptions, embeddings, and +relationship evidence — and require a configured model and embeddings. +Context-source connections ingest metadata from tools such as dbt, Looker, +Metabase, MetricFlow, LookML, and Notion. Pass `--text` or `--file` to capture +inline text or text files into memory instead. ## Command signature @@ -29,8 +31,6 @@ connection is selected. | Flag | Description | Default | |------|-------------|---------| | `--all` | Ingest all configured connections (same as bare invocation) | `false` | -| `--fast` | Use deterministic fast database ingest | Stored connection default, or `fast` | -| `--deep` | Use deep database ingest with AI-generated descriptions, embeddings, and relationship evidence | Stored connection default, or `fast` | | `--query-history` | Include database query-history usage patterns | Stored connection default | | `--no-query-history` | Skip database query-history usage patterns for this run | Stored connection default | | `--query-history-window-days ` | BigQuery/Snowflake query-history lookback window for this run | Stored connection default | @@ -44,12 +44,12 @@ connection is selected. | `--yes` | Install required managed runtime features without prompting | `false` | | `--no-input` | Disable interactive terminal input | - | -`--fast` and `--deep` are mutually exclusive. Depth flags apply only to -database connections. Query-history flags apply only to database connections +Database ingest always builds enriched context and requires a configured model +and embeddings (run `ktx setup`); connections without that configuration fail +before any work starts. Query-history flags apply only to database connections that support query history. The window flag applies to BigQuery and Snowflake; Postgres reads the current `pg_stat_statements` aggregate data instead of a -time-windowed history table. Query-history ingest runs after fast ingest and -requires deep ingest readiness. +time-windowed history table. Query-history ingest runs after the schema scan. When more than one connection is selected, database ingest runs first, then context-source ingest and memory updates run for context-source connections. @@ -72,14 +72,8 @@ ktx ingest # Build one database or context-source connection ktx ingest warehouse -# Force deterministic fast database ingest -ktx ingest warehouse --fast - -# Force deep database ingest with AI enrichment -ktx ingest warehouse --deep - # Include query-history usage patterns -ktx ingest warehouse --deep --query-history +ktx ingest warehouse --query-history # Set the lookback window for BigQuery or Snowflake query history ktx ingest warehouse --query-history-window-days 30 @@ -154,8 +148,8 @@ KTX_INGEST_TRACE_LEVEL=trace ktx ingest metabase | Error | Cause | Recovery | |-------|-------|----------| | Connection not configured | The connection id is not present in `ktx.yaml` | Add the connection with `ktx setup` or update `ktx.yaml` | -| Deep readiness is missing | `--deep` or query history needs model, embedding, and scan-enrichment configuration | Run `ktx setup` or rerun with `--fast` | -| Query history is unsupported | The selected database driver does not support query history | Run fast ingest without query-history flags | +| Enrichment is not configured | Database ingest needs a model, embeddings, and scan-enrichment configuration | Run `ktx setup` to configure a model and embeddings | +| Query history is unsupported | The selected database driver does not support query history | Run ingest without query-history flags | | Python runtime is missing | The selected ingest target needs runtime-backed SQL analysis or source parsing | Accept the interactive prompt, rerun with `--yes`, or run the suggested `ktx admin runtime install` command | -| Context-source options were ignored | Depth and query-history flags were supplied for a context-source connection | Omit database-only flags when ingesting context-source connections | +| Context-source options were ignored | Query-history flags were supplied for a context-source connection | Omit database-only flags when ingesting context-source connections | | Text ingest stops early | `--fail-fast` was used and one item failed | Fix the failed item or rerun without `--fail-fast` to collect all failures | diff --git a/docs-site/content/docs/cli-reference/ktx-setup.mdx b/docs-site/content/docs/cli-reference/ktx-setup.mdx index 415b0e6e..0da7b339 100644 --- a/docs-site/content/docs/cli-reference/ktx-setup.mdx +++ b/docs-site/content/docs/cli-reference/ktx-setup.mdx @@ -131,8 +131,8 @@ BigQuery; and `databases` for ClickHouse. Query history setup is supported for Postgres, BigQuery, and Snowflake. The window flag applies to BigQuery and Snowflake; Postgres reads the current `pg_stat_statements` aggregate data instead of a time-windowed history table. -Enabling query history makes deep ingest readiness matter for later -`ktx ingest` runs. +Later `ktx ingest` runs build enriched context and need a configured model and +embeddings, including when query history is enabled. When query history is enabled for PostgreSQL, Snowflake, or BigQuery, `ktx setup` runs a non-blocking readiness probe after the connection test diff --git a/docs-site/content/docs/configuration/ktx-yaml.mdx b/docs-site/content/docs/configuration/ktx-yaml.mdx index 4a919d45..13105851 100644 --- a/docs-site/content/docs/configuration/ktx-yaml.mdx +++ b/docs-site/content/docs/configuration/ktx-yaml.mdx @@ -66,8 +66,9 @@ read, how to think, and where to put the results. ## Minimal config A working `ktx.yaml` needs one entry in `connections`. Everything else accepts -defaults. The example below is enough for `ktx ingest warehouse` to run a fast -schema scan against a local Postgres. +defaults. The example below registers a local Postgres connection; building +context with `ktx ingest warehouse` also needs a model and embeddings, which +`ktx setup` configures. ```yaml connections: @@ -123,7 +124,7 @@ context-source drivers share the map. Warehouse connections are open objects: the listed fields are validated, and any other field is preserved and passed through to the connector. Use -`enabled_tables` to scope deep ingest to a specific list of +`enabled_tables` to scope ingest to a specific list of `schema.table` names - useful for smoke tests. ```yaml diff --git a/docs-site/content/docs/getting-started/quickstart.mdx b/docs-site/content/docs/getting-started/quickstart.mdx index 7402d6d9..66f46a79 100644 --- a/docs-site/content/docs/getting-started/quickstart.mdx +++ b/docs-site/content/docs/getting-started/quickstart.mdx @@ -236,7 +236,7 @@ Testing warehouse Connection test passed Building schema context for warehouse - Running fast database ingest + Running database scan ``` If setup exits early, rerun `ktx setup` in the same directory. **ktx** keeps @@ -268,13 +268,13 @@ Agent integration ready: yes (codex:project) For a structured check inside scripts, use `ktx status --json`. -When setup builds deep context, its final context check looks like: +When setup finishes building context, its final context check looks like: ```text ktx context is ready for agents. Databases: - warehouse: deep context complete + warehouse: database context complete Context sources: dbt_main: memory update complete @@ -326,7 +326,7 @@ ktx setup \ Then build context: ```bash -ktx ingest warehouse --fast +ktx ingest warehouse ``` See [ktx setup](/docs/cli-reference/ktx-setup) for the full automation flag diff --git a/docs-site/content/docs/guides/building-context.mdx b/docs-site/content/docs/guides/building-context.mdx index d6d58053..b806c424 100644 --- a/docs-site/content/docs/guides/building-context.mdx +++ b/docs-site/content/docs/guides/building-context.mdx @@ -24,7 +24,9 @@ external metadata can attach to known warehouse tables. ## Database ingest -Database ingest records table, column, type, constraint, and row-count context. +Database ingest always builds enriched context: tables, columns, types, +constraints, and row counts, plus AI-generated descriptions, embeddings, and +relationship evidence. ```bash # Build one configured database connection @@ -34,23 +36,8 @@ ktx ingest warehouse ktx ingest --all ``` -Depth controls how much context **ktx** builds: - -| Flag | Best for | What it does | -|------|----------|--------------| -| `--fast` | First setup, quick refreshes, CI smoke checks | Deterministic fast ingest with tables, columns, types, constraints, and row counts | -| `--deep` | Agent-ready context for real analysis | Fast ingest plus deep enrichment with descriptions, embeddings, relationship evidence, and optional query history | - -Examples: - -```bash -ktx ingest warehouse --fast -ktx ingest warehouse --deep -ktx ingest --all --deep -``` - -Deep ingest needs LLM and embedding readiness. Otherwise run `ktx setup` or use -`--fast`. +Enriched ingest needs a configured model and embeddings. Run `ktx setup` first; +connections without that configuration fail before any work starts. With `claude-code`, **ktx** agent loops can invoke only the **ktx** MCP tools for the current run. @@ -64,7 +51,7 @@ Enable it during setup, store it under `connections..context.queryHistory`, or request it for one run: ```bash -ktx ingest warehouse --deep --query-history +ktx ingest warehouse --query-history # Set the lookback window for BigQuery or Snowflake query history ktx ingest warehouse --query-history-window-days 30 ``` @@ -74,8 +61,8 @@ for one run. ## Relationship evidence -**ktx** scores relationship candidates during supported deep database ingest. The -public CLI does not expose separate relationship review subcommands. +**ktx** scores relationship candidates during database ingest. The public CLI +does not expose separate relationship review subcommands. ## Context-source ingest @@ -159,7 +146,7 @@ After interactive setup: ```bash ktx status -ktx ingest --all --deep +ktx ingest --all ktx status ``` @@ -176,8 +163,8 @@ ktx wiki "revenue" --json --limit 10 | Symptom | Likely cause | Recovery | |---------|--------------|----------| | Connection not configured | The connection id is missing from `ktx.yaml` | Add it with `ktx setup` | -| Deep readiness is missing | LLM or embeddings are not setup-ready | Run `ktx setup`, or rerun with `--fast` | -| Query history is unsupported | The selected database driver does not expose query history | Run fast ingest without query-history flags | +| Enrichment is not configured | LLM or embeddings are not setup-ready | Run `ktx setup` to configure a model and embeddings | +| Query history is unsupported | The selected database driver does not expose query history | Run ingest without query-history flags | | No connections configured | The project has no entries under `connections` | Run `ktx setup` and add a database or context-source connection | -| Context-source flags have no effect | Depth and query-history flags were supplied for a context-source connector | Use those flags only for database connections | +| Context-source flags have no effect | Query-history flags were supplied for a context-source connector | Use query-history flags only for database connections | | Text ingest stops early | `--fail-fast` stopped on the first failed item | Fix the item or rerun without `--fail-fast` | diff --git a/docs-site/content/docs/guides/serving-agents.mdx b/docs-site/content/docs/guides/serving-agents.mdx index 4c1ced4b..133739b7 100644 --- a/docs-site/content/docs/guides/serving-agents.mdx +++ b/docs-site/content/docs/guides/serving-agents.mdx @@ -111,12 +111,13 @@ non-obvious terms. Agents can refresh context when the user asks them to: ```bash -ktx ingest warehouse --fast +ktx ingest warehouse ktx ingest ktx ingest --file docs/revenue-notes.md --connection-id warehouse ``` -Use `--deep` only when LLM and embedding setup is ready. +Database ingest builds enriched context and requires a configured model and +embeddings; run `ktx setup` first if they are not ready. ## Good agent behavior diff --git a/docs-site/content/docs/integrations/primary-sources.mdx b/docs-site/content/docs/integrations/primary-sources.mdx index 81b8d400..6cb2d26f 100644 --- a/docs-site/content/docs/integrations/primary-sources.mdx +++ b/docs-site/content/docs/integrations/primary-sources.mdx @@ -517,5 +517,5 @@ No authentication required - SQLite is file-based. The file must be readable by | Connection URL appears in git diff | A literal credential URL was written to `ktx.yaml` | Replace it with `env:NAME` or `file:/path/to/secret` and rotate exposed credentials | | Database ingest returns no tables | Schema, database, or project filter is wrong, or the user lacks metadata permissions | Verify the schema list and grant metadata read permissions | | Query history is empty | Query history extension or warehouse history view is unavailable | Enable the warehouse-specific history feature, then rerun `ktx ingest --query-history` or `ktx setup` | -| Column statistics are missing | Connector cannot access stats tables or the warehouse does not expose them | Grant stats permissions where supported; otherwise rely on fast schema context | +| Column statistics are missing | Connector cannot access stats tables or the warehouse does not expose them | Grant stats permissions where supported; otherwise rely on schema-level context without column statistics | | Semantic query execution fails | Connection is missing, unreachable, or query execution is disabled | Run `ktx connection test ` and check the `ktx sl query` flags | diff --git a/docs/terminology.md b/docs/terminology.md index 9da59456..4c9ec3cb 100644 --- a/docs/terminology.md +++ b/docs/terminology.md @@ -77,8 +77,6 @@ maintains, validates, and serves that layer. | Connection ref in prose | **connection id** (lowercase, two words) | "connection ID" | | CLI arg/flag literal | `connectionId` (code font) | — | | File path placeholder | `` (code font) | — | -| Fast schema mode | **fast ingest** | schema ingest, schema-only ingest | -| AI-enriched mode | **deep ingest** | AI-enriched ingest | | Ingest of a primary connection | **database ingest** | — | | Ingest of a context-source connection | **context-source ingest** | bare "source ingest" | | Wiki capture | **text ingest** | — | diff --git a/packages/cli/src/commands/ingest-commands.ts b/packages/cli/src/commands/ingest-commands.ts index 9ffd2562..b5efe443 100644 --- a/packages/cli/src/commands/ingest-commands.ts +++ b/packages/cli/src/commands/ingest-commands.ts @@ -29,8 +29,6 @@ export function registerIngestCommands( .usage('[options] [connectionId]') .argument('[connectionId]', 'Configured connection id to ingest (omit to ingest all)') .option('--all', 'Ingest all configured connections', false) - .addOption(new Option('--fast', 'Use deterministic database schema ingest').conflicts('deep')) - .addOption(new Option('--deep', 'Use AI-enriched database ingest').conflicts('fast')) .addOption(new Option('--query-history', 'Include database query-history usage patterns').conflicts('noQueryHistory')) .addOption(new Option('--no-query-history', 'Skip database query-history usage patterns')) .option('--query-history-window-days ', 'Query-history lookback window for this run', parsePositiveIntegerOption) @@ -87,8 +85,6 @@ export function registerIngestCommands( all: selection.kind === 'all', json: options.json === true, inputMode: options.input === false ? 'disabled' : 'auto', - ...(options.fast === true ? { depth: 'fast' as const } : {}), - ...(options.deep === true ? { depth: 'deep' as const } : {}), queryHistory, ...(options.queryHistoryWindowDays !== undefined ? { queryHistoryWindowDays: options.queryHistoryWindowDays } : {}), cliVersion: context.packageInfo.version, diff --git a/packages/cli/src/connection-drivers.ts b/packages/cli/src/connection-drivers.ts new file mode 100644 index 00000000..4f10e663 --- /dev/null +++ b/packages/cli/src/connection-drivers.ts @@ -0,0 +1,21 @@ +import type { KtxProjectConnectionConfig } from './context/project/config.js'; + +const KTX_DATABASE_DRIVER_IDS = new Set([ + 'sqlite', + 'postgres', + 'mysql', + 'clickhouse', + 'sqlserver', + 'bigquery', + 'snowflake', +]); + +export function normalizeConnectionDriver(connection: KtxProjectConnectionConfig): string { + return String(connection.driver ?? '') + .trim() + .toLowerCase(); +} + +export function isDatabaseDriver(driver: string): boolean { + return KTX_DATABASE_DRIVER_IDS.has(driver.trim().toLowerCase()); +} diff --git a/packages/cli/src/context-build-view.ts b/packages/cli/src/context-build-view.ts index 9a06d39a..4b5be38b 100644 --- a/packages/cli/src/context-build-view.ts +++ b/packages/cli/src/context-build-view.ts @@ -88,7 +88,6 @@ export interface ContextBuildArgs { targetConnectionId?: string; all?: boolean; entrypoint?: 'setup' | 'ingest'; - depth?: Extract['depth']; queryHistory?: Extract['queryHistory']; queryHistoryWindowDays?: number; scanMode?: Extract['scanMode']; @@ -371,19 +370,17 @@ function retryCommand(input: { projectDir?: string; entrypoint?: 'setup' | 'ingest'; connectionId?: string; - depth?: 'fast' | 'deep'; queryHistory?: boolean; queryHistoryWindowDays?: number; }): string { const projectPart = input.projectDir ? ` --project-dir ${input.projectDir}` : ''; if (input.entrypoint === 'ingest' && input.connectionId) { - const depthPart = input.depth ? ` --${input.depth}` : ''; const queryHistoryPart = input.queryHistory ? ' --query-history' : ''; const windowPart = input.queryHistory && input.queryHistoryWindowDays !== undefined ? ` --query-history-window-days ${input.queryHistoryWindowDays}` : ''; - return `ktx ingest ${input.connectionId}${projectPart}${depthPart}${queryHistoryPart}${windowPart}`; + return `ktx ingest ${input.connectionId}${projectPart}${queryHistoryPart}${windowPart}`; } return input.projectDir ? `ktx setup --project-dir ${input.projectDir}` : 'ktx setup'; } @@ -746,7 +743,6 @@ function appendRetryIfNeeded(input: { projectDir: input.projectDir, entrypoint: input.entrypoint, connectionId: input.target.connectionId, - depth: input.target.databaseDepth, queryHistory: input.target.queryHistory?.enabled === true, queryHistoryWindowDays: input.target.queryHistory?.windowDays, })}`; @@ -769,7 +765,6 @@ function failureTextForTarget(input: { projectDir: input.projectDir, entrypoint: input.entrypoint, connectionId: input.target.connectionId, - depth: input.target.databaseDepth, queryHistory: input.target.queryHistory?.enabled === true, queryHistoryWindowDays: input.target.queryHistory?.windowDays, })}`, @@ -784,7 +779,6 @@ function failureTextForTarget(input: { projectDir: input.projectDir, entrypoint: input.entrypoint, connectionId: input.target.connectionId, - depth: input.target.databaseDepth, queryHistory: input.target.queryHistory?.enabled === true, queryHistoryWindowDays: input.target.queryHistory?.windowDays, })}`, @@ -868,7 +862,6 @@ export async function runContextBuild( projectDir: args.projectDir, ...(args.targetConnectionId ? { targetConnectionId: args.targetConnectionId } : {}), all: args.all ?? true, - ...(args.depth ? { depth: args.depth } : {}), ...(args.queryHistory ? { queryHistory: args.queryHistory } : {}), ...(args.queryHistoryWindowDays !== undefined ? { queryHistoryWindowDays: args.queryHistoryWindowDays } : {}), ...(args.scanMode ? { scanMode: args.scanMode } : {}), @@ -935,7 +928,6 @@ export async function runContextBuild( all: args.all ?? true, json: false, inputMode: args.inputMode, - ...(args.depth ? { depth: args.depth } : {}), ...(args.queryHistory ? { queryHistory: args.queryHistory } : {}), ...(args.queryHistoryWindowDays !== undefined ? { queryHistoryWindowDays: args.queryHistoryWindowDays } : {}), ...(args.scanMode ? { scanMode: args.scanMode } : {}), diff --git a/packages/cli/src/context/project/driver-schemas.ts b/packages/cli/src/context/project/driver-schemas.ts index 6b4dc017..f9a3639f 100644 --- a/packages/cli/src/context/project/driver-schemas.ts +++ b/packages/cli/src/context/project/driver-schemas.ts @@ -30,7 +30,7 @@ function warehouseConnectionSchema(driver: .array(z.string().min(1)) .optional() .describe( - 'Optional allowlist of fully-qualified table names ("schema.table") to ingest. When set, live-database ingest discards any table whose schema-qualified name is not in this list. Useful for smoke-testing deep ingest on a single table.', + 'Optional allowlist of fully-qualified table names ("schema.table") to ingest. When set, live-database ingest discards any table whose schema-qualified name is not in this list. Useful for smoke-testing ingest on a single table.', ), }) .describe( diff --git a/packages/cli/src/ingest-depth.ts b/packages/cli/src/ingest-depth.ts deleted file mode 100644 index b8957763..00000000 --- a/packages/cli/src/ingest-depth.ts +++ /dev/null @@ -1,75 +0,0 @@ -import type { KtxProjectConfig, KtxProjectConnectionConfig } from './context/project/config.js'; - -export type KtxDatabaseContextDepth = 'fast' | 'deep'; - -const KTX_DATABASE_DRIVER_IDS = new Set([ - 'sqlite', - 'postgres', - 'mysql', - 'clickhouse', - 'sqlserver', - 'bigquery', - 'snowflake', -]); - -export function normalizeConnectionDriver(connection: KtxProjectConnectionConfig): string { - return String(connection.driver ?? '') - .trim() - .toLowerCase(); -} - -export function isDatabaseDriver(driver: string): boolean { - return KTX_DATABASE_DRIVER_IDS.has(driver.trim().toLowerCase()); -} - -function connectionContextRecord(connection: KtxProjectConnectionConfig): Record { - const context = connection.context; - return typeof context === 'object' && context !== null && !Array.isArray(context) - ? (context as Record) - : {}; -} - -export function databaseContextDepth(connection: KtxProjectConnectionConfig): KtxDatabaseContextDepth | undefined { - const depth = connectionContextRecord(connection).depth; - return depth === 'fast' || depth === 'deep' ? depth : undefined; -} - -export function withDatabaseContextDepth( - connection: KtxProjectConnectionConfig, - depth: KtxDatabaseContextDepth, -): KtxProjectConnectionConfig { - return { - ...connection, - context: { - ...connectionContextRecord(connection), - depth, - }, - }; -} - -export function deepReadinessGaps(config: KtxProjectConfig): string[] { - const gaps: string[] = []; - if (config.llm.provider.backend === 'none' || !config.llm.models.default) { - gaps.push('model configuration'); - } - - if (config.scan.enrichment.mode !== 'llm') { - gaps.push('scan enrichment mode'); - } - - const embeddings = config.scan.enrichment.embeddings; - if ( - !embeddings || - embeddings.backend === 'none' || - !embeddings.model || - embeddings.dimensions <= 0 - ) { - gaps.push('scan embeddings'); - } - - return gaps; -} - -export function recommendedDatabaseContextDepth(config: KtxProjectConfig): KtxDatabaseContextDepth { - return deepReadinessGaps(config).length === 0 ? 'deep' : 'fast'; -} diff --git a/packages/cli/src/public-ingest-copy.ts b/packages/cli/src/public-ingest-copy.ts index be1206c1..86423f74 100644 --- a/packages/cli/src/public-ingest-copy.ts +++ b/packages/cli/src/public-ingest-copy.ts @@ -12,7 +12,7 @@ const DATABASE_INGEST_REPLACEMENTS: Array<[RegExp, string]> = [ 'Database enrichment failed after schema context completed', ], [/\bstructural scan\b/gi, 'schema context'], - [/\benriched scan\b/gi, 'deep database ingest'], + [/\benriched scan\b/gi, 'database ingest'], [/\bscan results\b/gi, 'database context'], ]; diff --git a/packages/cli/src/public-ingest.ts b/packages/cli/src/public-ingest.ts index 60bceecd..25fe30dd 100644 --- a/packages/cli/src/public-ingest.ts +++ b/packages/cli/src/public-ingest.ts @@ -1,16 +1,10 @@ import { getKtxCliPackageInfo } from './cli-runtime.js'; import { loadKtxProject, type KtxLocalProject } from './context/project/project.js'; -import type { KtxProjectConnectionConfig } from './context/project/config.js'; +import type { KtxProjectConfig, KtxProjectConnectionConfig } from './context/project/config.js'; import type { KtxProgressPort } from './context/scan/types.js'; import type { KtxCliIo } from './index.js'; import type { KtxIngestArgs, KtxIngestDeps, KtxIngestProgressUpdate } from './ingest.js'; -import { - type KtxDatabaseContextDepth, - databaseContextDepth, - deepReadinessGaps, - isDatabaseDriver, - normalizeConnectionDriver, -} from './ingest-depth.js'; +import { isDatabaseDriver, normalizeConnectionDriver } from './connection-drivers.js'; import { ensureManagedPythonCommandRuntime, type KtxManagedPythonInstallPolicy, @@ -29,7 +23,6 @@ profileMark('module:public-ingest'); type KtxPublicIngestStepName = 'database-schema' | 'query-history' | 'source-ingest' | 'memory-update'; type KtxPublicIngestStepStatus = 'done' | 'skipped' | 'failed' | 'not-run'; type KtxPublicIngestInputMode = 'auto' | 'disabled'; -type KtxPublicIngestDepth = KtxDatabaseContextDepth; type KtxPublicIngestQueryHistoryFlag = 'default' | 'enabled' | 'disabled'; type HistoricSqlDialect = 'postgres' | 'bigquery' | 'snowflake'; @@ -41,7 +34,6 @@ export type KtxPublicIngestArgs = all: boolean; json: boolean; inputMode: KtxPublicIngestInputMode; - depth?: KtxPublicIngestDepth; queryHistory?: KtxPublicIngestQueryHistoryFlag; queryHistoryWindowDays?: number; scanMode?: Extract['mode']; @@ -58,7 +50,6 @@ export interface KtxPublicIngestPlanTarget { sourceDir?: string; debugCommand: string; steps: KtxPublicIngestStepName[]; - databaseDepth?: KtxPublicIngestDepth; detectRelationships?: boolean; preflightFailure?: string; queryHistory?: { @@ -67,7 +58,6 @@ export interface KtxPublicIngestPlanTarget { windowDays?: number; pullConfig?: Record; unsupported?: boolean; - skippedStoredByFast?: boolean; }; } @@ -121,7 +111,6 @@ interface KtxPublicContextBuildArgs { inputMode: 'auto' | 'disabled'; targetConnectionId?: string; all?: boolean; - depth?: KtxPublicIngestDepth; queryHistory?: KtxPublicIngestQueryHistoryFlag; queryHistoryWindowDays?: number; scanMode?: Extract['mode']; @@ -154,7 +143,6 @@ interface KtxUnsupportedQueryHistoryWarning { interface KtxPublicIngestWarningAccumulator { warnings: string[]; - ignoredDepthForSources: string[]; ignoredQueryHistoryForSources: string[]; unsupportedQueryHistoryForDatabases: KtxUnsupportedQueryHistoryWarning[]; } @@ -162,7 +150,6 @@ interface KtxPublicIngestWarningAccumulator { function createWarningAccumulator(): KtxPublicIngestWarningAccumulator { return { warnings: [], - ignoredDepthForSources: [], ignoredQueryHistoryForSources: [], unsupportedQueryHistoryForDatabases: [], }; @@ -233,7 +220,6 @@ function finalizeWarnings( accumulator: KtxPublicIngestWarningAccumulator, args: { all: boolean; - depth?: KtxPublicIngestDepth; queryHistory?: KtxPublicIngestQueryHistoryFlag; queryHistoryWindowDays?: number; }, @@ -242,11 +228,6 @@ function finalizeWarnings( ...accumulator.warnings, ...unsupportedQueryHistoryWarnings(accumulator.unsupportedQueryHistoryForDatabases, args.all), ]; - const depthOption = args.depth ? `--${args.depth}` : null; - if (depthOption) { - const warning = sourceIgnoredWarning(depthOption, accumulator.ignoredDepthForSources, args.all); - if (warning) warnings.push(warning); - } if (args.queryHistory === 'enabled' || args.queryHistoryWindowDays !== undefined) { const warning = sourceIgnoredWarning('--query-history', accumulator.ignoredQueryHistoryForSources, args.all); if (warning) warnings.push(warning); @@ -317,13 +298,12 @@ function resolveDatabaseTargetOptions(input: { driver: string; connection: KtxProjectConnectionConfig; args: { - depth?: KtxPublicIngestDepth; queryHistory?: KtxPublicIngestQueryHistoryFlag; queryHistoryWindowDays?: number; scanMode?: Extract['mode']; }; warnings: KtxPublicIngestWarningAccumulator; -}): Pick { +}): Pick { const storedQh = storedQueryHistory(input.connection); const dialect = queryHistoryDialectByDriver.get(input.driver); const explicitQueryHistory = input.args.queryHistory ?? 'default'; @@ -332,7 +312,6 @@ function resolveDatabaseTargetOptions(input: { const requestedQh = explicitQueryHistory === 'enabled' || (explicitQueryHistory !== 'disabled' && (windowOverrideRequested || storedEnabled)); - let depth = input.args.depth ?? databaseContextDepth(input.connection) ?? 'fast'; const queryHistory = { enabled: false, ...(input.args.queryHistoryWindowDays !== undefined @@ -350,19 +329,13 @@ function resolveDatabaseTargetOptions(input: { explicitQueryHistory === 'enabled' || input.args.queryHistoryWindowDays !== undefined ? 'explicit' : 'stored', }); return { - databaseDepth: depth, queryHistory: { ...queryHistory, unsupported: true }, steps: ['database-schema'], }; } if (requestedQh && dialect) { - if (depth === 'fast') { - input.warnings.warnings.push(`--query-history requires deep ingest; running ${input.connectionId} with --deep.`); - } - depth = 'deep'; return { - databaseDepth: depth, queryHistory: { ...queryHistory, enabled: true, @@ -378,30 +351,35 @@ function resolveDatabaseTargetOptions(input: { }; } - if (input.args.depth === 'fast' && explicitQueryHistory !== 'enabled' && storedEnabled) { - input.warnings.warnings.push( - `${input.connectionId} has query history enabled in ktx.yaml, but --fast skips query-history processing.`, - ); - return { - databaseDepth: 'fast', - queryHistory: { ...queryHistory, skippedStoredByFast: true }, - steps: ['database-schema'], - }; - } - return { - databaseDepth: depth, queryHistory, steps: ['database-schema'], }; } +function enrichmentReadinessGaps(config: KtxProjectConfig): string[] { + const gaps: string[] = []; + if (config.llm.provider.backend === 'none' || !config.llm.models.default) { + gaps.push('model configuration'); + } + + if (config.scan.enrichment.mode !== 'llm') { + gaps.push('scan enrichment mode'); + } + + const embeddings = config.scan.enrichment.embeddings; + if (!embeddings || embeddings.backend === 'none' || !embeddings.model || embeddings.dimensions <= 0) { + gaps.push('scan embeddings'); + } + + return gaps; +} + function targetForConnection( connectionId: string, connection: KtxProjectConnectionConfig, projectConfig: KtxPublicIngestProject['config'], args: { - depth?: KtxPublicIngestDepth; queryHistory?: KtxPublicIngestQueryHistoryFlag; queryHistoryWindowDays?: number; scanMode?: Extract['mode']; @@ -412,9 +390,6 @@ function targetForConnection( const adapter = sourceAdapterByDriver.get(driver); const sourceDir = sourceDirForConnection(connection); if (adapter) { - if (args.depth) { - warnings.ignoredDepthForSources.push(connectionId); - } if (args.queryHistory === 'enabled' || args.queryHistoryWindowDays !== undefined) { warnings.ignoredQueryHistoryForSources.push(connectionId); } @@ -431,18 +406,18 @@ function targetForConnection( if (isDatabaseDriver(driver)) { const options = resolveDatabaseTargetOptions({ connectionId, driver, connection, args, warnings }); - const gaps = options.databaseDepth === 'deep' ? deepReadinessGaps(projectConfig) : []; + const gaps = enrichmentReadinessGaps(projectConfig); return { connectionId, driver, operation: 'database-ingest', debugCommand: `ktx ingest ${connectionId} --debug`, - detectRelationships: options.databaseDepth === 'deep' && projectConfig.scan.relationships.enabled, + detectRelationships: projectConfig.scan.relationships.enabled, ...(gaps.length > 0 ? { - preflightFailure: `${connectionId} requires deep ingest readiness: ${gaps.join( + preflightFailure: `${connectionId} cannot be ingested: enrichment is not configured (${gaps.join( ', ', - )}. Run ktx setup or rerun with --fast.`, + )}). Run ktx setup to configure a model and embeddings.`, } : {}), ...options, @@ -458,7 +433,6 @@ export function buildPublicIngestPlan( projectDir: string; targetConnectionId?: string; all: boolean; - depth?: KtxPublicIngestDepth; queryHistory?: KtxPublicIngestQueryHistoryFlag; queryHistoryWindowDays?: number; scanMode?: Extract['mode']; @@ -522,13 +496,12 @@ function retryCommandForTarget( args: Extract, ): string { const projectPart = ` --project-dir ${args.projectDir}`; - const depthPart = target.databaseDepth ? ` --${target.databaseDepth}` : ''; const queryHistoryPart = target.queryHistory?.enabled === true ? ' --query-history' : ''; const windowPart = target.queryHistory?.enabled === true && target.queryHistory.windowDays !== undefined ? ` --query-history-window-days ${target.queryHistory.windowDays}` : ''; - return `ktx ingest ${target.connectionId}${projectPart}${depthPart}${queryHistoryPart}${windowPart}`; + return `ktx ingest ${target.connectionId}${projectPart}${queryHistoryPart}${windowPart}`; } function trimTrailingPeriod(value: string): string { @@ -830,7 +803,7 @@ export async function executePublicIngestTarget( command: 'run', projectDir: args.projectDir, connectionId: target.connectionId, - mode: target.databaseDepth === 'deep' ? 'enriched' : 'structural', + mode: 'enriched', detectRelationships: target.detectRelationships === true, dryRun: false, ...(args.cliVersion ? { cliVersion: args.cliVersion } : {}), @@ -979,7 +952,6 @@ export async function runKtxPublicIngest( all: args.all, entrypoint: 'ingest', inputMode: args.inputMode, - ...(args.depth ? { depth: args.depth } : {}), ...(args.queryHistory ? { queryHistory: args.queryHistory } : {}), ...(args.queryHistoryWindowDays !== undefined ? { queryHistoryWindowDays: args.queryHistoryWindowDays } : {}), ...(args.scanMode ? { scanMode: args.scanMode } : {}), diff --git a/packages/cli/src/setup-context.ts b/packages/cli/src/setup-context.ts index dc289278..63b4dbdf 100644 --- a/packages/cli/src/setup-context.ts +++ b/packages/cli/src/setup-context.ts @@ -7,12 +7,7 @@ import { serializeKtxProjectConfig } from './context/project/config.js'; import type { KtxCliIo } from './cli-runtime.js'; import { errorMessage, writePrefixedLines } from './clack.js'; import { buildPublicIngestPlan } from './public-ingest.js'; -import { - type KtxDatabaseContextDepth, - databaseContextDepth, -} from './ingest-depth.js'; import type { KtxManagedPythonInstallPolicy } from './managed-python-command.js'; -import { ensureSetupDatabaseContextDepths } from './setup-database-context-depth.js'; import { type ContextBuildSourceProgressUpdate, runContextBuild, @@ -353,16 +348,6 @@ async function readLatestScanReport(projectDir: string, connectionId: string): P return reports.at(-1)?.report ?? null; } -function scanReportHasSchemaManifest(report: unknown, connectionId: string): boolean { - if (!isRecord(report)) { - return false; - } - if (report.connectionId !== connectionId || report.dryRun === true) { - return false; - } - return stringArrayValue(isRecord(report.artifactPaths) ? report.artifactPaths.manifestShards : undefined).length > 0; -} - function scanReportHasCompletedDeepEnrichment( report: unknown, connectionId: string, @@ -389,18 +374,6 @@ function scanReportHasCompletedDeepEnrichment( ); } -function scanReportSatisfiesDepth(input: { - report: unknown; - connectionId: string; - depth: KtxDatabaseContextDepth; - relationshipsRequired: boolean; -}): boolean { - if (input.depth === 'fast') { - return scanReportHasSchemaManifest(input.report, input.connectionId); - } - return scanReportHasCompletedDeepEnrichment(input.report, input.connectionId, input.relationshipsRequired); -} - async function verifyPrimarySourceScans( project: KtxLocalProject, connectionIds: string[], @@ -408,15 +381,9 @@ async function verifyPrimarySourceScans( const details: string[] = []; const relationshipsRequired = project.config.scan.relationships.enabled; for (const connectionId of connectionIds) { - const connection = project.config.connections[connectionId]; - const depth = connection ? (databaseContextDepth(connection) ?? 'fast') : 'fast'; const report = await readLatestScanReport(project.projectDir, connectionId); - if (!scanReportSatisfiesDepth({ report, connectionId, depth, relationshipsRequired })) { - details.push( - depth === 'fast' - ? `${connectionId}: schema context has not completed.` - : `${connectionId}: deep database context has not completed.`, - ); + if (!scanReportHasCompletedDeepEnrichment(report, connectionId, relationshipsRequired)) { + details.push(`${connectionId}: database context has not completed.`); } } return { ready: details.length === 0, details }; @@ -482,7 +449,6 @@ function writeSkippedContext(projectDir: string, io: KtxCliIo): void { } function writeSuccess( - project: KtxLocalProject, readiness: KtxSetupContextReadiness, targets: KtxSetupContextTargets, io: KtxCliIo, @@ -493,9 +459,7 @@ function writeSuccess( io.stdout.write(' none\n'); } else { for (const connectionId of targets.primarySourceConnectionIds) { - const connection = project.config.connections[connectionId]; - const depth = connection ? (databaseContextDepth(connection) ?? 'fast') : 'fast'; - io.stdout.write(` ${connectionId}: ${depth === 'deep' ? 'deep context complete' : 'schema context complete'}\n`); + io.stdout.write(` ${connectionId}: database context complete\n`); } } io.stdout.write('\nContext sources:\n'); @@ -636,7 +600,7 @@ async function runBuild( failureReason: undefined, ...(lastSourceProgress ? { sourceProgress: lastSourceProgress } : {}), }); - writeSuccess(project, readiness, targets, io); + writeSuccess(readiness, targets, io); return { status: 'ready', projectDir: args.projectDir, runId }; } @@ -678,17 +642,8 @@ export async function runKtxSetupContextStep( deps: KtxSetupContextDeps = {}, ): Promise { try { - let project = await loadKtxProject({ projectDir: args.projectDir }); + const project = await loadKtxProject({ projectDir: args.projectDir }); const prompts = deps.prompts ?? createPromptAdapter(); - const depthProject = await ensureSetupDatabaseContextDepths({ - project, - args, - prompts, - }); - if (depthProject === 'back') { - return { status: 'back', projectDir: args.projectDir }; - } - project = depthProject; const existingState = await readKtxSetupContextState(args.projectDir); const completedSteps = (await readKtxSetupState(args.projectDir)).completed_steps; if (completedSteps.includes('context') && existingState.status === 'completed') { diff --git a/packages/cli/src/setup-database-context-depth.ts b/packages/cli/src/setup-database-context-depth.ts deleted file mode 100644 index 20df813c..00000000 --- a/packages/cli/src/setup-database-context-depth.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { writeFile } from 'node:fs/promises'; -import { type KtxLocalProject, loadKtxProject } from './context/project/project.js'; -import { type KtxProjectConnectionConfig, serializeKtxProjectConfig } from './context/project/config.js'; -import { - type KtxDatabaseContextDepth, - databaseContextDepth, - deepReadinessGaps, - isDatabaseDriver, - normalizeConnectionDriver, - recommendedDatabaseContextDepth, - withDatabaseContextDepth, -} from './ingest-depth.js'; -import type { KtxSetupPromptOption } from './setup-prompts.js'; - -export interface KtxSetupDatabaseContextDepthArgs { - inputMode: 'auto' | 'disabled'; -} - -export interface KtxSetupDatabaseContextDepthPromptAdapter { - select(options: { message: string; options: KtxSetupPromptOption[] }): Promise; -} - -function databaseConnectionsNeedingDepth(project: KtxLocalProject): string[] { - return Object.entries(project.config.connections) - .filter(([, connection]) => isDatabaseDriver(normalizeConnectionDriver(connection))) - .filter(([, connection]) => databaseContextDepth(connection) === undefined) - .map(([connectionId]) => connectionId) - .sort((left, right) => left.localeCompare(right)); -} - -async function chooseSetupDatabaseContextDepth(input: { - project: KtxLocalProject; - args: KtxSetupDatabaseContextDepthArgs; - prompts: KtxSetupDatabaseContextDepthPromptAdapter; -}): Promise { - const recommended = recommendedDatabaseContextDepth(input.project.config); - if (input.args.inputMode === 'disabled') { - return recommended; - } - - const deepReady = deepReadinessGaps(input.project.config).length === 0; - const options = - recommended === 'deep' - ? [ - { - value: 'deep', - label: 'Deep: AI descriptions, embeddings, relationships, slower', - hint: 'recommended', - }, - { value: 'fast', label: 'Fast: schema only, no AI, quickest' }, - { value: 'back', label: 'Back' }, - ] - : [ - { value: 'fast', label: 'Fast: schema only, no AI, quickest', hint: 'recommended' }, - { value: 'deep', label: 'Deep: AI descriptions, embeddings, relationships, slower' }, - { value: 'back', label: 'Back' }, - ]; - - const choice = await input.prompts.select({ - message: - 'How much database context should KTX build?\n\n' + - (deepReady - ? 'Deep is available because model, embedding, and scan enrichment are configured.' - : 'Fast is recommended because model, embedding, or scan enrichment is not configured.'), - options, - }); - if (choice === 'back') { - return 'back'; - } - if (choice === 'fast' || choice === 'deep') { - return choice; - } - return recommended; -} - -async function writeDatabaseContextDepths( - project: KtxLocalProject, - connectionIds: string[], - depth: KtxDatabaseContextDepth, -): Promise { - if (connectionIds.length === 0) { - return project; - } - const nextConnections = { ...project.config.connections }; - for (const connectionId of connectionIds) { - const connection = nextConnections[connectionId]; - if (connection) { - nextConnections[connectionId] = withDatabaseContextDepth(connection, depth); - } - } - const nextConfig = { ...project.config, connections: nextConnections }; - await writeFile(project.configPath, serializeKtxProjectConfig(nextConfig), 'utf-8'); - return await loadKtxProject({ projectDir: project.projectDir }); -} - -export async function ensureSetupDatabaseContextDepths(input: { - project: KtxLocalProject; - args: KtxSetupDatabaseContextDepthArgs; - prompts: KtxSetupDatabaseContextDepthPromptAdapter; -}): Promise { - const missingDepthConnectionIds = databaseConnectionsNeedingDepth(input.project); - if (missingDepthConnectionIds.length === 0) { - return input.project; - } - - const depth = await chooseSetupDatabaseContextDepth(input); - if (depth === 'back') { - return 'back'; - } - return await writeDatabaseContextDepths(input.project, missingDepthConnectionIds, depth); -} - -export async function applySetupDatabaseContextDepth(input: { - project: KtxLocalProject; - connection: KtxProjectConnectionConfig; - args: KtxSetupDatabaseContextDepthArgs; - prompts: KtxSetupDatabaseContextDepthPromptAdapter; -}): Promise { - if ( - !isDatabaseDriver(normalizeConnectionDriver(input.connection)) || - databaseContextDepth(input.connection) !== undefined - ) { - return input.connection; - } - - const depth = await chooseSetupDatabaseContextDepth(input); - if (depth === 'back') { - return 'back'; - } - return withDatabaseContextDepth(input.connection, depth); -} diff --git a/packages/cli/src/setup-databases.ts b/packages/cli/src/setup-databases.ts index eb364228..09db1bde 100644 --- a/packages/cli/src/setup-databases.ts +++ b/packages/cli/src/setup-databases.ts @@ -29,7 +29,6 @@ import { } from './database-tree-picker.js'; import { withMultiselectNavigation, withTextInputNavigation } from './prompt-navigation.js'; import { runKtxScan } from './scan.js'; -import { applySetupDatabaseContextDepth } from './setup-database-context-depth.js'; import { writeProjectLocalSecretReference } from './setup-secrets.js'; import { isDemoConnection } from './telemetry/demo-detect.js'; import { emitTelemetryEvent } from './telemetry/index.js'; @@ -1614,45 +1613,10 @@ async function applyHistoricSqlConfigToExistingConnection(input: { prompts: input.prompts, }); if (withHistoricSql === 'back') return 'back'; - const withContextDepth = await maybeApplyContextDepthConfig({ - projectDir: input.projectDir, - connectionId: input.connectionId, - connection: withHistoricSql, - args: input.args, - prompts: input.prompts, - }); - if (withContextDepth === 'back') return 'back'; await writeConnectionConfig({ projectDir: input.projectDir, connectionId: input.connectionId, - connection: withContextDepth, - }); -} - -async function maybeApplyContextDepthConfig(input: { - projectDir: string; - connectionId: string; - connection: KtxProjectConnectionConfig; - args: KtxSetupDatabasesArgs; - prompts: KtxSetupDatabasesPromptAdapter; -}): Promise { - const project = await loadKtxProject({ projectDir: input.projectDir }); - return await applySetupDatabaseContextDepth({ - project: { - ...project, - config: { - ...project.config, - connections: { - ...project.config.connections, - [input.connectionId]: input.connection, - }, - }, - }, - connection: input.connection, - args: { - inputMode: input.args.inputMode === 'disabled' || input.args.databaseUrl ? 'disabled' : input.args.inputMode, - }, - prompts: input.prompts, + connection: withHistoricSql, }); } @@ -1698,7 +1662,7 @@ async function validateAndScanConnection(input: { deps: input.deps, }); writeSetupSection(input.io, `Building schema context for ${input.connectionId}`, [ - 'Running fast database ingest…', + 'Running database scan…', ]); let scanIo = createBufferedCommandIo(); let scanCode = await scanConnection(input.projectDir, input.connectionId, scanIo); @@ -1708,7 +1672,7 @@ async function validateAndScanConnection(input: { writePrefixedLines( (chunk) => input.io.stderr.write(chunk), [ - `Fast database ingest failed for ${input.connectionId}.`, + `Database scan failed for ${input.connectionId}.`, 'Native SQLite is built for a different Node.js ABI.', `Detail: ${nativeSqliteDetail}`, 'Rebuilding Native SQLite with pnpm run native:rebuild…', @@ -1719,7 +1683,7 @@ async function validateAndScanConnection(input: { if (rebuildCode === 0) { writePrefixedLines( (chunk) => input.io.stderr.write(chunk), - 'Native SQLite rebuild complete. Retrying fast database ingest…', + 'Native SQLite rebuild complete. Retrying database scan…', ); const retryScanIo = createBufferedCommandIo(); scanCode = await scanConnection(input.projectDir, input.connectionId, retryScanIo); @@ -1730,10 +1694,10 @@ async function validateAndScanConnection(input: { (chunk) => input.io.stderr.write(chunk), [ rebuildCode === 0 - ? `Fast database ingest still failed for ${input.connectionId} after rebuilding Native SQLite.` + ? `Database scan still failed for ${input.connectionId} after rebuilding Native SQLite.` : `Native SQLite rebuild failed for ${input.connectionId}.`, 'Fix: pnpm run native:rebuild', - `Retry: ktx ingest ${input.connectionId} --project-dir ${input.projectDir} --fast`, + `Retry: ktx ingest ${input.connectionId} --project-dir ${input.projectDir}`, ].join('\n'), ); } @@ -1742,8 +1706,8 @@ async function validateAndScanConnection(input: { writePrefixedLines( (chunk) => input.io.stderr.write(chunk), [ - `Fast database ingest failed for ${input.connectionId}.`, - `Debug command: ktx ingest ${input.connectionId} --project-dir ${input.projectDir} --fast --debug`, + `Database scan failed for ${input.connectionId}.`, + `Debug command: ktx ingest ${input.connectionId} --project-dir ${input.projectDir} --debug`, ].join('\n'), ); } @@ -2167,22 +2131,10 @@ export async function runKtxSetupDatabasesStep( returnToDriverSelection = true; break; } - const withContextDepth = await maybeApplyContextDepthConfig({ - projectDir: args.projectDir, - connectionId: connectionChoice.connectionId, - connection: withHistoricSql, - args, - prompts, - }); - if (withContextDepth === 'back') { - if (!canReturnToDriverSelection) return { status: 'back', projectDir: args.projectDir }; - returnToDriverSelection = true; - break; - } await writeConnectionConfig({ projectDir: args.projectDir, connectionId: connectionChoice.connectionId, - connection: withContextDepth, + connection: withHistoricSql, io, }); } else { @@ -2193,22 +2145,10 @@ export async function runKtxSetupDatabasesStep( returnToDriverSelection = true; break; } - const withContextDepth = await maybeApplyContextDepthConfig({ - projectDir: args.projectDir, - connectionId: connectionChoice.connectionId, - connection: withHistoricSql, - args, - prompts, - }); - if (withContextDepth === 'back') { - if (!canReturnToDriverSelection) return { status: 'back', projectDir: args.projectDir }; - returnToDriverSelection = true; - break; - } await writeConnectionConfig({ projectDir: args.projectDir, connectionId: connectionChoice.connectionId, - connection: withContextDepth, + connection: withHistoricSql, io, }); } @@ -2291,22 +2231,10 @@ export async function runKtxSetupDatabasesStep( returnToDriverSelection = true; break; } - const withContextDepth = await maybeApplyContextDepthConfig({ - projectDir: args.projectDir, - connectionId: connectionChoice.connectionId, - connection: withHistoricSql, - args, - prompts, - }); - if (withContextDepth === 'back') { - if (!canReturnToDriverSelection) return { status: 'back', projectDir: args.projectDir }; - returnToDriverSelection = true; - break; - } await writeConnectionConfig({ projectDir: args.projectDir, connectionId: connectionChoice.connectionId, - connection: withContextDepth, + connection: withHistoricSql, io, }); setupStatus = await validateAndScanConnection({ diff --git a/packages/cli/src/telemetry/events.schema.json b/packages/cli/src/telemetry/events.schema.json index 13642c49..628c8f4b 100644 --- a/packages/cli/src/telemetry/events.schema.json +++ b/packages/cli/src/telemetry/events.schema.json @@ -365,7 +365,6 @@ "embeddings", "secrets", "databases", - "database-context-depth", "sources", "context", "agents", diff --git a/packages/cli/src/telemetry/events.ts b/packages/cli/src/telemetry/events.ts index e73001ed..5e5b5335 100644 --- a/packages/cli/src/telemetry/events.ts +++ b/packages/cli/src/telemetry/events.ts @@ -38,7 +38,6 @@ const setupStepSchema = telemetryCommonEnvelopeSchema 'embeddings', 'secrets', 'databases', - 'database-context-depth', 'sources', 'context', 'agents', diff --git a/packages/cli/test/context-build-view.test.ts b/packages/cli/test/context-build-view.test.ts index 5936afa9..40e33606 100644 --- a/packages/cli/test/context-build-view.test.ts +++ b/packages/cli/test/context-build-view.test.ts @@ -228,11 +228,11 @@ describe('renderContextBuildView', () => { const rendered = renderContextBuildView(state, { styled: false, - warnings: ['--deep affects database ingest only; ignoring it for docs.'], + warnings: ['--query-history affects database ingest only; ignoring it for docs.'], }); expect(rendered).toContain('Warnings:'); - expect(rendered).toContain('--deep affects database ingest only; ignoring it for docs.'); + expect(rendered).toContain('--query-history affects database ingest only; ignoring it for docs.'); }); it('renders public notices in the foreground view before warnings', () => { @@ -243,7 +243,6 @@ describe('renderContextBuildView', () => { operation: 'database-ingest', debugCommand: 'ktx ingest warehouse --debug', steps: ['database-schema', 'query-history'], - databaseDepth: 'deep', detectRelationships: true, queryHistory: { enabled: true, dialect: 'postgres' }, }, @@ -252,12 +251,12 @@ describe('renderContextBuildView', () => { const rendered = renderContextBuildView(state, { styled: false, notices: ['Schema ingest runs before query history for warehouse.'], - warnings: ['--query-history requires deep ingest; running warehouse with --deep.'], + warnings: ['--query-history is not supported for sqlite; running schema ingest for local.'], }); expect(rendered.indexOf('Notices:')).toBeLessThan(rendered.indexOf('Warnings:')); expect(rendered).toContain('Schema ingest runs before query history for warehouse.'); - expect(rendered).toContain('--query-history requires deep ingest; running warehouse with --deep.'); + expect(rendered).toContain('--query-history is not supported for sqlite; running schema ingest for local.'); }); it('renders dynamic separator matching header width', () => { @@ -653,7 +652,6 @@ describe('runContextBuild', () => { inputMode: 'disabled', targetConnectionId: 'warehouse', all: false, - depth: 'fast', queryHistory: 'default', }, io.io, @@ -665,7 +663,6 @@ describe('runContextBuild', () => { expect(executeTarget.mock.calls[0]?.[0]).toMatchObject({ connectionId: 'warehouse', operation: 'database-ingest', - databaseDepth: 'fast', }); expect(io.stdout()).toContain('Databases:'); expect(io.stdout()).toContain('warehouse'); @@ -716,7 +713,7 @@ describe('runContextBuild', () => { it('renders localhost SQL analysis refusal as a runtime failure during query history', async () => { const io = makeIo(); const project = projectWithConnections({ - warehouse: { driver: 'postgres', context: { depth: 'deep', queryHistory: { enabled: true } } }, + warehouse: { driver: 'postgres', context: { queryHistory: { enabled: true } } }, }); const executeTarget = vi.fn(async (target, _args, targetIo) => { targetIo.stderr.write('connect ECONNREFUSED 127.0.0.1:8765\n'); @@ -751,7 +748,7 @@ describe('runContextBuild', () => { it('uses captured query-history stderr instead of generic failed-at detail', async () => { const io = makeIo(); const project = projectWithConnections({ - warehouse: { driver: 'postgres', context: { depth: 'deep', queryHistory: { enabled: true } } }, + warehouse: { driver: 'postgres', context: { queryHistory: { enabled: true } } }, }); const executeTarget = vi.fn(async (target, _args, targetIo) => { targetIo.stdout.write('KTX scan completed\n'); @@ -768,7 +765,7 @@ describe('runContextBuild', () => { operation: 'query-history', status: 'failed', detail: - 'warehouse failed at query-history. Retry: ktx ingest warehouse --project-dir /tmp/project --deep --query-history', + 'warehouse failed at query-history. Retry: ktx ingest warehouse --project-dir /tmp/project --query-history', }, { operation: 'source-ingest', status: 'skipped' }, { operation: 'memory-update', status: 'skipped' }, @@ -785,7 +782,7 @@ describe('runContextBuild', () => { expect(result).toEqual({ exitCode: 1 }); expect(io.stdout()).toContain('Missing bundled Python runtime manifest: /tmp/assets/python/manifest.json.'); - expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --deep --query-history'); + expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --query-history'); expect(io.stdout()).not.toContain('Then retry the runtime-backed KTX command'); expect(io.stdout()).not.toContain('warehouse failed at query-history'); expect(io.stdout().match(/Retry: /g)).toHaveLength(1); @@ -899,12 +896,12 @@ describe('runContextBuild', () => { const io = makeIo(); const project: KtxPublicIngestProject = { ...projectWithConnections({ - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, }), config: { ...projectWithConnections({ warehouse: { driver: 'postgres' } }).config, connections: { - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, }, llm: { provider: { backend: 'gateway', gateway: { api_key: 'env:KTX_GATEWAY_API_KEY' } }, // pragma: allowlist secret diff --git a/packages/cli/test/index.test.ts b/packages/cli/test/index.test.ts index a60c48f2..bd17e641 100644 --- a/packages/cli/test/index.test.ts +++ b/packages/cli/test/index.test.ts @@ -702,7 +702,7 @@ describe('runKtxCli', () => { const publicIngest = vi.fn().mockResolvedValue(0); await expect( - runKtxCli(['--project-dir', tempDir, 'ingest', 'warehouse', '--fast', '--no-input'], testIo.io, { + runKtxCli(['--project-dir', tempDir, 'ingest', 'warehouse', '--no-input'], testIo.io, { publicIngest, }), ).resolves.toBe(0); @@ -715,7 +715,6 @@ describe('runKtxCli', () => { all: false, json: false, inputMode: 'disabled', - depth: 'fast', queryHistory: 'default', cliVersion, runtimeInstallPolicy: 'never', @@ -725,12 +724,12 @@ describe('runKtxCli', () => { expect(testIo.stderr()).toBe(`Project: ${tempDir}\n`); }); - it('routes public ingest --all --deep with JSON output', async () => { + it('routes public ingest --all with JSON output', async () => { const testIo = makeIo(); const publicIngest = vi.fn().mockResolvedValue(0); await expect( - runKtxCli(['--project-dir', tempDir, 'ingest', '--all', '--deep', '--json'], testIo.io, { + runKtxCli(['--project-dir', tempDir, 'ingest', '--all', '--json'], testIo.io, { publicIngest, }), ).resolves.toBe(0); @@ -742,7 +741,6 @@ describe('runKtxCli', () => { all: true, json: true, inputMode: 'auto', - depth: 'deep', queryHistory: 'default', cliVersion, runtimeInstallPolicy: 'prompt', @@ -786,20 +784,6 @@ describe('runKtxCli', () => { expect(testIo.stderr()).toContain('Choose only one runtime install mode: --yes or --no-input'); }); - it('rejects mutually exclusive public ingest depth flags before dispatch', async () => { - const testIo = makeIo(); - const publicIngest = vi.fn().mockResolvedValue(0); - - await expect( - runKtxCli(['--project-dir', '/tmp/project', 'ingest', 'warehouse', '--fast', '--deep'], testIo.io, { - publicIngest, - }), - ).resolves.toBe(1); - - expect(publicIngest).not.toHaveBeenCalled(); - expect(testIo.stderr()).toMatch(/option '--(deep|fast)' cannot be used with option '--(fast|deep)'/); - }); - it.each(['run', 'status', 'watch', 'replay'])( 'routes former ingest subcommand name "%s" as a connection id', async (connectionId) => { @@ -890,8 +874,6 @@ describe('runKtxCli', () => { expect(testIo.stdout()).toContain('Usage: ktx ingest'); expect(testIo.stdout()).toContain('Build or inspect KTX context'); expect(testIo.stdout()).toContain('--all'); - expect(testIo.stdout()).toContain('--fast'); - expect(testIo.stdout()).toContain('--deep'); expect(testIo.stdout()).toContain('--query-history'); expect(testIo.stdout()).toContain('--no-query-history'); expect(testIo.stdout()).toContain('--query-history-window-days '); diff --git a/packages/cli/test/public-ingest.test.ts b/packages/cli/test/public-ingest.test.ts index b926793c..41289208 100644 --- a/packages/cli/test/public-ingest.test.ts +++ b/packages/cli/test/public-ingest.test.ts @@ -88,7 +88,7 @@ function deepReadyProject( describe('buildPublicIngestPlan', () => { it('plans warehouse connections as scan targets and source connections as source ingest targets', () => { - const project = projectWithConnections({ + const project = deepReadyProject({ warehouse: { driver: 'postgres' }, prod_metabase: { driver: 'metabase', api_url: 'https://metabase.example.com' }, docs: { driver: 'notion' }, @@ -103,8 +103,7 @@ describe('buildPublicIngestPlan', () => { operation: 'database-ingest', debugCommand: 'ktx ingest warehouse --debug', steps: ['database-schema'], - databaseDepth: 'fast', - detectRelationships: false, + detectRelationships: true, queryHistory: { enabled: false }, }, { @@ -139,61 +138,6 @@ describe('buildPublicIngestPlan', () => { expect(plan.targets.map((target) => target.connectionId).sort()).toEqual(['docs', 'warehouse']); }); - it('resolves database depth from flags, stored context, and defaults', () => { - const project = projectWithConnections({ - fast_default: { driver: 'postgres' }, - deep_default: { driver: 'postgres', context: { depth: 'deep' } }, - docs: { driver: 'notion' }, - }); - - expect( - buildPublicIngestPlan(project, { - projectDir: '/tmp/project', - targetConnectionId: 'fast_default', - all: false, - queryHistory: 'default', - }).targets[0], - ).toMatchObject({ connectionId: 'fast_default', databaseDepth: 'fast', queryHistory: { enabled: false } }); - - expect( - buildPublicIngestPlan(project, { - projectDir: '/tmp/project', - targetConnectionId: 'deep_default', - all: false, - queryHistory: 'default', - }).targets[0], - ).toMatchObject({ connectionId: 'deep_default', databaseDepth: 'deep' }); - - expect( - buildPublicIngestPlan(project, { - projectDir: '/tmp/project', - targetConnectionId: 'docs', - all: false, - depth: 'deep', - queryHistory: 'default', - }).warnings, - ).toEqual(['--deep affects database ingest only; ignoring it for docs.']); - }); - - it('does not infer deep ingest from legacy scanMode values', () => { - const project = projectWithConnections({ - warehouse: { driver: 'postgres' }, - }); - - const plan = buildPublicIngestPlan(project, { - projectDir: '/tmp/project', - targetConnectionId: 'warehouse', - all: false, - scanMode: 'enriched', - }); - - expect(plan.targets[0]).toMatchObject({ - connectionId: 'warehouse', - databaseDepth: 'fast', - steps: ['database-schema'], - }); - }); - it('rejects stale local Looker source driver aliases', () => { const project = projectWithConnections({ local_looker: { driver: 'local_looker' } as never, @@ -204,8 +148,8 @@ describe('buildPublicIngestPlan', () => { ); }); - it('upgrades effective depth when query history is explicitly enabled', () => { - const project = projectWithConnections({ + it('enables query history when explicitly requested even if stored config disables it', () => { + const project = deepReadyProject({ warehouse: { driver: 'postgres', context: { queryHistory: { enabled: false } } }, }); @@ -213,17 +157,16 @@ describe('buildPublicIngestPlan', () => { projectDir: '/tmp/project', targetConnectionId: 'warehouse', all: false, - depth: 'fast', queryHistory: 'enabled', queryHistoryWindowDays: 30, }); expect(plan.targets[0]).toMatchObject({ connectionId: 'warehouse', - databaseDepth: 'deep', queryHistory: { enabled: true, windowDays: 30, dialect: 'postgres' }, + steps: ['database-schema', 'query-history'], }); - expect(plan.warnings).toEqual(['--query-history requires deep ingest; running warehouse with --deep.']); + expect(plan.warnings).toEqual([]); }); it('warns and skips query history for unsupported database drivers', () => { @@ -238,7 +181,6 @@ describe('buildPublicIngestPlan', () => { expect(plan.targets[0]).toMatchObject({ connectionId: 'local', - databaseDepth: 'fast', queryHistory: { enabled: false, unsupported: true }, }); expect(plan.warnings).toEqual(['--query-history is not supported for sqlite; running schema ingest for local.']); @@ -249,12 +191,11 @@ describe('buildPublicIngestPlan', () => { deepReadyProject({ local: { driver: 'sqlite' }, mysql_warehouse: { driver: 'mysql' }, - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, }), { projectDir: '/tmp/project', all: true, - depth: 'deep', queryHistory: 'enabled', }, ); @@ -326,7 +267,6 @@ describe('buildPublicIngestPlan', () => { expect(plan.targets[0]).toMatchObject({ connectionId: 'warehouse', - databaseDepth: 'deep', queryHistory: { enabled: true, dialect: 'postgres', windowDays: 30 }, steps: ['database-schema', 'query-history'], }); @@ -334,7 +274,7 @@ describe('buildPublicIngestPlan', () => { it('adds a schema-first notice when query history is explicitly enabled', () => { const project = deepReadyProject({ - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, }); expect( @@ -363,34 +303,15 @@ describe('buildPublicIngestPlan', () => { expect(plan.targets[0]).toMatchObject({ connectionId: 'local', - databaseDepth: 'fast', queryHistory: { enabled: false, windowDays: 30, unsupported: true }, steps: ['database-schema'], }); expect(plan.warnings).toEqual(['--query-history is not supported for sqlite; running schema ingest for local.']); }); - it('aggregates ignored database-depth warnings for all source targets', () => { - const plan = buildPublicIngestPlan( - projectWithConnections({ - warehouse: { driver: 'postgres' }, - docs: { driver: 'notion' }, - dbt: { driver: 'dbt' }, - }), - { - projectDir: '/tmp/project', - all: true, - depth: 'deep', - queryHistory: 'default', - }, - ); - - expect(plan.warnings).toEqual(['--deep ignored for 2 non-database sources.']); - }); - - it('records a preflight failure for deep database ingest when readiness config is missing', () => { + it('records a preflight failure for database ingest when enrichment readiness config is missing', () => { const project = projectWithConnections({ - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, }); const plan = buildPublicIngestPlan(project, { @@ -402,15 +323,14 @@ describe('buildPublicIngestPlan', () => { expect(plan.targets[0]).toMatchObject({ connectionId: 'warehouse', - databaseDepth: 'deep', preflightFailure: - 'warehouse requires deep ingest readiness: model configuration, scan enrichment mode, scan embeddings. Run ktx setup or rerun with --fast.', + 'warehouse cannot be ingested: enrichment is not configured (model configuration, scan enrichment mode, scan embeddings). Run ktx setup to configure a model and embeddings.', }); }); - it('honors scan.relationships.enabled when planning deep database ingest', () => { + it('honors scan.relationships.enabled when planning database ingest', () => { const plan = buildPublicIngestPlan( - deepReadyProject({ warehouse: { driver: 'postgres', context: { depth: 'deep' } } }, false), + deepReadyProject({ warehouse: { driver: 'postgres' } }, false), { projectDir: '/tmp/project', targetConnectionId: 'warehouse', @@ -421,7 +341,6 @@ describe('buildPublicIngestPlan', () => { expect(plan.targets[0]).toMatchObject({ connectionId: 'warehouse', - databaseDepth: 'deep', detectRelationships: false, }); }); @@ -432,11 +351,11 @@ describe('runKtxPublicIngest', () => { vi.unstubAllEnvs(); }); - it('maps fast and deep database targets to scan internals', async () => { + it('maps database targets to enriched scan internals', async () => { const io = makeIo(); const project = deepReadyProject({ - fast: { driver: 'postgres' }, - deep: { driver: 'postgres', context: { depth: 'deep' } }, + first: { driver: 'postgres' }, + second: { driver: 'postgres' }, }); const runScan = vi.fn(async () => 0); @@ -450,12 +369,12 @@ describe('runKtxPublicIngest', () => { expect(runScan).toHaveBeenNthCalledWith( 1, - expect.objectContaining({ connectionId: 'deep', mode: 'enriched', detectRelationships: true }), + expect.objectContaining({ connectionId: 'first', mode: 'enriched', detectRelationships: true }), expect.anything(), ); expect(runScan).toHaveBeenNthCalledWith( 2, - expect.objectContaining({ connectionId: 'fast', mode: 'structural', detectRelationships: false }), + expect.objectContaining({ connectionId: 'second', mode: 'enriched', detectRelationships: true }), expect.anything(), ); }); @@ -467,7 +386,7 @@ describe('runKtxPublicIngest', () => { try { await initKtxProject({ projectDir }); const io = makeIo({ isTTY: true }); - const project = projectWithConnections({ + const project = deepReadyProject({ warehouse: { driver: 'sqlite', path: join(projectDir, 'warehouse.sqlite') }, }); @@ -614,7 +533,7 @@ describe('runKtxPublicIngest', () => { it('prints the schema-first notice for explicit query-history runs', async () => { const io = makeIo(); const project = deepReadyProject({ - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, }); const runScan = vi.fn(async () => 0); const runIngest = vi.fn(async () => 0); @@ -640,7 +559,7 @@ describe('runKtxPublicIngest', () => { it('suppresses internal scan output for public database ingest summaries', async () => { const io = makeIo(); - const project = projectWithConnections({ warehouse: { driver: 'postgres' } }); + const project = deepReadyProject({ warehouse: { driver: 'postgres' } }); const runScan = vi.fn(async (_args, scanIo) => { scanIo.stdout.write('KTX scan completed\n'); scanIo.stdout.write('Mode: structural\n'); @@ -674,7 +593,7 @@ describe('runKtxPublicIngest', () => { it('sanitizes captured database scan failure details in direct public output', async () => { const io = makeIo(); - const project = deepReadyProject({ warehouse: { driver: 'postgres', context: { depth: 'deep' } } }); + const project = deepReadyProject({ warehouse: { driver: 'postgres' } }); const runScan = vi.fn(async (_args, scanIo) => { scanIo.stdout.write('KTX scan enrichment failed after structural scan completed: embedding service timed out\n'); return 1; @@ -689,7 +608,6 @@ describe('runKtxPublicIngest', () => { all: false, json: false, inputMode: 'disabled', - depth: 'deep', }, io.io, { loadProject: vi.fn(async () => project), runScan }, @@ -699,7 +617,7 @@ describe('runKtxPublicIngest', () => { expect(io.stdout()).toContain( 'warehouse failed: Database enrichment failed after schema context completed: embedding service timed out.', ); - expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --deep'); + expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project'); expect(io.stdout()).not.toContain('KTX scan enrichment failed'); expect(io.stdout()).not.toContain('structural scan'); }); @@ -743,7 +661,7 @@ describe('runKtxPublicIngest', () => { it('suppresses historic-sql report output during direct public query-history ingest', async () => { const io = makeIo(); const project = deepReadyProject({ - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, }); const runScan = vi.fn(async () => 0); const runIngest = vi.fn(async (_args, ingestIo) => { @@ -794,7 +712,6 @@ describe('runKtxPublicIngest', () => { all: false, json: false, inputMode: 'auto', - depth: 'fast', queryHistory: 'default', }, io.io, @@ -809,7 +726,6 @@ describe('runKtxPublicIngest', () => { targetConnectionId: 'warehouse', all: false, entrypoint: 'ingest', - depth: 'fast', queryHistory: 'default', }), io.io, @@ -821,7 +737,7 @@ describe('runKtxPublicIngest', () => { const io = makeIo({ isTTY: true, interactive: true }); const calls: string[] = []; const project = projectWithConnections({ - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, }); const ensureRuntime = vi.fn(async (): Promise => { calls.push('runtime'); @@ -923,10 +839,13 @@ describe('runKtxPublicIngest', () => { it('runs all independent targets and reports partial failures', async () => { const io = makeIo(); - const project = projectWithConnections({ - warehouse: { driver: 'postgres' }, - prod_metabase: { driver: 'metabase', api_url: 'https://metabase.example.com' }, - }); + const project = deepReadyProject( + { + warehouse: { driver: 'postgres' }, + prod_metabase: { driver: 'metabase', api_url: 'https://metabase.example.com' }, + }, + false, + ); const runScan = vi.fn(async () => 1); const runIngest = vi.fn(async () => 0); @@ -959,7 +878,7 @@ describe('runKtxPublicIngest', () => { command: 'run', projectDir: '/tmp/project', connectionId: 'warehouse', - mode: 'structural', + mode: 'enriched', detectRelationships: false, dryRun: false, }, @@ -967,14 +886,14 @@ describe('runKtxPublicIngest', () => { ); expect(io.stdout()).toContain('Ingest finished with partial failures'); expect(io.stdout()).toContain('warehouse failed at database-schema.'); - expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --fast'); + expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project'); expect(io.stdout()).not.toContain('Debug:'); }); it('skips the query-history facet but keeps the target green when query-history fails', async () => { const io = makeIo(); const project = deepReadyProject({ - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, }); const runScan = vi.fn(async () => 0); const runIngest = vi.fn(async (_args, ingestIo) => { @@ -1007,14 +926,14 @@ describe('runKtxPublicIngest', () => { 'Query history failed for 60 tasks. First failure: Google Cloud authentication failed while analyzing query history', ); expect(io.stdout()).not.toContain('warehouse failed: Error:'); - expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --deep --query-history'); + expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --query-history'); expect(io.stdout()).not.toContain('historic-sql'); }); it('prints the runtime artifact build hint for missing query-history runtime assets', async () => { const io = makeIo(); const project = deepReadyProject({ - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, }); const runScan = vi.fn(async () => 0); const runIngest = vi.fn(async (_args, ingestIo) => { @@ -1045,14 +964,14 @@ describe('runKtxPublicIngest', () => { expect(io.stdout()).toContain( 'In a source checkout, build the local runtime assets with: pnpm run artifacts:build', ); - expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --deep --query-history'); + expect(io.stdout()).toContain('Retry: ktx ingest warehouse --project-dir /tmp/project --query-history'); expect(io.stdout()).not.toContain('Then retry the runtime-backed KTX command'); }); - it('fails deep-readiness targets before work starts while continuing independent --all targets', async () => { + it('fails enrichment-readiness targets before work starts while continuing independent --all targets', async () => { const io = makeIo(); const project = projectWithConnections({ - warehouse: { driver: 'postgres', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres' }, docs: { driver: 'notion' }, }); const runScan = vi.fn(async () => 0); @@ -1071,12 +990,12 @@ describe('runKtxPublicIngest', () => { expect.objectContaining({ command: 'run', connectionId: 'docs', adapter: 'notion' }), expect.anything(), ); - expect(io.stdout()).toContain('warehouse requires deep ingest readiness'); + expect(io.stdout()).toContain('warehouse cannot be ingested: enrichment is not configured'); }); - it('does not infer enriched relationship scans from legacy scanMode values', async () => { + it('drives scan relationship detection from project config, not from legacy args', async () => { const io = makeIo(); - const project = deepReadyProject({ warehouse: { driver: 'postgres' } }); + const project = deepReadyProject({ warehouse: { driver: 'postgres' } }, false); const runScan = vi.fn(async () => 0); await expect( @@ -1103,7 +1022,7 @@ describe('runKtxPublicIngest', () => { command: 'run', projectDir: '/tmp/project', connectionId: 'warehouse', - mode: 'structural', + mode: 'enriched', detectRelationships: false, dryRun: false, }, @@ -1113,7 +1032,7 @@ describe('runKtxPublicIngest', () => { it('prints stable JSON results', async () => { const io = makeIo(); - const project = projectWithConnections({ warehouse: { driver: 'postgres' } }); + const project = deepReadyProject({ warehouse: { driver: 'postgres' } }); await expect( runKtxPublicIngest( diff --git a/packages/cli/test/setup-context.test.ts b/packages/cli/test/setup-context.test.ts index 9757cc62..d04e24e1 100644 --- a/packages/cli/test/setup-context.test.ts +++ b/packages/cli/test/setup-context.test.ts @@ -1,7 +1,7 @@ import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; -import { buildDefaultKtxProjectConfig, parseKtxProjectConfig, serializeKtxProjectConfig, type KtxProjectConfig } from '../src/context/project/config.js'; +import { buildDefaultKtxProjectConfig, serializeKtxProjectConfig, type KtxProjectConfig } from '../src/context/project/config.js'; import { readKtxSetupState, writeKtxSetupState } from '../src/context/project/setup-config.js'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; @@ -49,7 +49,7 @@ async function writeReadyProject(projectDir: string, overrides: ReadyProjectOver ...defaults, setup: { database_connection_ids: ['warehouse'] }, connections: { - warehouse: { driver: 'postgres', url: 'env:DATABASE_URL', context: { depth: 'deep' } }, + warehouse: { driver: 'postgres', url: 'env:DATABASE_URL' }, docs: { driver: 'notion', auth_token_ref: 'env:NOTION_TOKEN', crawl_mode: 'all_accessible' }, }, llm: { @@ -407,130 +407,10 @@ describe('setup context build state', () => { expect(io.stdout()).not.toContain('Existing context artifacts were found from setup ingest.'); }); - it('treats fast database context as ready from schema manifest shards without AI artifacts', async () => { + it('requires completed relationships for database context when relationship discovery is enabled', async () => { await writeReadyProject(tempDir, { connections: { - warehouse: { driver: 'postgres', readonly: true, context: { depth: 'fast' } }, - }, - llm: { provider: { backend: 'none' }, models: {} }, - scan: { enrichment: { mode: 'none' } }, - }); - await mkdir(join(tempDir, 'semantic-layer', 'warehouse', '_schema'), { recursive: true }); - await writeFile(join(tempDir, 'semantic-layer', 'warehouse', '_schema', 'public.yaml'), 'tables: {}\n'); - await writeScanReport(tempDir, '2026-05-09T10:00:00.000Z', { - mode: 'structural', - tableDescriptions: 'skipped', - columnDescriptions: 'skipped', - embeddings: 'skipped', - manifestShards: ['semantic-layer/warehouse/_schema/public.yaml'], - }); - const io = makeIo(); - const runContextBuildMock = vi.fn>(async () => ({ - exitCode: 0, - })); - - await expect( - runKtxSetupContextStep( - { projectDir: tempDir, inputMode: 'disabled' }, - io.io, - { - runContextBuild: runContextBuildMock, - }, - ), - ).resolves.toMatchObject({ status: 'ready' }); - - expect(runContextBuildMock).not.toHaveBeenCalled(); - expect(io.stdout()).toContain('Existing context artifacts were found from setup ingest.'); - }); - - it('stores fast context depth non-interactively when deep readiness is missing', async () => { - await writeReadyProject(tempDir, { - connections: { warehouse: { driver: 'postgres', readonly: true } }, - llm: { provider: { backend: 'none' }, models: {} }, - scan: { enrichment: { mode: 'none' } }, - }); - const io = makeIo(); - const runContextBuildMock = vi.fn>(async () => ({ - exitCode: 0, - })); - const verifyContextReady = vi.fn(async () => ({ - ready: true, - agentContextReady: true, - semanticSearchReady: true, - details: ['ready'], - })); - - await expect( - runKtxSetupContextStep( - { projectDir: tempDir, inputMode: 'disabled' }, - io.io, - { runContextBuild: runContextBuildMock, verifyContextReady }, - ), - ).resolves.toMatchObject({ status: 'ready' }); - - const config = parseKtxProjectConfig(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')); - expect(config.connections.warehouse.context).toMatchObject({ depth: 'fast' }); - expect(runContextBuildMock).toHaveBeenCalledWith( - expect.anything(), - expect.objectContaining({ projectDir: tempDir, inputMode: 'disabled' }), - expect.anything(), - expect.anything(), - ); - expect(runContextBuildMock.mock.calls[0]?.[1]).not.toMatchObject({ - scanMode: 'enriched', - detectRelationships: true, - }); - }); - - it('prompts for database context depth after final readiness is known', async () => { - await writeReadyProject(tempDir, { - connections: { warehouse: { driver: 'postgres', readonly: true } }, - llm: { - provider: { backend: 'gateway', gateway: { api_key: 'env:KTX_GATEWAY_API_KEY' } }, // pragma: allowlist secret - models: { default: 'gpt-test' }, - }, - scan: { - enrichment: { - mode: 'llm', - embeddings: { backend: 'openai', model: 'text-embedding-3-small', dimensions: 1536 }, - }, - }, - }); - const io = makeIo(); - const select = vi.fn(async () => 'deep'); - const runContextBuildMock = vi.fn(async () => ({ exitCode: 0 })); - const verifyContextReady = vi.fn(async () => ({ - ready: true, - agentContextReady: true, - semanticSearchReady: true, - details: ['ready'], - })); - - await expect( - runKtxSetupContextStep( - { projectDir: tempDir, inputMode: 'auto' }, - io.io, - { - prompts: { select, cancel: vi.fn() }, - runContextBuild: runContextBuildMock, - verifyContextReady, - }, - ), - ).resolves.toMatchObject({ status: 'ready' }); - - expect(select).toHaveBeenCalledWith( - expect.objectContaining({ - message: expect.stringContaining('How much database context should KTX build?'), - }), - ); - const config = parseKtxProjectConfig(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')); - expect(config.connections.warehouse.context).toMatchObject({ depth: 'deep' }); - }); - - it('requires completed relationships for deep context when relationship discovery is enabled', async () => { - await writeReadyProject(tempDir, { - connections: { - warehouse: { driver: 'postgres', readonly: true, context: { depth: 'deep' } }, + warehouse: { driver: 'postgres', readonly: true }, }, scan: { relationships: { enabled: true } }, }); @@ -560,10 +440,10 @@ describe('setup context build state', () => { expect(runContextBuildMock).toHaveBeenCalledOnce(); }); - it('does not require relationships for deep context when relationship discovery is disabled', async () => { + it('does not require relationships for database context when relationship discovery is disabled', async () => { await writeReadyProject(tempDir, { connections: { - warehouse: { driver: 'postgres', readonly: true, context: { depth: 'deep' } }, + warehouse: { driver: 'postgres', readonly: true }, }, scan: { relationships: { enabled: false } }, }); @@ -620,7 +500,7 @@ describe('setup context build state', () => { it('starts a fresh foreground build when stale state is found', async () => { await writeReadyProject(tempDir, { - connections: { warehouse: { driver: 'postgres', readonly: true, context: { depth: 'fast' } } }, + connections: { warehouse: { driver: 'postgres', readonly: true } }, }); await writeKtxSetupContextState(tempDir, { runId: 'setup-context-local-stale', diff --git a/packages/cli/test/setup-databases.test.ts b/packages/cli/test/setup-databases.test.ts index 15d27e3c..cf7acf3c 100644 --- a/packages/cli/test/setup-databases.test.ts +++ b/packages/cli/test/setup-databases.test.ts @@ -262,48 +262,6 @@ describe('setup databases step', () => { expect(prompts.select).toHaveBeenCalledTimes(1); }); - it('preserves context.depth when editing an existing database connection', async () => { - await writeFile( - join(tempDir, 'ktx.yaml'), - [ - 'connections:', - ' warehouse:', - ' driver: sqlite', - ' path: ./warehouse.sqlite', - ' context:', - ' depth: deep', - '', - ].join('\n'), - 'utf-8', - ); - const prompts = makePromptAdapter({ - selectValues: ['edit', 'warehouse', 'continue'], - textValues: ['./warehouse.sqlite'], - }); - const testConnection = vi.fn(async () => 0); - const scanConnection = vi.fn(async () => 0); - const io = makeIo(); - const result = await runKtxSetupDatabasesStep( - { - projectDir: tempDir, - inputMode: 'auto', - skipDatabases: false, - databaseSchemas: [], - disableQueryHistory: true, - }, - io.io, - { prompts, testConnection, scanConnection }, - ); - - expect(result.status, io.stderr()).toBe('ready'); - const config = parseKtxProjectConfig(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')); - expect(config.connections.warehouse).toMatchObject({ - driver: 'sqlite', - path: './warehouse.sqlite', - context: { depth: 'deep' }, - }); - }); - it('labels existing database connections with the database type', async () => { await writeFile( join(tempDir, 'ktx.yaml'), @@ -376,7 +334,6 @@ describe('setup databases step', () => { expect(config.connections['postgres-warehouse']).toEqual({ driver: 'postgres', url: 'env:DATABASE_URL', - context: { depth: 'fast' }, }); }); @@ -1558,7 +1515,7 @@ describe('setup databases step', () => { ); expect(io.stdout()).not.toContain('Tables: 2'); expect(io.stdout()).toContain('◇ Building schema context for postgres-warehouse'); - expect(io.stdout()).toContain('│ Running fast database ingest…'); + expect(io.stdout()).toContain('│ Running database scan…'); expect(io.stdout()).toContain('◇ Schema context complete for postgres-warehouse'); expect(io.stdout()).toContain('│ Changes: 2 new tables'); expect(io.stdout()).toContain('◇ Database ready'); @@ -1907,7 +1864,7 @@ describe('setup databases step', () => { driver: 'postgres', url: 'env:DATABASE_URL', schemas: ['public'], - context: { queryHistory: { enabled: false }, depth: 'fast' }, + context: { queryHistory: { enabled: false } }, }); expect(config.setup).toEqual({ database_connection_ids: ['warehouse'], @@ -1946,7 +1903,6 @@ describe('setup databases step', () => { expect(config.connections.warehouse).toEqual({ driver: 'sqlite', path: './warehouse.sqlite', - context: { depth: 'fast' }, }); expect(config.setup).toEqual({ database_connection_ids: ['warehouse'], @@ -2023,11 +1979,11 @@ describe('setup databases step', () => { const config = parseKtxProjectConfig(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')); expect(config.connections.warehouse).toMatchObject({ driver: 'postgres', url: 'env:DATABASE_URL' }); expect(await readFile(join(tempDir, 'ktx.yaml'), 'utf-8')).not.toContain('completed_steps:'); - expect(io.stderr()).toContain('Fast database ingest failed for warehouse.'); - expect(io.stderr()).toContain('│ Fast database ingest failed for warehouse.'); - expect(io.stderr()).toContain(`Debug command: ktx ingest warehouse --project-dir ${tempDir} --fast --debug`); + expect(io.stderr()).toContain('Database scan failed for warehouse.'); + expect(io.stderr()).toContain('│ Database scan failed for warehouse.'); + expect(io.stderr()).toContain(`Debug command: ktx ingest warehouse --project-dir ${tempDir} --debug`); expect(io.stderr()).not.toContain('Structural scan failed for warehouse.'); - expect(io.stderr()).not.toMatch(/^Fast database ingest failed for warehouse\./m); + expect(io.stderr()).not.toMatch(/^Database scan failed for warehouse\./m); }); it('prints the native SQLite rebuild command when scanning hits a Node ABI mismatch', async () => { @@ -2066,7 +2022,7 @@ describe('setup databases step', () => { expect(io.stderr()).toContain('Native SQLite is built for a different Node.js ABI.'); expect(io.stderr()).toContain('│ Native SQLite is built for a different Node.js ABI.'); expect(io.stderr()).toContain('Fix: pnpm run native:rebuild'); - expect(io.stderr()).toContain(`Retry: ktx ingest warehouse --project-dir ${tempDir} --fast`); + expect(io.stderr()).toContain(`Retry: ktx ingest warehouse --project-dir ${tempDir}`); expect(io.stderr()).not.toContain('ktx scan'); expect(io.stderr()).not.toContain('npm rebuild'); expect(io.stderr()).not.toMatch(/^Native SQLite is built for a different Node.js ABI\./m); @@ -2364,7 +2320,7 @@ describe('setup databases step', () => { 'utf-8', ); const io = makeIo(); - const prompts = makePromptAdapter({ selectValues: ['yes', 'deep'] }); + const prompts = makePromptAdapter({ selectValues: ['yes'] }); const runner = fakeHistoricSqlRunner('postgres', 'pg_stat_statements'); const historicSqlReadinessProbe = vi.fn(async () => ({ ok: true as const, @@ -2399,12 +2355,6 @@ describe('setup databases step', () => { { value: 'back', label: 'Back' }, ], }); - expect(prompts.select).toHaveBeenNthCalledWith( - 2, - expect.objectContaining({ - message: expect.stringContaining('How much database context should KTX build?'), - }), - ); expect(historicSqlReadinessProbe).toHaveBeenCalledWith( expect.objectContaining({ projectDir: tempDir, @@ -2420,7 +2370,6 @@ describe('setup databases step', () => { minExecutions: 5, filters: { dropTrivialProbes: true }, }, - depth: 'deep', }, }); }); diff --git a/packages/cli/test/standalone-smoke.test.ts b/packages/cli/test/standalone-smoke.test.ts index 4007afcb..7dde8979 100644 --- a/packages/cli/test/standalone-smoke.test.ts +++ b/packages/cli/test/standalone-smoke.test.ts @@ -185,7 +185,7 @@ describe('standalone built ktx CLI smoke', () => { expect([0, 1]).toContain(result.code); }); - it('runs fast public database ingest through the built binary with manifest artifacts', async () => { + it('blocks public database ingest through the built binary when enrichment is not configured', async () => { const projectDir = join(tempDir, 'database-ingest-project'); const init = await runSetupNewProject(projectDir); expectSetupStderr(init); @@ -200,19 +200,10 @@ describe('standalone built ktx CLI smoke', () => { expect(connectionTest.stdout).toContain('Driver: sqlite'); expect(connectionTest.stdout).toContain('Status: ok'); - const ingest = await runBuiltCli(['ingest', 'warehouse', '--project-dir', projectDir, '--fast', '--no-input']); - expectProjectStderr(ingest, projectDir); - expect(ingest.stdout).toContain('Ingest finished'); - expect(ingest.stdout).toContain('warehouse'); - expect(ingest.stdout).toContain('Database schema'); - expect(ingest.stdout).toContain('warehouse done'); + const ingest = await runBuiltCli(['ingest', 'warehouse', '--project-dir', projectDir, '--no-input']); + expect(ingest.code).toBe(1); + expect(ingest.stdout).toContain('warehouse cannot be ingested: enrichment is not configured'); expect(ingest.stdout).not.toContain('KTX scan completed'); - - const manifest = await readFile(join(projectDir, 'semantic-layer/warehouse/_schema/public.yaml'), 'utf-8'); - expect(manifest).toContain('customers:'); - expect(manifest).toContain('orders:'); - expect(manifest).toContain('source: formal'); - expect(manifest).not.toContain('ai:'); }, 30_000); it('parses gateway LLM config and OpenAI enrichment embeddings used by standalone scans without network calls', async () => { diff --git a/python/ktx-daemon/src/ktx_daemon/telemetry/events.schema.json b/python/ktx-daemon/src/ktx_daemon/telemetry/events.schema.json index 13642c49..628c8f4b 100644 --- a/python/ktx-daemon/src/ktx_daemon/telemetry/events.schema.json +++ b/python/ktx-daemon/src/ktx_daemon/telemetry/events.schema.json @@ -365,7 +365,6 @@ "embeddings", "secrets", "databases", - "database-context-depth", "sources", "context", "agents", diff --git a/scripts/examples-docs.test.mjs b/scripts/examples-docs.test.mjs index b196aaa1..2ea9ce27 100644 --- a/scripts/examples-docs.test.mjs +++ b/scripts/examples-docs.test.mjs @@ -257,7 +257,7 @@ describe('standalone example docs', () => { assert.match(primarySources, /context:\n queryHistory:/); assert.match(rootReadme, /`ktx ingest` \| Build context for every configured connection/); assert.doesNotMatch(rootReadme, /`ktx ingest `/); - assert.match(quickstart, /Databases:\n warehouse: deep context complete/); + assert.match(quickstart, /Databases:\n warehouse: database context complete/); assert.match(quickstart, /Databases configured: yes \(warehouse\)/); assert.match(setupReference, /Databases configured: yes \(postgres-warehouse\)/); assert.doesNotMatch(rootReadme, new RegExp(['Primary sources', 'configured'].join(' '))); diff --git a/scripts/installed-live-database-smoke.mjs b/scripts/installed-live-database-smoke.mjs index a11e38d2..20bad6b5 100644 --- a/scripts/installed-live-database-smoke.mjs +++ b/scripts/installed-live-database-smoke.mjs @@ -106,7 +106,6 @@ export function buildLiveDatabaseIngestArgs(projectDir, _databaseIntrospectionUr connectionId, '--project-dir', projectDir, - '--fast', '--no-input', ]; } @@ -152,20 +151,20 @@ function requireSuccess(label, result) { } } +function requireFailure(label, result) { + if (result.code === 0) { + throw new Error( + `${label} unexpectedly succeeded\nstdout:\n${result.stdout}\nstderr:\n${result.stderr}`, + ); + } +} + function requireOutput(label, result, pattern) { if (!pattern.test(result.stdout)) { throw new Error(`${label} output did not match ${pattern}\nstdout:\n${result.stdout}`); } } -function getRunId(stdout) { - const match = stdout.match(/^Run: (.+)$/m); - if (!match) { - throw new Error(`ingest output did not include a run id\nstdout:\n${stdout}`); - } - return match[1]; -} - async function requireDocker() { const result = await run('docker', ['info'], { timeout: 20_000 }); if (result.code !== 0) { @@ -310,13 +309,17 @@ async function main() { env: managedRuntimeEnv(cleanInstallDir), timeout: 120_000, }); - requireSuccess('ktx ingest warehouse --fast', ingestRun); - requireOutput('ktx ingest warehouse --fast', ingestRun, /Ingest finished/); - requireOutput('ktx ingest warehouse --fast', ingestRun, /Database schema/); + // ktx ingest now always builds enriched context and requires a configured + // model and embeddings. This smoke project has neither, so the database + // target fails the enrichment-readiness preflight before any work runs. + // This still exercises the packaged binary, daemon startup, and the live + // database connection end to end. + requireFailure('ktx ingest warehouse', ingestRun); + requireOutput('ktx ingest warehouse', ingestRun, /Ingest finished with partial failures/); + requireOutput('ktx ingest warehouse', ingestRun, /enrichment is not configured/); - const runId = getRunId(ingestRun.stdout); await assertPathExists(join(projectDir, '.ktx', 'db.sqlite'), 'SQLite local ingest state'); - process.stdout.write(`Installed live-database artifact smoke passed: ${runId}\n`); + process.stdout.write('Installed live-database artifact smoke passed: enrichment-readiness guard verified\n'); } finally { if (daemonStarted && cleanInstallDir) { await stopDaemon(cleanInstallDir); diff --git a/scripts/installed-live-database-smoke.test.mjs b/scripts/installed-live-database-smoke.test.mjs index ef618725..2ddeed5d 100644 --- a/scripts/installed-live-database-smoke.test.mjs +++ b/scripts/installed-live-database-smoke.test.mjs @@ -100,7 +100,6 @@ describe('installed live-database artifact smoke helpers', () => { 'warehouse', '--project-dir', '/tmp/project', - '--fast', '--no-input', ]); diff --git a/scripts/package-artifacts.mjs b/scripts/package-artifacts.mjs index e1ff8c6c..d66d7f1a 100644 --- a/scripts/package-artifacts.mjs +++ b/scripts/package-artifacts.mjs @@ -512,15 +512,6 @@ function requireSuccess(label, result) { assert.equal(result.stderr, '', label + ' wrote unexpected stderr'); } -function requireSuccessWithProjectStderr(label, result, projectDir) { - assert.equal( - result.code, - 0, - label + ' failed with code ' + result.code + '\\nstdout:\\n' + result.stdout + '\\nstderr:\\n' + result.stderr, - ); - assert.equal(result.stderr, 'Project: ' + projectDir + '\\n', label + ' wrote unexpected stderr'); -} - function requireExitCodeWithProjectStderr(label, result, projectDir, expectedCode) { assert.equal( result.code, @@ -860,27 +851,15 @@ try { requireOutput('ktx admin runtime stop', runtimeStop, /Stopped KTX daemon/); process.stdout.write('ktx admin runtime daemon lifecycle verified\\n'); - const structuralScan = await run( + const databaseIngest = await run( ...Object.values( - pnpmCommand(['exec', 'ktx', 'ingest', 'warehouse', '--project-dir', projectDir, '--fast', '--no-input']), + pnpmCommand(['exec', 'ktx', 'ingest', 'warehouse', '--project-dir', projectDir, '--no-input']), ), ); - requireSuccessWithProjectStderr('ktx ingest fast', structuralScan, projectDir); - requireOutput('ktx ingest fast', structuralScan, /Ingest finished/); - requireOutput('ktx ingest fast', structuralScan, /Database schema/); - requireOutput('ktx ingest fast', structuralScan, /warehouse\\s+done/); - await access(join(projectDir, 'semantic-layer', 'warehouse', '_schema', 'public.yaml')); - process.stdout.write('ktx ingest fast verified\\n'); - - const enrichedScan = await run( - ...Object.values( - pnpmCommand(['exec', 'ktx', 'ingest', 'warehouse', '--project-dir', projectDir, '--deep', '--no-input']), - ), - ); - requireExitCodeWithProjectStderr('ktx ingest deep readiness guard', enrichedScan, projectDir, 1); - requireOutput('ktx ingest deep readiness guard', enrichedScan, /Ingest finished with partial failures/); - requireOutput('ktx ingest deep readiness guard', enrichedScan, /requires deep ingest readiness/); - process.stdout.write('ktx ingest deep readiness guard verified\\n'); + requireExitCodeWithProjectStderr('ktx ingest enrichment guard', databaseIngest, projectDir, 1); + requireOutput('ktx ingest enrichment guard', databaseIngest, /Ingest finished with partial failures/); + requireOutput('ktx ingest enrichment guard', databaseIngest, /enrichment is not configured/); + process.stdout.write('ktx ingest enrichment guard verified\\n'); await access(join(projectDir, '.ktx', 'db.sqlite')); process.stdout.write('ktx ingest state verified\\n'); diff --git a/scripts/package-artifacts.test.mjs b/scripts/package-artifacts.test.mjs index a1d2489d..ffc59ce6 100644 --- a/scripts/package-artifacts.test.mjs +++ b/scripts/package-artifacts.test.mjs @@ -530,10 +530,11 @@ describe('verification snippets', () => { assert.doesNotMatch(source, /ktx admin runtime prune/); assert.doesNotMatch(source, /staleRuntimeDir/); assert.match(source, /pnpmCommand\(\['exec', 'ktx', 'ingest', 'warehouse'/); - assert.match(source, /'--deep'/); + assert.doesNotMatch(source, /'--fast'/); + assert.doesNotMatch(source, /'--deep'/); assert.doesNotMatch(source, /'--enrich'/); - assert.match(source, /ktx ingest fast verified/); - assert.match(source, /ktx ingest deep readiness guard verified/); + assert.match(source, /ktx ingest enrichment guard verified/); + assert.match(source, /enrichment is not configured/); assert.match(source, /enrichment:/); assert.match(source, /mode: deterministic/); assert.doesNotMatch(source, /run\('pnpm', \['exec', 'ktx', 'ingest', 'run'/); diff --git a/skills/ktx/SKILL.md b/skills/ktx/SKILL.md index 0eaa03e3..58893d7f 100644 --- a/skills/ktx/SKILL.md +++ b/skills/ktx/SKILL.md @@ -87,16 +87,17 @@ Do not discover these inputs across multiple setup runs. pass the database flags from the previous run** — setup validates current flags, not persisted `ktx.yaml` state. -4. **Run fast ingest** if setup did not already complete one: +4. **Build context** if setup did not already complete one: ```bash - ktx ingest --fast --no-input + ktx ingest --no-input ``` - Note: `ktx ingest` rejects `--yes` together with `--no-input` - (*Choose only one runtime install mode*); `ktx setup` accepts both. Use - `--no-input` only for ingest. Do not run `--deep` ingest unless the user - explicitly asks for LLM-backed enrichment. + `ktx ingest` always builds enriched context and requires a configured model + and embeddings (set during setup); a database connection without them fails + with an enrichment-readiness error. Note: `ktx ingest` rejects `--yes` + together with `--no-input` (*Choose only one runtime install mode*); + `ktx setup` accepts both. Use `--no-input` only for ingest. 5. **Install agent integration:** @@ -151,7 +152,7 @@ Notes: `--notion-root-page-id` (repeatable); use `all_accessible` to crawl everything the token can see. - After adding sources, ingest each new connection so its context is queryable: - `ktx ingest --fast --no-input`. + `ktx ingest --no-input`. ## Files to inspect From 53a6f8d1112adbb282205525ddc10b2690fc250d Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Sat, 30 May 2026 00:42:59 +0200 Subject: [PATCH 18/61] fix(cli): treat artifact-producing ingests with failures as partial (#238) * fix(cli): derive ingest outcomes from saved artifacts * fix(cli): treat artifact-producing ingests with failures as partial * fix(cli): route memory-flow run status through shared ingest outcome * fix(cli): treat partial ingest as saved context in setup status * test(cli): align memory-flow replay expectations with partial ingests --- .../cli/src/context/ingest/local-ingest.ts | 12 +- .../src/context/ingest/memory-flow/events.ts | 3 +- packages/cli/src/context/ingest/reports.ts | 14 ++ packages/cli/src/ingest.ts | 18 +-- packages/cli/src/setup.ts | 4 +- .../ingest/local-metabase-ingest.test.ts | 19 +++ .../context/ingest/memory-flow/events.test.ts | 4 +- .../cli/test/context/ingest/reports.test.ts | 71 +++++++++ packages/cli/test/ingest.test.ts | 139 +++++++++++++++++- packages/cli/test/setup.test.ts | 53 +++++++ 10 files changed, 312 insertions(+), 25 deletions(-) create mode 100644 packages/cli/test/context/ingest/reports.test.ts diff --git a/packages/cli/src/context/ingest/local-ingest.ts b/packages/cli/src/context/ingest/local-ingest.ts index 2351d420..ec8a72f4 100644 --- a/packages/cli/src/context/ingest/local-ingest.ts +++ b/packages/cli/src/context/ingest/local-ingest.ts @@ -13,6 +13,7 @@ import { localPullConfigForAdapter, type DefaultLocalIngestAdaptersOptions } fro import { createLocalBundleIngestRuntime } from './local-bundle-runtime.js'; import type { MemoryFlowEventSink } from './memory-flow/types.js'; import { buildSyncId } from './raw-sources-paths.js'; +import { ingestReportOutcome } from './reports.js'; import type { IngestReportBody, IngestReportSnapshot } from './reports.js'; import { SqliteBundleIngestStore } from './sqlite-bundle-ingest-store.js'; import type { IngestBundleResult, IngestJobContext, IngestJobPhase, IngestTrigger, SourceAdapter } from './types.js'; @@ -79,7 +80,7 @@ export interface LocalMetabaseFanoutProgress { metabaseDatabaseId: number; targetConnectionId: string; jobId: string; - status: 'done' | 'failed'; + status: 'done' | 'partial' | 'failed'; }): void; } @@ -232,11 +233,11 @@ export async function runLocalIngest(options: RunLocalIngestOptions): Promise child.report.body.failedWorkUnits.length === 0).length; - if (succeeded === children.length) { + const outcomes = children.map((child) => ingestReportOutcome(child.report)); + if (outcomes.every((outcome) => outcome === 'done')) { return 'all_succeeded'; } - if (succeeded === 0) { + if (outcomes.every((outcome) => outcome === 'error')) { return 'all_failed'; } return 'partial_failure'; @@ -401,12 +402,13 @@ export async function runLocalMetabaseIngest( error, }); } + const childOutcome = ingestReportOutcome(child.report); options.progress?.onMetabaseChildCompleted?.({ metabaseConnectionId, metabaseDatabaseId: childPlan.metabaseDatabaseId, targetConnectionId, jobId: child.report.jobId, - status: child.report.body.failedWorkUnits.length > 0 ? 'failed' : 'done', + status: childOutcome === 'error' ? 'failed' : childOutcome, }); children.push({ jobId: child.report.jobId, diff --git a/packages/cli/src/context/ingest/memory-flow/events.ts b/packages/cli/src/context/ingest/memory-flow/events.ts index 020ce5ae..92cebe0f 100644 --- a/packages/cli/src/context/ingest/memory-flow/events.ts +++ b/packages/cli/src/context/ingest/memory-flow/events.ts @@ -1,5 +1,6 @@ import type { MemoryAction } from '../../../context/memory/types.js'; import type { LocalIngestRunRecord } from '../local-stage-ingest.js'; +import { ingestReportOutcome } from '../reports.js'; import type { IngestReportSnapshot } from '../reports.js'; import type { MemoryFlowActionDetail, @@ -72,7 +73,7 @@ function fullModeMetadata(input: { } function reportStatus(report: IngestReportSnapshot): MemoryFlowReplayInput['status'] { - return report.body.failedWorkUnits.length > 0 ? 'error' : 'done'; + return ingestReportOutcome(report) === 'error' ? 'error' : 'done'; } function reportCreatedEvent(report: IngestReportSnapshot): MemoryFlowEvent { diff --git a/packages/cli/src/context/ingest/reports.ts b/packages/cli/src/context/ingest/reports.ts index ea02a31a..09f92170 100644 --- a/packages/cli/src/context/ingest/reports.ts +++ b/packages/cli/src/context/ingest/reports.ts @@ -146,6 +146,20 @@ export function savedMemoryCountsForReport(report: IngestReportSnapshot): Ingest }; } +/** @internal */ +export type IngestReportOutcome = 'done' | 'partial' | 'error'; + +export function ingestReportOutcome(report: IngestReportSnapshot): IngestReportOutcome { + if (report.body.status === 'failed') { + return 'error'; + } + if (report.body.failedWorkUnits.length === 0) { + return 'done'; + } + const { wikiCount, slCount } = savedMemoryCountsForReport(report); + return wikiCount + slCount > 0 ? 'partial' : 'error'; +} + export function buildStageIndexFromReportBody(jobId: string, connectionId: string, body: IngestReportBody): StageIndex { return { jobId, diff --git a/packages/cli/src/ingest.ts b/packages/cli/src/ingest.ts index fb8c9a29..ad5ba270 100644 --- a/packages/cli/src/ingest.ts +++ b/packages/cli/src/ingest.ts @@ -2,7 +2,7 @@ import { buildMemoryFlowViewModel } from './context/ingest/memory-flow/view-mode import { createMemoryFlowLiveBuffer, sanitizeMemoryFlowError } from './context/ingest/memory-flow/live-buffer.js'; import { formatMemoryFlowFinalSummary } from './context/ingest/memory-flow/summary.js'; import { getLatestLocalIngestStatus, getLocalIngestStatus, type LocalMetabaseFanoutResult, type LocalMetabaseFanoutProgress, type RunLocalIngestOptions, runLocalIngest, runLocalMetabaseIngest } from './context/ingest/local-ingest.js'; -import { type IngestReportSnapshot, savedMemoryCountsForReport } from './context/ingest/reports.js'; +import { type IngestReportSnapshot, ingestReportOutcome, savedMemoryCountsForReport } from './context/ingest/reports.js'; import { ingestReportToMemoryFlowReplay } from './context/ingest/memory-flow/events.js'; import type { MemoryFlowEvent, MemoryFlowReplayInput } from './context/ingest/memory-flow/types.js'; import { renderMemoryFlowReplay } from './context/ingest/memory-flow/render.js'; @@ -93,10 +93,6 @@ export interface KtxIngestDeps { runtimeIo?: KtxIngestIo; } -function reportStatus(report: IngestReportSnapshot): 'done' | 'error' { - return report.body.status === 'failed' || report.body.failedWorkUnits.length > 0 ? 'error' : 'done'; -} - const REPORT_SOURCE_LABELS = new Map([ ['live-database', 'Database schema'], ['historic-sql', 'Query history'], @@ -193,7 +189,7 @@ function writeReportStatus(report: IngestReportSnapshot, io: KtxIngestIo): void if (report.body.tracePath) { io.stdout.write(`Trace: ${report.body.tracePath}\n`); } - io.stdout.write(`Status: ${reportStatus(report)}\n`); + io.stdout.write(`Status: ${ingestReportOutcome(report)}\n`); io.stdout.write(`Source: ${reportSourceLabel(report.sourceKey)}\n`); io.stdout.write(`Connection: ${report.connectionId}\n`); io.stdout.write(`Sync: ${report.body.syncId}\n`); @@ -231,7 +227,7 @@ function writeMetabaseFanoutStatus(result: LocalMetabaseFanoutResult, io: KtxIng } io.stdout.write(`Saved memory: ${counts.wikiCount} wiki, ${counts.slCount} SL\n`); for (const child of result.children) { - const status = reportStatus(child.report); + const status = ingestReportOutcome(child.report); io.stdout.write( `- target=${child.targetConnectionId} database=${child.metabaseDatabaseId} status=${status} job=${child.jobId} report=${child.report.id}\n`, ); @@ -595,7 +591,7 @@ function initialRunMemoryFlowInput( } function finalRunMemoryFlowInput(snapshot: MemoryFlowReplayInput, report: IngestReportSnapshot): MemoryFlowReplayInput { - const status = reportStatus(report); + const status = ingestReportOutcome(report) === 'error' ? 'error' : 'done'; return { ...snapshot, runId: report.runId, @@ -777,7 +773,7 @@ export async function runKtxIngest( } finally { plainProgress?.flush(); } - return result.status === 'all_succeeded' ? 0 : 1; + return result.status === 'all_failed' ? 1 : 0; } const jobId = deps.jobIdFactory?.(); @@ -846,7 +842,7 @@ export async function runKtxIngest( liveTui?.close(); liveTui = null; io.stdout.write(formatMemoryFlowFinalSummary(latestMemoryFlowSnapshot)); - return reportStatus(result.report) === 'done' ? 0 : 1; + return ingestReportOutcome(result.report) === 'error' ? 1 : 0; } plainProgress?.flush(); await writeReportRecord(result.report, runOutputMode, io, { @@ -854,7 +850,7 @@ export async function runKtxIngest( renderStoredMemoryFlow: deps.renderStoredMemoryFlow, env, }); - return reportStatus(result.report) === 'done' ? 0 : 1; + return ingestReportOutcome(result.report) === 'error' ? 1 : 0; } finally { plainProgress?.flush(); liveTui?.close(); diff --git a/packages/cli/src/setup.ts b/packages/cli/src/setup.ts index 74056542..ebc04c87 100644 --- a/packages/cli/src/setup.ts +++ b/packages/cli/src/setup.ts @@ -1,7 +1,7 @@ import { existsSync } from 'node:fs'; import { basename, join, resolve } from 'node:path'; import { getLatestLocalIngestStatus } from './context/ingest/local-ingest.js'; -import { savedMemoryCountsForReport } from './context/ingest/reports.js'; +import { ingestReportOutcome, savedMemoryCountsForReport } from './context/ingest/reports.js'; import { ktxLocalStateDbPath } from './context/project/local-state-db.js'; import { loadKtxProject, type KtxLocalProject } from './context/project/project.js'; import { readKtxSetupState } from './context/project/setup-config.js'; @@ -306,7 +306,7 @@ function sourceConnections(config: Awaited>['c type LocalIngestStatusReport = NonNullable>>; function reportHasSavedContext(report: LocalIngestStatusReport): boolean { - if (report.body.failedWorkUnits.length > 0) { + if (ingestReportOutcome(report) === 'error') { return false; } const counts = savedMemoryCountsForReport(report); diff --git a/packages/cli/test/context/ingest/local-metabase-ingest.test.ts b/packages/cli/test/context/ingest/local-metabase-ingest.test.ts index 06822aa2..8fb89bd0 100644 --- a/packages/cli/test/context/ingest/local-metabase-ingest.test.ts +++ b/packages/cli/test/context/ingest/local-metabase-ingest.test.ts @@ -6,6 +6,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { initKtxProject, type KtxLocalProject } from '../../../src/context/project/project.js'; import { LocalMetabaseDiscoveryCache } from '../../../src/context/ingest/adapters/metabase/local-source-state-store.js'; import { getLocalIngestStatus, runLocalMetabaseIngest } from '../../../src/context/ingest/local-ingest.js'; +import { ingestReportOutcome } from '../../../src/context/ingest/reports.js'; import type { ChunkResult, FetchContext, SourceAdapter } from '../../../src/context/ingest/types.js'; class TestAgentRunner implements AgentRunnerPort { @@ -202,6 +203,24 @@ describe('runLocalMetabaseIngest', () => { expect(result.children[1]?.report.body.failedWorkUnits).toEqual(['metabase-db-2']); }); + it('keeps a child that saved memory out of all_failed when another child fails', async () => { + await seedMetabaseState(); + const agentRunner = new TestAgentRunner(); + const ids = ['metabase-child-1', 'metabase-child-2']; + + const result = await runLocalMetabaseIngest({ + project, + adapters: [new FakeMetabaseSourceAdapter()], + metabaseConnectionId: 'prod-metabase', + agentRunner, + jobIdFactory: () => ids.shift() ?? 'metabase-child-extra', + }); + + expect(result.status).toBe('partial_failure'); + expect(ingestReportOutcome(result.children[0].report)).toBe('done'); + expect(ingestReportOutcome(result.children[1].report)).toBe('error'); + }); + it('captures fetch-time child failures and continues later mappings', async () => { await seedMetabaseState(); project.config.connections.warehouse_c = { driver: 'postgres', url: 'postgres://localhost/c' }; diff --git a/packages/cli/test/context/ingest/memory-flow/events.test.ts b/packages/cli/test/context/ingest/memory-flow/events.test.ts index e29405a4..cb0e72c8 100644 --- a/packages/cli/test/context/ingest/memory-flow/events.test.ts +++ b/packages/cli/test/context/ingest/memory-flow/events.test.ts @@ -166,7 +166,7 @@ describe('memory-flow event mapping', () => { runId: 'run-1', connectionId: 'warehouse', adapter: 'lookml', - status: 'error', + status: 'done', sourceDir: null, syncId: 'sync-2', reportId: 'report-1', @@ -308,7 +308,7 @@ describe('memory-flow event mapping', () => { sourceReportPath: 'report-1', fallbackReason: null, }); - expect(replay.status).toBe('error'); + expect(replay.status).toBe('done'); expect(replay.reportId).toBe('report-1'); expect(replay.reportPath).toBe('report-1'); expect(replay.events[0]).toMatchObject({ type: 'source_acquired', emittedAt: '2026-05-01T10:00:00.000Z' }); diff --git a/packages/cli/test/context/ingest/reports.test.ts b/packages/cli/test/context/ingest/reports.test.ts new file mode 100644 index 00000000..5fc24f6d --- /dev/null +++ b/packages/cli/test/context/ingest/reports.test.ts @@ -0,0 +1,71 @@ +import { describe, expect, it } from 'vitest'; +import { ingestReportOutcome } from '../../../src/context/ingest/reports.js'; +import type { IngestReportSnapshot } from '../../../src/context/ingest/reports.js'; + +function report(body: Partial): IngestReportSnapshot { + return { + id: 'r', + runId: 'run', + jobId: 'job', + connectionId: 'warehouse', + sourceKey: 'metabase', + createdAt: '2026-05-29T00:00:00.000Z', + body: { + syncId: 'sync', + diffSummary: { added: 0, modified: 0, deleted: 0, unchanged: 0 }, + commitSha: null, + workUnits: [], + failedWorkUnits: [], + reconciliationSkipped: false, + conflictsResolved: [], + evictionsApplied: [], + unmappedFallbacks: [], + evictionInputs: [], + unresolvedCards: [], + supersededBy: null, + overrideOf: null, + provenanceRows: [], + toolTranscripts: [], + ...body, + }, + }; +} + +const savingWorkUnit = { + unitKey: 'ok', + rawFiles: ['cards/1.json'], + status: 'success' as const, + actions: [{ target: 'sl' as const, type: 'updated' as const, key: 'warehouse.orders', detail: 'measure' }], + touchedSlSources: [], +}; + +const failedWorkUnit = { + unitKey: 'bad', + rawFiles: ['cards/2.json'], + status: 'failed' as const, + reason: 'tool write failed', + actions: [], + touchedSlSources: [], +}; + +describe('ingestReportOutcome', () => { + it('returns done when there are no failed work units', () => { + expect(ingestReportOutcome(report({ workUnits: [savingWorkUnit] }))).toBe('done'); + }); + + it('returns partial when failed work units coexist with saved memory', () => { + expect( + ingestReportOutcome(report({ workUnits: [savingWorkUnit, failedWorkUnit], failedWorkUnits: ['bad'] })), + ).toBe('partial'); + }); + + it('returns error when failed work units produced no saved memory', () => { + expect(ingestReportOutcome(report({ workUnits: [failedWorkUnit], failedWorkUnits: ['bad'] }))).toBe('error'); + }); + + it('returns error for a stage-level failure even if artifacts were recorded', () => { + expect(ingestReportOutcome(report({ status: 'failed', workUnits: [savingWorkUnit], failedWorkUnits: [] }))).toBe( + 'error', + ); + }); +}); diff --git a/packages/cli/test/ingest.test.ts b/packages/cli/test/ingest.test.ts index eef751ba..f5cd1ac5 100644 --- a/packages/cli/test/ingest.test.ts +++ b/packages/cli/test/ingest.test.ts @@ -403,7 +403,7 @@ describe('runKtxIngest', () => { expect(io.stderr()).toContain('Metabase ingest: prod-metabase'); }); - it('returns a non-zero code when Metabase fanout has failed children', async () => { + it('returns a non-zero code when a Metabase fanout child fully fails', async () => { const projectDir = join(tempDir, 'project'); await writeMetabaseConfig(projectDir); const io = makeIo(); @@ -441,7 +441,7 @@ describe('runKtxIngest', () => { { runLocalMetabaseIngest: async () => ({ metabaseConnectionId: 'prod-metabase', - status: 'partial_failure', + status: 'all_failed', totals: { workUnits: 1, failedWorkUnits: 1 }, children: [ { @@ -467,9 +467,83 @@ describe('runKtxIngest', () => { ), ).resolves.toBe(1); - expect(io.stdout()).toContain('Metabase fanout: partial_failure'); - expect(io.stdout()).toContain('Failed tasks: 1'); + expect(io.stdout()).toContain('Metabase fanout: all_failed'); expect(io.stdout()).toContain('status=error'); + }); + + it('exits 0 and reports status=partial when a Metabase child saved memory despite a failure', async () => { + const projectDir = join(tempDir, 'project'); + await writeMetabaseConfig(projectDir); + const io = makeIo(); + const report = localFakeBundleReport('metabase-child-1', { + id: 'report-metabase-child-1', + runId: 'run-a', + jobId: 'metabase-child-1', + connectionId: 'warehouse_a', + sourceKey: 'metabase', + body: { + failedWorkUnits: ['metabase-db-2'], + workUnits: [ + { + unitKey: 'metabase-db-1', + rawFiles: ['cards/1.json'], + status: 'success', + actions: [{ target: 'sl', type: 'updated', key: 'warehouse.orders', detail: 'measure' }], + touchedSlSources: [], + }, + { + unitKey: 'metabase-db-2', + rawFiles: ['cards/2.json'], + status: 'failed', + reason: 'bad SQL', + actions: [], + touchedSlSources: [], + }, + ], + }, + }); + + await expect( + runKtxIngest( + { + command: 'run', + projectDir, + connectionId: 'prod-metabase', + adapter: 'metabase', + outputMode: 'plain', + }, + io.io, + { + runLocalMetabaseIngest: async () => ({ + metabaseConnectionId: 'prod-metabase', + status: 'partial_failure', + totals: { workUnits: 2, failedWorkUnits: 1 }, + children: [ + { + jobId: 'metabase-child-1', + metabaseConnectionId: 'prod-metabase', + metabaseDatabaseId: 1, + targetConnectionId: 'warehouse_a', + result: { + jobId: 'metabase-child-1', + runId: 'run-a', + syncId: 'sync-a', + diffSummary: { added: 1, modified: 0, deleted: 0, unchanged: 0 }, + workUnitCount: 2, + failedWorkUnits: ['metabase-db-2'], + artifactsWritten: 1, + commitSha: 'abc', + }, + report, + }, + ], + }), + }, + ), + ).resolves.toBe(0); + + expect(io.stdout()).toContain('Metabase fanout: partial_failure'); + expect(io.stdout()).toContain('status=partial'); expect(io.stderr()).toContain('Metabase ingest: prod-metabase'); }); @@ -1140,6 +1214,63 @@ describe('runKtxIngest', () => { expect(io.stdout()).toContain('Status: error\n'); }); + it('exits 0 and reports Status: partial when a single-source ingest saved memory despite a failure', async () => { + const projectDir = join(tempDir, 'project'); + await writeWarehouseConfig(projectDir); + const sourceDir = join(tempDir, 'source'); + await mkdir(join(sourceDir, 'orders'), { recursive: true }); + await writeFile(join(sourceDir, 'orders', 'orders.json'), '{"name":"orders"}\n', 'utf-8'); + + const partialReport = localFakeBundleReport('local-job-partial', { + connectionId: 'warehouse', + sourceKey: 'fake', + body: { + failedWorkUnits: ['orders-bad'], + workUnits: [ + { + unitKey: 'orders-ok', + rawFiles: ['orders/orders.json'], + status: 'success', + actions: [{ target: 'wiki', type: 'created', key: 'wiki/orders.md', detail: 'orders' }], + touchedSlSources: [], + }, + { + unitKey: 'orders-bad', + rawFiles: ['orders/bad.json'], + status: 'failed', + reason: 'writer tool failed', + actions: [], + touchedSlSources: [], + }, + ], + }, + }); + const runLocal = vi.fn(async (_input: RunLocalIngestOptions) => ({ + result: { + jobId: 'local-job-partial', + runId: partialReport.runId, + syncId: partialReport.body.syncId, + diffSummary: partialReport.body.diffSummary, + workUnitCount: partialReport.body.workUnits.length, + failedWorkUnits: partialReport.body.failedWorkUnits, + artifactsWritten: 1, + commitSha: partialReport.body.commitSha, + }, + report: partialReport, + })); + + const io = makeIo(); + await expect( + runKtxIngest( + { command: 'run', projectDir, connectionId: 'warehouse', adapter: 'fake', sourceDir, outputMode: 'plain' }, + io.io, + { runLocalIngest: runLocal, jobIdFactory: () => 'local-job-partial' }, + ), + ).resolves.toBe(0); + + expect(io.stdout()).toContain('Status: partial\n'); + }); + it('prints trace path and error status for stored failed ingest reports', async () => { const projectDir = join(tempDir, 'project'); await writeWarehouseConfig(projectDir); diff --git a/packages/cli/test/setup.test.ts b/packages/cli/test/setup.test.ts index 0bc00919..da51e9af 100644 --- a/packages/cli/test/setup.test.ts +++ b/packages/cli/test/setup.test.ts @@ -398,6 +398,59 @@ describe('setup status', () => { expect(rendered).toContain('KTX context built: yes'); }); + it('reports context ready after a partial ingest report saved memory', async () => { + await writeFile( + join(tempDir, 'ktx.yaml'), + [ + 'setup:', + ' database_connection_ids:', + ' - warehouse', + 'connections:', + ' warehouse:', + ' driver: postgres', + ' url: env:DATABASE_URL', + 'ingest:', + ' embeddings:', + ' backend: none', + ' dimensions: 8', + '', + ].join('\n'), + 'utf-8', + ); + await writeKtxSetupState(tempDir, { completed_steps: ['project', 'databases'] }); + await persistLocalBundleReport( + tempDir, + localFakeBundleReport('warehouse-job-partial', { + connectionId: 'warehouse', + sourceKey: 'fake', + body: { + failedWorkUnits: ['orders-bad'], + workUnits: [ + { + unitKey: 'orders-ok', + rawFiles: ['orders/orders.json'], + status: 'success', + actions: [{ target: 'wiki', type: 'created', key: 'wiki/orders.md', detail: 'orders' }], + touchedSlSources: [], + }, + { + unitKey: 'orders-bad', + rawFiles: ['orders/bad.json'], + status: 'failed', + reason: 'writer tool failed', + actions: [], + touchedSlSources: [], + }, + ], + }, + }), + ); + + const status = await readKtxSetupStatus(tempDir); + + expect(status.context).toMatchObject({ ready: true, status: 'completed' }); + }); + it('formats plain and JSON setup status payloads', async () => { const status = await readKtxSetupStatus(tempDir); const rendered = formatKtxSetupStatus(status); From 08d08d8ea00639f9a8198566805cd955eadcad0b Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Sat, 30 May 2026 12:07:15 +0200 Subject: [PATCH 19/61] ci: refresh README star history chart twice daily Point the README chart at a committed assets/star-history.svg instead of the star-history API URL so GitHub serves it directly and bypasses the Camo proxy cache. A scheduled workflow regenerates the SVG at 06:00/18:00 UTC, busting star-history's server-side cache, and commits it when it changes. --- .github/workflows/star-history.yml | 61 ++++++++++++++++++++++++++++++ README.md | 2 +- assets/star-history.svg | 1 + 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/star-history.yml create mode 100644 assets/star-history.svg diff --git a/.github/workflows/star-history.yml b/.github/workflows/star-history.yml new file mode 100644 index 00000000..ec484b05 --- /dev/null +++ b/.github/workflows/star-history.yml @@ -0,0 +1,61 @@ +name: Refresh star history chart + +on: + schedule: + # Twice daily at 06:00 and 18:00 UTC. + - cron: "0 6,18 * * *" + workflow_dispatch: + +permissions: + contents: write + +env: + DO_NOT_TRACK: "1" + KTX_TELEMETRY_DISABLED: "1" + NEXT_TELEMETRY_DISABLED: "1" + +concurrency: + group: star-history-refresh + cancel-in-progress: true + +jobs: + refresh: + name: Regenerate assets/star-history.svg + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + + - name: Fetch fresh star-history SVG + run: | + set -euo pipefail + # cachebust forces star-history to regenerate instead of serving its + # own server-side cache; --location follows the slug-normalizing 301. + url="https://api.star-history.com/svg?repos=Kaelio/ktx&type=Date&cachebust=${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" + curl --fail --location --silent --show-error \ + --retry 3 --retry-delay 5 --max-time 60 \ + -o assets/star-history.svg.new "$url" + # Guard against error pages / truncated responses before overwriting. + if ! grep -q "" assets/star-history.svg.new; then + echo "Downloaded file is not a valid SVG; aborting." >&2 + exit 1 + fi + if [ "$(wc -c < assets/star-history.svg.new)" -lt 1000 ]; then + echo "Downloaded SVG is suspiciously small; aborting." >&2 + exit 1 + fi + mv assets/star-history.svg.new assets/star-history.svg + + - name: Commit if changed + run: | + set -euo pipefail + if git diff --quiet -- assets/star-history.svg; then + echo "Star-history chart unchanged; nothing to commit." + exit 0 + fi + git config user.name "github-actions[bot]" + git config user.email "41898282+github-actions[bot]@users.noreply.github.com" + git add assets/star-history.svg + # [skip ci] keeps this housekeeping commit from triggering KTX CI. + git commit -m "chore: refresh star history chart [skip ci]" + git push diff --git a/README.md b/README.md index 23b2fa0a..686ece22 100644 --- a/README.md +++ b/README.md @@ -248,6 +248,6 @@ event catalog and opt-out options.

- ktx Star History Chart + ktx Star History Chart

diff --git a/assets/star-history.svg b/assets/star-history.svg new file mode 100644 index 00000000..3f6c4a04 --- /dev/null +++ b/assets/star-history.svg @@ -0,0 +1 @@ +star-history.comMay 17May 24 100200300400kaelio/ktxStar HistoryDateGitHub Stars From ba06f7078af69fdba2184186ca5cc53c65427ea2 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Sat, 30 May 2026 16:01:47 +0200 Subject: [PATCH 20/61] ci: push star-history refresh to protected main with RELEASE_PAT (#239) The scheduled star-history workflow checked out with the default GITHUB_TOKEN, so its git push to main was rejected by the branch protection hook (GH006). Check out with RELEASE_PAT instead, matching release.yml, whose semantic-release step already pushes to the protected main branch with the same token. --- .github/workflows/star-history.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/star-history.yml b/.github/workflows/star-history.yml index ec484b05..e67a0517 100644 --- a/.github/workflows/star-history.yml +++ b/.github/workflows/star-history.yml @@ -25,6 +25,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + # RELEASE_PAT can push to the protected main branch; the default + # GITHUB_TOKEN is rejected by the branch-protection hook (GH006). + token: ${{ secrets.RELEASE_PAT }} - name: Fetch fresh star-history SVG run: | From 54d6e877335a7218dc2ec795ff85529403ac6bde Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 14:02:55 +0000 Subject: [PATCH 21/61] chore: refresh star history chart [skip ci] --- assets/star-history.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/star-history.svg b/assets/star-history.svg index 3f6c4a04..246ba5a0 100644 --- a/assets/star-history.svg +++ b/assets/star-history.svg @@ -1 +1 @@ -star-history.comMay 17May 24 100200300400kaelio/ktxStar HistoryDateGitHub Stars +star-history.comMay 17May 24 100200300400kaelio/ktxStar HistoryDateGitHub Stars \ No newline at end of file From cbbcf8e8bdd1560b3d0c73e47abd36eb5d8c6f23 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Sat, 30 May 2026 17:44:27 +0200 Subject: [PATCH 22/61] ci: normalize star-history.svg trailing newline (#241) The star-history refresh workflow committed the API's SVG verbatim, but the response has no trailing newline. Because the refresh commit uses [skip ci], the file never ran end-of-file-fixer at commit time, so pre-commit's `--all-files` run failed end-of-file-fixer on every open PR (e.g. #240), even PRs that never touched the file. Normalize the downloaded SVG to exactly one trailing newline in the workflow (idempotent, so the "unchanged" guard still works), and fix the currently committed file so open PRs go green now. --- .github/workflows/star-history.yml | 9 ++++++++- assets/star-history.svg | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/star-history.yml b/.github/workflows/star-history.yml index e67a0517..b7d90c43 100644 --- a/.github/workflows/star-history.yml +++ b/.github/workflows/star-history.yml @@ -48,7 +48,14 @@ jobs: echo "Downloaded SVG is suspiciously small; aborting." >&2 exit 1 fi - mv assets/star-history.svg.new assets/star-history.svg + # The star-history API returns the SVG without a trailing newline, + # which end-of-file-fixer rewrites whenever pre-commit runs + # --all-files on a PR. Because the refresh commit below uses [skip ci], + # the hook never runs against it here, so an un-normalized file + # silently breaks the pre-commit check on every open PR. Normalize to + # exactly one trailing newline before committing. + printf '%s\n' "$(cat assets/star-history.svg.new)" > assets/star-history.svg + rm -f assets/star-history.svg.new - name: Commit if changed run: | diff --git a/assets/star-history.svg b/assets/star-history.svg index 246ba5a0..3f6c4a04 100644 --- a/assets/star-history.svg +++ b/assets/star-history.svg @@ -1 +1 @@ -star-history.comMay 17May 24 100200300400kaelio/ktxStar HistoryDateGitHub Stars \ No newline at end of file +star-history.comMay 17May 24 100200300400kaelio/ktxStar HistoryDateGitHub Stars From 25f639fba2f71aa880e4184ce4b50b56e2374d0e Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Sat, 30 May 2026 17:54:24 +0200 Subject: [PATCH 23/61] feat: trim MCP query response payloads (#240) --- .../mcp/__snapshots__/mcp-tools-list.json | 1620 ----------------- packages/cli/src/context/mcp/context-tools.ts | 106 +- packages/cli/src/context/mcp/types.ts | 5 +- packages/cli/src/context/search/discover.ts | 7 +- packages/cli/src/skills/analytics/SKILL.md | 7 +- .../mcp/__snapshots__/mcp-tools-list.json | 41 +- packages/cli/test/context/mcp/server.test.ts | 152 +- 7 files changed, 235 insertions(+), 1703 deletions(-) delete mode 100644 packages/cli/src/context/mcp/__snapshots__/mcp-tools-list.json diff --git a/packages/cli/src/context/mcp/__snapshots__/mcp-tools-list.json b/packages/cli/src/context/mcp/__snapshots__/mcp-tools-list.json deleted file mode 100644 index 10cb0b77..00000000 --- a/packages/cli/src/context/mcp/__snapshots__/mcp-tools-list.json +++ /dev/null @@ -1,1620 +0,0 @@ -[ - { - "name": "connection_list", - "title": "Connection List", - "description": "List configured read-only data connections available to this KTX project. Use this before connection-scoped tools when the project may have multiple warehouses.", - "inputSchema": { - "type": "object", - "properties": {}, - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "connections": { - "type": "array", - "items": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "connectionType": { - "type": "string" - } - }, - "required": [ - "id", - "name", - "connectionType" - ], - "additionalProperties": false - } - } - }, - "required": [ - "connections" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "Connection List", - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - }, - { - "name": "wiki_search", - "title": "Wiki Search", - "description": "Search KTX wiki pages for reusable business context. Example: wiki_search({ query: \"revenue recognition\", limit: 5 }).", - "inputSchema": { - "type": "object", - "properties": { - "query": { - "type": "string", - "minLength": 1, - "description": "Natural-language wiki search query, e.g. \"revenue recognition policy\"." - }, - "limit": { - "default": 10, - "description": "Maximum wiki pages to return. Defaults to 10.", - "type": "integer", - "minimum": 1, - "maximum": 50 - } - }, - "required": [ - "query" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "results": { - "type": "array", - "items": { - "type": "object", - "properties": { - "key": { - "type": "string" - }, - "path": { - "type": "string" - }, - "scope": { - "type": "string", - "enum": [ - "GLOBAL", - "USER" - ] - }, - "summary": { - "type": "string" - }, - "score": { - "type": "number" - }, - "matchReasons": { - "type": "array", - "items": { - "type": "string" - } - }, - "lanes": { - "type": "array", - "items": { - "type": "object", - "properties": { - "lane": { - "type": "string" - }, - "status": { - "type": "string" - }, - "requestedCandidatePoolLimit": { - "type": "number" - }, - "effectiveCandidatePoolLimit": { - "type": "number" - }, - "returnedCandidateCount": { - "type": "number" - }, - "weight": { - "type": "number" - }, - "reason": { - "type": "string" - } - }, - "required": [ - "lane", - "status", - "requestedCandidatePoolLimit", - "effectiveCandidatePoolLimit", - "returnedCandidateCount", - "weight" - ], - "additionalProperties": false - } - } - }, - "required": [ - "key", - "path", - "scope", - "summary", - "score" - ], - "additionalProperties": false - } - }, - "totalFound": { - "type": "number" - } - }, - "required": [ - "results", - "totalFound" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "Wiki Search", - "readOnlyHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - }, - { - "name": "wiki_read", - "title": "Wiki Read", - "description": "Read a KTX wiki page by key returned from wiki_search. Example: wiki_read({ key: \"global/revenue\" }).", - "inputSchema": { - "type": "object", - "properties": { - "key": { - "type": "string", - "minLength": 1, - "description": "Wiki page key returned by wiki_search, e.g. \"global/revenue\"." - } - }, - "required": [ - "key" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "key": { - "type": "string" - }, - "summary": { - "type": "string" - }, - "content": { - "type": "string" - }, - "scope": { - "type": "string", - "enum": [ - "GLOBAL", - "USER" - ] - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "refs": { - "type": "array", - "items": { - "type": "string" - } - }, - "slRefs": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "key", - "summary", - "content", - "scope" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "Wiki Read", - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - }, - { - "name": "sl_read_source", - "title": "Semantic Layer Read Source", - "description": "Read a semantic-layer YAML source by connection id and source name. Example: sl_read_source({ connectionId: \"warehouse\", sourceName: \"orders\" }).", - "inputSchema": { - "type": "object", - "properties": { - "connectionId": { - "type": "string", - "minLength": 1, - "description": "Connection id that owns the semantic-layer source." - }, - "sourceName": { - "type": "string", - "minLength": 1, - "description": "Semantic-layer source name without \".yaml\", e.g. \"orders\"." - } - }, - "required": [ - "connectionId", - "sourceName" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "sourceName": { - "type": "string" - }, - "yaml": { - "type": "string" - } - }, - "required": [ - "sourceName", - "yaml" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "Semantic Layer Read Source", - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - }, - { - "name": "sl_query", - "title": "Semantic Layer Query", - "description": "Execute a semantic-layer query and return rows, headers, generated SQL, and plan details. Example: sl_query({ connectionId: \"warehouse\", measures: [\"orders.order_count\"], dimensions: [{ field: \"orders.created_at\", granularity: \"month\" }] }).", - "inputSchema": { - "type": "object", - "properties": { - "connectionId": { - "description": "Connection id to query. Omit only when the project has exactly one configured connection.", - "type": "string", - "minLength": 1 - }, - "measures": { - "minItems": 1, - "type": "array", - "items": { - "anyOf": [ - { - "type": "string", - "description": "Semantic-layer measure key, e.g. \"orders.order_count\"." - }, - { - "type": "object", - "properties": { - "expr": { - "type": "string", - "minLength": 1, - "description": "Ad hoc aggregate expression, e.g. \"sum(orders.amount)\"." - }, - "name": { - "type": "string", - "minLength": 1, - "description": "Alias for the ad hoc measure, e.g. \"gross_revenue\"." - } - }, - "required": [ - "expr", - "name" - ] - } - ] - }, - "description": "Measures to select. Use semantic-layer keys when available." - }, - "dimensions": { - "default": [], - "description": "Dimensions to group by. Use {field, granularity?} entries.", - "type": "array", - "items": { - "type": "object", - "properties": { - "field": { - "type": "string", - "minLength": 1, - "description": "Dimension to group by, e.g. \"orders.created_at\" or \"orders.status\"." - }, - "granularity": { - "description": "Time grain for time dimensions: day, week, month, quarter, or year.", - "type": "string", - "minLength": 1 - } - }, - "required": [ - "field" - ] - } - }, - "filters": { - "default": [], - "description": "Semantic-layer filter expressions to apply.", - "type": "array", - "items": { - "type": "string", - "description": "Semantic-layer filter expression, e.g. \"orders.status = paid\"." - } - }, - "segments": { - "default": [], - "description": "Semantic-layer segment keys to apply.", - "type": "array", - "items": { - "type": "string", - "description": "Semantic-layer segment key to apply." - } - }, - "order_by": { - "default": [], - "description": "Sort clauses. Use {field, direction?} entries.", - "type": "array", - "items": { - "type": "object", - "properties": { - "field": { - "type": "string", - "minLength": 1, - "description": "Field/measure/dimension id to order by, e.g. \"orders.created_at\", a dimension key like \"mart_nrr_quarterly.quarter_label\", or a measure alias." - }, - "direction": { - "default": "asc", - "description": "Sort direction: \"asc\" or \"desc\". Defaults to \"asc\".", - "type": "string", - "enum": [ - "asc", - "desc" - ] - } - }, - "required": [ - "field" - ] - } - }, - "limit": { - "default": 1000, - "description": "Maximum rows to return. Defaults to 1000.", - "type": "integer", - "minimum": 0, - "maximum": 9007199254740991 - }, - "include_empty": { - "default": true, - "description": "Whether to include empty dimension groups. Defaults to true.", - "type": "boolean" - } - }, - "required": [ - "measures" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "connectionId": { - "type": "string" - }, - "dialect": { - "type": "string" - }, - "sql": { - "type": "string" - }, - "headers": { - "type": "array", - "items": { - "type": "string" - } - }, - "rows": { - "type": "array", - "items": { - "type": "array", - "items": {} - } - }, - "totalRows": { - "type": "number" - }, - "plan": { - "type": "object", - "propertyNames": { - "type": "string" - }, - "additionalProperties": {} - } - }, - "required": [ - "sql", - "headers", - "rows", - "totalRows" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "Semantic Layer Query", - "readOnlyHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - }, - { - "name": "entity_details", - "title": "Entity Details", - "description": "Read table and column metadata from the latest live-database scan snapshot. Example: entity_details({ connectionId: \"warehouse\", entities: [{ table: { catalog: null, db: \"public\", name: \"orders\" }, columns: [\"id\"] }] }).", - "inputSchema": { - "type": "object", - "properties": { - "connectionId": { - "type": "string", - "minLength": 1, - "description": "Connection id whose latest scan snapshot should be read." - }, - "entities": { - "minItems": 1, - "maxItems": 20, - "type": "array", - "items": { - "type": "object", - "properties": { - "table": { - "anyOf": [ - { - "type": "string", - "minLength": 1 - }, - { - "type": "object", - "properties": { - "catalog": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Catalog/project/database. Use null when not applicable." - }, - "db": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "description": "Schema/database/dataset. Use null when not applicable." - }, - "name": { - "type": "string", - "minLength": 1, - "description": "Table name." - } - }, - "required": [ - "catalog", - "db", - "name" - ] - } - ], - "description": "Table display string or canonical object ref." - }, - "columns": { - "description": "Optional column filter.", - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "description": "Column name to inspect." - } - } - }, - "required": [ - "table" - ] - }, - "description": "Tables or columns to inspect. Maximum 20 entities." - } - }, - "required": [ - "connectionId", - "entities" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "results": { - "type": "array", - "items": { - "anyOf": [ - { - "type": "object", - "properties": { - "ok": { - "type": "boolean", - "const": true - }, - "connectionId": { - "type": "string" - }, - "tableRef": { - "type": "object", - "properties": { - "catalog": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "db": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "name": { - "type": "string" - } - }, - "required": [ - "catalog", - "db", - "name" - ], - "additionalProperties": false - }, - "display": { - "type": "string" - }, - "kind": { - "type": "string", - "enum": [ - "table", - "view", - "external", - "event_stream" - ] - }, - "comment": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "estimatedRows": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "columns": { - "type": "array", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "nativeType": { - "type": "string" - }, - "normalizedType": { - "type": "string" - }, - "dimensionType": { - "type": "string", - "enum": [ - "time", - "string", - "number", - "boolean" - ] - }, - "nullable": { - "type": "boolean" - }, - "primaryKey": { - "type": "boolean" - }, - "comment": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "name", - "nativeType", - "normalizedType", - "dimensionType", - "nullable", - "primaryKey", - "comment" - ], - "additionalProperties": false - } - }, - "foreignKeys": { - "type": "array", - "items": { - "type": "object", - "properties": { - "fromColumn": { - "type": "string" - }, - "toCatalog": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "toDb": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "toTable": { - "type": "string" - }, - "toColumn": { - "type": "string" - }, - "constraintName": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "fromColumn", - "toCatalog", - "toDb", - "toTable", - "toColumn", - "constraintName" - ], - "additionalProperties": false - } - }, - "snapshot": { - "type": "object", - "properties": { - "syncId": { - "type": "string" - }, - "extractedAt": { - "type": "string" - }, - "scanRunId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "syncId", - "extractedAt", - "scanRunId" - ], - "additionalProperties": false - } - }, - "required": [ - "ok", - "connectionId", - "tableRef", - "display", - "kind", - "comment", - "estimatedRows", - "columns", - "foreignKeys", - "snapshot" - ], - "additionalProperties": false - }, - { - "type": "object", - "properties": { - "ok": { - "type": "boolean", - "const": false - }, - "connectionId": { - "type": "string" - }, - "table": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "object", - "properties": { - "catalog": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "db": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "name": { - "type": "string" - } - }, - "required": [ - "catalog", - "db", - "name" - ], - "additionalProperties": false - } - ] - }, - "snapshot": { - "type": "object", - "properties": { - "syncId": { - "type": "string" - }, - "extractedAt": { - "type": "string" - }, - "scanRunId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "syncId", - "extractedAt", - "scanRunId" - ], - "additionalProperties": false - }, - "error": { - "type": "object", - "properties": { - "code": { - "type": "string", - "enum": [ - "scan_missing", - "table_not_found", - "ambiguous_table", - "column_not_found" - ] - }, - "message": { - "type": "string" - }, - "candidates": { - "anyOf": [ - { - "type": "array", - "items": { - "type": "object", - "properties": { - "tableRef": { - "type": "object", - "properties": { - "catalog": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "db": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "name": { - "type": "string" - } - }, - "required": [ - "catalog", - "db", - "name" - ], - "additionalProperties": false - }, - "display": { - "type": "string" - } - }, - "required": [ - "tableRef", - "display" - ], - "additionalProperties": false - } - }, - { - "type": "array", - "items": { - "type": "string" - } - } - ] - } - }, - "required": [ - "code", - "message" - ], - "additionalProperties": false - } - }, - "required": [ - "ok", - "connectionId", - "table", - "error" - ], - "additionalProperties": false - } - ] - } - } - }, - "required": [ - "results" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "Entity Details", - "readOnlyHint": true, - "idempotentHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - }, - { - "name": "dictionary_search", - "title": "Dictionary Search", - "description": "Search profile-sampled warehouse values to locate likely source columns for business values. Example: dictionary_search({ values: [\"Acme Corp\"], connectionId: \"warehouse\" }).", - "inputSchema": { - "type": "object", - "properties": { - "values": { - "minItems": 1, - "maxItems": 20, - "type": "array", - "items": { - "type": "string", - "minLength": 1, - "description": "Business value to locate, e.g. \"Acme Corp\" or \"enterprise\"." - }, - "description": "Values to search for in sampled warehouse dictionaries." - }, - "connectionId": { - "description": "Optional connection id. Pass it when user intent pins a specific warehouse.", - "type": "string", - "minLength": 1 - } - }, - "required": [ - "values" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "searched": { - "type": "array", - "items": { - "type": "object", - "properties": { - "connectionId": { - "type": "string" - }, - "coverage": { - "type": "object", - "properties": { - "sampledRows": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "valuesPerColumn": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - }, - "profiledColumns": { - "type": "number" - }, - "syncId": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "profiledAt": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "sampledRows", - "valuesPerColumn", - "profiledColumns", - "syncId", - "profiledAt" - ], - "additionalProperties": false - }, - "status": { - "type": "string", - "enum": [ - "ready", - "no_profile_artifact", - "no_candidate_columns" - ] - } - }, - "required": [ - "connectionId", - "coverage", - "status" - ], - "additionalProperties": false - } - }, - "results": { - "type": "array", - "items": { - "type": "object", - "properties": { - "value": { - "type": "string" - }, - "matches": { - "type": "array", - "items": { - "type": "object", - "properties": { - "connectionId": { - "type": "string" - }, - "sourceName": { - "type": "string" - }, - "columnName": { - "type": "string" - }, - "matchedValue": { - "type": "string" - }, - "cardinality": { - "anyOf": [ - { - "type": "number" - }, - { - "type": "null" - } - ] - } - }, - "required": [ - "connectionId", - "sourceName", - "columnName", - "matchedValue", - "cardinality" - ], - "additionalProperties": false - } - }, - "misses": { - "type": "array", - "items": { - "type": "object", - "properties": { - "connectionId": { - "type": "string" - }, - "reason": { - "type": "string", - "enum": [ - "no_profile_artifact", - "no_candidate_columns", - "value_not_in_sample" - ] - } - }, - "required": [ - "connectionId", - "reason" - ], - "additionalProperties": false - } - } - }, - "required": [ - "value", - "matches", - "misses" - ], - "additionalProperties": false - } - } - }, - "required": [ - "searched", - "results" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "Dictionary Search", - "readOnlyHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - }, - { - "name": "discover_data", - "title": "Discover Data", - "description": "Search across KTX wiki pages, semantic-layer sources, measures, dimensions, raw tables, and columns. Example: discover_data({ query: \"monthly orders by customer\", connectionId: \"warehouse\", kinds: [\"sl_source\", \"table\"] }).", - "inputSchema": { - "type": "object", - "properties": { - "query": { - "type": "string", - "minLength": 1, - "description": "Natural-language discovery query, e.g. \"monthly orders by customer\"." - }, - "connectionId": { - "description": "Optional connection id. Pass it when user intent pins a specific warehouse.", - "type": "string", - "minLength": 1 - }, - "kinds": { - "description": "Optional kind filter.", - "type": "array", - "items": { - "type": "string", - "enum": [ - "wiki", - "sl_source", - "sl_measure", - "sl_dimension", - "table", - "column" - ], - "description": "Reference kind to include." - } - }, - "limit": { - "description": "Maximum refs to return. Defaults to 15.", - "default": 15, - "type": "integer", - "minimum": 1, - "maximum": 50 - } - }, - "required": [ - "query" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "refs": { - "type": "array", - "items": { - "type": "object", - "properties": { - "kind": { - "type": "string", - "enum": [ - "wiki", - "sl_source", - "sl_measure", - "sl_dimension", - "table", - "column" - ] - }, - "id": { - "type": "string" - }, - "score": { - "type": "number" - }, - "summary": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "snippet": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "matchedOn": { - "type": "string", - "enum": [ - "name", - "display", - "description", - "comment", - "expr", - "sample_value", - "body" - ] - }, - "connectionId": { - "type": "string" - }, - "tableRef": { - "type": "object", - "properties": { - "catalog": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "db": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "name": { - "type": "string" - } - }, - "required": [ - "catalog", - "db", - "name" - ], - "additionalProperties": false - }, - "columnName": { - "type": "string" - } - }, - "required": [ - "kind", - "id", - "score", - "summary", - "snippet", - "matchedOn" - ], - "additionalProperties": false - } - } - }, - "required": [ - "refs" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "Discover Data", - "readOnlyHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - }, - { - "name": "sql_execution", - "title": "SQL Execution", - "description": "Execute one parser-validated read-only SQL query against a configured KTX connection. Example: sql_execution({ connectionId: \"warehouse\", sql: \"select count(*) from public.orders\", maxRows: 100 }).", - "inputSchema": { - "type": "object", - "properties": { - "connectionId": { - "type": "string", - "minLength": 1, - "description": "Connection id to execute against. Required for raw SQL." - }, - "sql": { - "type": "string", - "minLength": 1, - "description": "Parser-validated read-only SQL, e.g. \"select count(*) from public.orders\"." - }, - "maxRows": { - "description": "Maximum rows to return. Defaults to 1000.", - "default": 1000, - "type": "integer", - "minimum": 1, - "maximum": 10000 - } - }, - "required": [ - "connectionId", - "sql" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "headers": { - "type": "array", - "items": { - "type": "string" - } - }, - "headerTypes": { - "type": "array", - "items": { - "type": "string" - } - }, - "rows": { - "type": "array", - "items": { - "type": "array", - "items": {} - } - }, - "rowCount": { - "type": "number" - } - }, - "required": [ - "headers", - "rows", - "rowCount" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "SQL Execution", - "readOnlyHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - }, - { - "name": "memory_ingest", - "title": "Memory Ingest", - "description": "Ingest free-form markdown knowledge into durable KTX memory. Use this for business rules, metric definitions, schema gotchas, recurring findings, or explicit user requests to remember something. Example: memory_ingest({ connectionId: \"warehouse\", content: \"ARR is reported in cents in this warehouse.\" }).", - "inputSchema": { - "type": "object", - "properties": { - "content": { - "type": "string", - "minLength": 1, - "description": "Free-form markdown to ingest. Include the knowledge itself plus any context (source, the user question, why this came up) that the memory agent should consider when triaging into wiki/SL." - }, - "connectionId": { - "description": "Scope this memory to a specific connection. Required when the knowledge is warehouse-specific, including measure definitions, schema gotchas, or anything tied to a particular warehouse. Omit only for global wiki knowledge.", - "type": "string", - "minLength": 1 - } - }, - "required": [ - "content" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "runId": { - "type": "string" - } - }, - "required": [ - "runId" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "Memory Ingest", - "destructiveHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - }, - { - "name": "memory_ingest_status", - "title": "Memory Ingest Status", - "description": "Read the current or final status for a memory ingest run. Example: memory_ingest_status({ runId: \"memory-run-1\" }).", - "inputSchema": { - "type": "object", - "properties": { - "runId": { - "type": "string", - "minLength": 1, - "description": "The memory ingest run id returned by memory_ingest." - } - }, - "required": [ - "runId" - ], - "$schema": "http://json-schema.org/draft-07/schema#" - }, - "outputSchema": { - "type": "object", - "properties": { - "runId": { - "type": "string" - }, - "status": { - "type": "string", - "enum": [ - "running", - "done", - "error" - ] - }, - "stage": { - "type": "string" - }, - "done": { - "type": "boolean" - }, - "captured": { - "type": "object", - "properties": { - "wiki": { - "type": "array", - "items": { - "type": "string" - } - }, - "sl": { - "type": "array", - "items": { - "type": "string" - } - }, - "xrefs": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "wiki", - "sl", - "xrefs" - ], - "additionalProperties": false - }, - "error": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "commitHash": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ] - }, - "skillsLoaded": { - "type": "array", - "items": { - "type": "string" - } - }, - "signalDetected": { - "type": "boolean" - } - }, - "required": [ - "runId", - "status", - "stage", - "done", - "captured", - "error", - "commitHash", - "skillsLoaded", - "signalDetected" - ], - "$schema": "http://json-schema.org/draft-07/schema#", - "additionalProperties": false - }, - "annotations": { - "title": "Memory Ingest Status", - "readOnlyHint": true, - "openWorldHint": false - }, - "execution": { - "taskSupport": "forbidden" - } - } -] diff --git a/packages/cli/src/context/mcp/context-tools.ts b/packages/cli/src/context/mcp/context-tools.ts index aa593f7f..057e570b 100644 --- a/packages/cli/src/context/mcp/context-tools.ts +++ b/packages/cli/src/context/mcp/context-tools.ts @@ -12,6 +12,7 @@ import type { KtxMcpToolHandlerContext, KtxMcpToolResult, KtxMcpUserContext, + KtxSemanticLayerQueryResponse, NonArrayObject, } from './types.js'; @@ -60,7 +61,7 @@ const toolDescriptions = { sl_read_source: 'Read a semantic-layer YAML source by connection id and source name. Example: sl_read_source({ connectionId: "warehouse", sourceName: "orders" }).', sl_query: - 'Execute a semantic-layer query and return rows, headers, generated SQL, and plan details. Example: sl_query({ connectionId: "warehouse", measures: ["orders.order_count"], dimensions: [{ field: "orders.created_at", granularity: "month" }] }).', + 'Execute a semantic-layer query and return headers, rows, and total row count, plus correctness notes (e.g. compile-only or fan-out) when relevant. The generated SQL and full query plan are omitted by default; request them with include: ["sql"] and/or include: ["plan"]. Example: sl_query({ connectionId: "warehouse", measures: ["orders.order_count"], dimensions: [{ field: "orders.created_at", granularity: "month" }], include: ["sql"] }).', sql_execution: 'Execute one parser-validated read-only SQL query against a configured KTX connection. Example: sql_execution({ connectionId: "warehouse", sql: "select count(*) from public.orders", maxRows: 100 }).', memory_ingest: @@ -73,7 +74,7 @@ const connectionListSchema = z.object({}); const knowledgeSearchSchema = z.object({ query: z.string().min(1).describe('Natural-language wiki search query, e.g. "revenue recognition policy".'), - limit: z.number().int().min(1).max(50).default(10).describe('Maximum wiki pages to return. Defaults to 10.'), + limit: z.number().int().min(1).max(50).default(10).describe('Maximum wiki pages to return.'), }); const knowledgeReadSchema = z.object({ @@ -109,10 +110,7 @@ const slQueryOrderBySchema = z.object({ .describe( 'Field/measure/dimension id to order by, e.g. "orders.created_at", a dimension key like "mart_nrr_quarterly.quarter_label", or a measure alias.', ), - direction: z - .enum(['asc', 'desc']) - .default('asc') - .describe('Sort direction: "asc" or "desc". Defaults to "asc".'), + direction: z.enum(['asc', 'desc']).default('asc').describe('Sort direction for this field.'), }); const slQuerySchema = z.object({ @@ -136,8 +134,12 @@ const slQuerySchema = z.object({ .array(slQueryOrderBySchema) .default([]) .describe('Sort clauses. Use {field, direction?} entries.'), - limit: z.number().int().min(0).default(1000).describe('Maximum rows to return. Defaults to 1000.'), - include_empty: z.boolean().default(true).describe('Whether to include empty dimension groups. Defaults to true.'), + limit: z.number().int().min(0).default(1000).describe('Maximum rows to return.'), + include_empty: z.boolean().default(true).describe('Whether to include empty dimension groups.'), + include: z + .array(z.enum(['plan', 'sql'])) + .default([]) + .describe('Extra detail to attach to the response: "sql" for the generated SQL, "plan" for the full query plan.'), }); const entityDetailsTableRefSchema = z.object({ @@ -184,13 +186,13 @@ const discoverDataSchema = z.object({ .optional() .describe('Optional connection id. Pass it when user intent pins a specific warehouse.'), kinds: z.array(discoverDataKindSchema.describe('Reference kind to include.')).optional().describe('Optional kind filter.'), - limit: z.number().int().min(1).max(50).default(15).optional().describe('Maximum refs to return. Defaults to 15.'), + limit: z.number().int().min(1).max(50).default(10).optional().describe('Maximum refs to return.'), }); const sqlExecutionSchema = z.object({ connectionId: connectionIdSchema.describe('Connection id to execute against. Required for raw SQL.'), sql: z.string().min(1).describe('Parser-validated read-only SQL, e.g. "select count(*) from public.orders".'), - maxRows: z.number().int().min(1).max(10_000).default(1000).optional().describe('Maximum rows to return. Defaults to 1000.'), + maxRows: z.number().int().min(1).max(10_000).default(1000).optional().describe('Maximum rows to return.'), }); const memoryIngestSchema = z.object({ @@ -266,10 +268,14 @@ const slReadSourceOutputSchema = z.object({ const slQueryOutputSchema = z.object({ connectionId: z.string().optional(), dialect: z.string().optional(), - sql: z.string(), headers: z.array(z.string()), rows: z.array(z.array(z.unknown())), totalRows: z.number(), + // Correctness signals hoisted out of `plan` so they survive default projection (e.g. compile-only + // status, fan-out warnings). Present only when there is something to report. + notes: z.array(z.string()).optional(), + // Opt-in detail, attached only when requested via the `include` input. + sql: z.string().optional(), plan: unknownRecordSchema.optional(), }); @@ -411,12 +417,59 @@ const memoryIngestStatusOutputSchema = z.object({ /** @internal */ export function jsonToolResult(structuredContent: T): KtxMcpToolResult { + // Compact (non-indented) JSON: this `content` text is the copy the model reads. Pretty-printing + // arrays-of-arrays (every `rows` payload) puts one scalar per line, inflating tabular results by + // a large constant factor. `structuredContent` carries the same data for structured-output clients. return { - content: [{ type: 'text', text: JSON.stringify(structuredContent, null, 2) }], + content: [{ type: 'text', text: JSON.stringify(structuredContent) }], structuredContent, }; } +/** + * Pull the correctness-critical signals out of a query plan so they survive even when the caller + * did not opt into the full `plan`. Returns an empty list when there is nothing to flag. + */ +function slQueryNotes(plan: Record | undefined): string[] { + if (!plan) { + return []; + } + const notes: string[] = []; + const execution = plan.execution; + if ( + execution && + typeof execution === 'object' && + (execution as Record).mode === 'compile_only' + ) { + const reason = (execution as Record).reason; + notes.push(typeof reason === 'string' ? reason : 'Compiled SQL only; no rows were executed.'); + } + if (plan.has_fan_out === true) { + const description = typeof plan.fan_out_description === 'string' ? plan.fan_out_description.trim() : ''; + notes.push(description.length > 0 ? description : 'Fan-out detected: measure totals may be inflated by joins.'); + } + return notes; +} + +/** + * Default sl_query response is the minimum the agent needs to read the result: connection, headers, + * rows, totals, plus any correctness notes. The generated `sql` and the full `plan` are attached only + * when explicitly requested via `include`, since both are large and echo information the caller already has. + */ +function projectSlQueryResult(result: KtxSemanticLayerQueryResponse, include: ('plan' | 'sql')[]) { + const notes = slQueryNotes(result.plan); + return { + ...(result.connectionId !== undefined ? { connectionId: result.connectionId } : {}), + ...(result.dialect !== undefined ? { dialect: result.dialect } : {}), + headers: result.headers, + rows: result.rows, + totalRows: result.totalRows, + ...(notes.length > 0 ? { notes } : {}), + ...(include.includes('sql') ? { sql: result.sql } : {}), + ...(include.includes('plan') && result.plan ? { plan: result.plan } : {}), + }; +} + function jsonErrorToolResult(text: string): KtxMcpToolResult> { return { content: [{ type: 'text', text }], @@ -618,23 +671,22 @@ export function registerKtxContextTools(deps: RegisterKtxContextToolsDeps): void slQuerySchema, async (input, context) => { const onProgress = mcpProgressCallback(context); - return jsonToolResult( - await semanticLayer.query( - { - connectionId: input.connectionId, - query: { - measures: input.measures, - dimensions: input.dimensions, - filters: input.filters, - segments: input.segments, - order_by: input.order_by, - limit: input.limit, - include_empty: input.include_empty, - }, + const result = await semanticLayer.query( + { + connectionId: input.connectionId, + query: { + measures: input.measures, + dimensions: input.dimensions, + filters: input.filters, + segments: input.segments, + order_by: input.order_by, + limit: input.limit, + include_empty: input.include_empty, }, - onProgress ? { onProgress } : undefined, - ), + }, + onProgress ? { onProgress } : undefined, ); + return jsonToolResult(projectSlQueryResult(result, input.include)); }, ); } diff --git a/packages/cli/src/context/mcp/types.ts b/packages/cli/src/context/mcp/types.ts index 29a8c069..e9fc0ff2 100644 --- a/packages/cli/src/context/mcp/types.ts +++ b/packages/cli/src/context/mcp/types.ts @@ -110,7 +110,10 @@ interface KtxSemanticLayerReadResponse { yaml: string; } -interface KtxSemanticLayerQueryResponse { +/** @internal */ +export interface KtxSemanticLayerQueryResponse { + connectionId?: string; + dialect?: string; sql: string; headers: string[]; rows: unknown[][]; diff --git a/packages/cli/src/context/search/discover.ts b/packages/cli/src/context/search/discover.ts index b3456459..9a572daf 100644 --- a/packages/cli/src/context/search/discover.ts +++ b/packages/cli/src/context/search/discover.ts @@ -167,7 +167,7 @@ async function wikiCandidates( query: input.query, userId: options.userId, embeddingService: options.embeddingService ?? null, - limit: Math.max(input.limit ?? 15, 25), + limit: Math.max(input.limit ?? 10, 25), }); const records: CandidateRecord[] = []; for (const result of searchResults) { @@ -421,7 +421,8 @@ function hydrate( } return { ...ref, - score: maxScore > 0 ? Number((candidate.score / maxScore).toFixed(6)) : 0, + // 3 decimals is plenty for a relative-rank hint; 6 just spent bytes on noise. + score: maxScore > 0 ? Number((candidate.score / maxScore).toFixed(3)) : 0, }; }) .filter((result): result is KtxDiscoverDataRef => result !== null); @@ -433,7 +434,7 @@ export function createKtxDiscoverDataService( ): { search(input: KtxDiscoverDataInput): Promise } { return { async search(input) { - const limit = Math.max(1, Math.min(input.limit ?? 15, 50)); + const limit = Math.max(1, Math.min(input.limit ?? 10, 50)); const query = input.query.trim(); if (!query) { return []; diff --git a/packages/cli/src/skills/analytics/SKILL.md b/packages/cli/src/skills/analytics/SKILL.md index e4aa86d2..e6857e56 100644 --- a/packages/cli/src/skills/analytics/SKILL.md +++ b/packages/cli/src/skills/analytics/SKILL.md @@ -28,7 +28,12 @@ You have access to KTX MCP tools for data discovery, semantic-layer analysis, ra - Read entity details before writing SQL against an unfamiliar table. Do not assume column names. - Treat `sql_execution` as read-only. Writes are rejected by the server. - Validate value mentions with `dictionary_search` instead of guessing case or spelling. Treat a `dictionary_search` miss as non-authoritative. The index is built from profile-sampled values, so a missing value may simply have been outside the sample. Follow up with `sql_execution` against the most plausible columns before concluding the value is absent. -- When `connection_list` shows multiple connections, pass an explicit `connectionId` to every tool that takes one and where user intent pins a specific warehouse. Required: `entity_details`, `sl_read_source`, and `sql_execution`. Required when user intent is warehouse-specific, including wording like "in our warehouse" or "this warehouse": `memory_ingest`; without `connectionId`, the memory agent cannot update the semantic layer and the knowledge lands as wiki-only. Pass `connectionId` when intent pins a warehouse, otherwise omit for unscoped discovery: `sl_query`, `discover_data`, and `dictionary_search`. Never pass `connectionId` to `connection_list`, `wiki_search`, `wiki_read`, or `memory_ingest_status`. If intent is ambiguous for a required-or-scoped tool, ask the user which warehouse before calling. +- `connectionId` scoping when `connection_list` shows multiple connections: + - Always pass it: `entity_details`, `sl_read_source`, `sql_execution`. + - Pass it when intent pins a warehouse, otherwise omit for unscoped discovery: `sl_query`, `discover_data`, `dictionary_search`. + - `memory_ingest`: pass it for warehouse-specific knowledge (e.g. "in our warehouse"); without it the memory lands as wiki-only and cannot update the semantic layer. + - Never pass it: `connection_list`, `wiki_search`, `wiki_read`, `memory_ingest_status`. + - If scoping is required but intent is ambiguous, ask which warehouse before calling. - Show compact result tables for small outputs. For broad results, summarize the top findings and mention the applied limit. - Ask a concise clarification only when the metric, date range, entity, or grain is genuinely ambiguous and cannot be inferred from context. diff --git a/packages/cli/test/context/mcp/__snapshots__/mcp-tools-list.json b/packages/cli/test/context/mcp/__snapshots__/mcp-tools-list.json index 10cb0b77..b38851f4 100644 --- a/packages/cli/test/context/mcp/__snapshots__/mcp-tools-list.json +++ b/packages/cli/test/context/mcp/__snapshots__/mcp-tools-list.json @@ -65,7 +65,7 @@ }, "limit": { "default": 10, - "description": "Maximum wiki pages to return. Defaults to 10.", + "description": "Maximum wiki pages to return.", "type": "integer", "minimum": 1, "maximum": 50 @@ -307,7 +307,7 @@ { "name": "sl_query", "title": "Semantic Layer Query", - "description": "Execute a semantic-layer query and return rows, headers, generated SQL, and plan details. Example: sl_query({ connectionId: \"warehouse\", measures: [\"orders.order_count\"], dimensions: [{ field: \"orders.created_at\", granularity: \"month\" }] }).", + "description": "Execute a semantic-layer query and return headers, rows, and total row count, plus correctness notes (e.g. compile-only or fan-out) when relevant. The generated SQL and full query plan are omitted by default; request them with include: [\"sql\"] and/or include: [\"plan\"]. Example: sl_query({ connectionId: \"warehouse\", measures: [\"orders.order_count\"], dimensions: [{ field: \"orders.created_at\", granularity: \"month\" }], include: [\"sql\"] }).", "inputSchema": { "type": "object", "properties": { @@ -403,7 +403,7 @@ }, "direction": { "default": "asc", - "description": "Sort direction: \"asc\" or \"desc\". Defaults to \"asc\".", + "description": "Sort direction for this field.", "type": "string", "enum": [ "asc", @@ -418,15 +418,27 @@ }, "limit": { "default": 1000, - "description": "Maximum rows to return. Defaults to 1000.", + "description": "Maximum rows to return.", "type": "integer", "minimum": 0, "maximum": 9007199254740991 }, "include_empty": { "default": true, - "description": "Whether to include empty dimension groups. Defaults to true.", + "description": "Whether to include empty dimension groups.", "type": "boolean" + }, + "include": { + "default": [], + "description": "Extra detail to attach to the response: \"sql\" for the generated SQL, \"plan\" for the full query plan.", + "type": "array", + "items": { + "type": "string", + "enum": [ + "plan", + "sql" + ] + } } }, "required": [ @@ -443,9 +455,6 @@ "dialect": { "type": "string" }, - "sql": { - "type": "string" - }, "headers": { "type": "array", "items": { @@ -462,6 +471,15 @@ "totalRows": { "type": "number" }, + "notes": { + "type": "array", + "items": { + "type": "string" + } + }, + "sql": { + "type": "string" + }, "plan": { "type": "object", "propertyNames": { @@ -471,7 +489,6 @@ } }, "required": [ - "sql", "headers", "rows", "totalRows" @@ -1241,8 +1258,8 @@ } }, "limit": { - "description": "Maximum refs to return. Defaults to 15.", - "default": 15, + "description": "Maximum refs to return.", + "default": 10, "type": "integer", "minimum": 1, "maximum": 50 @@ -1396,7 +1413,7 @@ "description": "Parser-validated read-only SQL, e.g. \"select count(*) from public.orders\"." }, "maxRows": { - "description": "Maximum rows to return. Defaults to 1000.", + "description": "Maximum rows to return.", "default": 1000, "type": "integer", "minimum": 1, diff --git a/packages/cli/test/context/mcp/server.test.ts b/packages/cli/test/context/mcp/server.test.ts index f6d3e37e..38bc4af9 100644 --- a/packages/cli/test/context/mcp/server.test.ts +++ b/packages/cli/test/context/mcp/server.test.ts @@ -307,16 +307,12 @@ describe('createKtxMcpServer', () => { content: [ { type: 'text', - text: JSON.stringify( - { - headers: ['status', 'count'], - headerTypes: ['text', 'bigint'], - rows: [['paid', 42]], - rowCount: 1, - }, - null, - 2, - ), + text: JSON.stringify({ + headers: ['status', 'count'], + headerTypes: ['text', 'bigint'], + rows: [['paid', 42]], + rowCount: 1, + }), }, ], structuredContent: { @@ -598,6 +594,92 @@ describe('createKtxMcpServer', () => { ); }); + it('sl_query default response omits plan and sql but keeps compile-only and fan-out notes', async () => { + const fake = makeFakeServer(); + const semanticLayer: KtxSemanticLayerMcpPort = { + readSource: vi.fn(), + query: vi.fn().mockResolvedValue({ + connectionId: 'warehouse', + dialect: 'postgres', + sql: 'select count(*) from public.orders', + headers: ['order_count'], + rows: [], + totalRows: 0, + plan: { + sources_used: ['orders'], + has_fan_out: true, + fan_out_description: 'orders fans out across line_items', + execution: { mode: 'compile_only', reason: 'No execution adapter configured.' }, + }, + }), + }; + + createKtxMcpServer({ + server: fake.server, + userContext: { userId: 'local-user' }, + contextTools: { semanticLayer }, + }); + + const result = await getTool(fake.tools, 'sl_query').handler({ + connectionId: 'warehouse', + measures: ['orders.order_count'], + }); + + expect(result).toMatchObject({ + structuredContent: { + connectionId: 'warehouse', + dialect: 'postgres', + headers: ['order_count'], + rows: [], + totalRows: 0, + notes: ['No execution adapter configured.', 'orders fans out across line_items'], + }, + }); + const structured = (result as { structuredContent: Record }).structuredContent; + expect(structured.sql).toBeUndefined(); + expect(structured.plan).toBeUndefined(); + }); + + it('sl_query attaches sql and plan only when include requests them', async () => { + const fake = makeFakeServer(); + const plan = { sources_used: ['orders'], execution: { mode: 'executed' } }; + const semanticLayer: KtxSemanticLayerMcpPort = { + readSource: vi.fn(), + query: vi.fn().mockResolvedValue({ + connectionId: 'warehouse', + dialect: 'postgres', + sql: 'select count(*) from public.orders', + headers: ['order_count'], + rows: [[3]], + totalRows: 1, + plan, + }), + }; + + createKtxMcpServer({ + server: fake.server, + userContext: { userId: 'local-user' }, + contextTools: { semanticLayer }, + }); + + const result = await getTool(fake.tools, 'sl_query').handler({ + connectionId: 'warehouse', + measures: ['orders.order_count'], + include: ['plan', 'sql'], + }); + + expect(result).toMatchObject({ + structuredContent: { + sql: 'select count(*) from public.orders', + plan, + rows: [[3]], + totalRows: 1, + }, + }); + const structured = (result as { structuredContent: Record }).structuredContent; + expect(structured.notes).toBeUndefined(); + }); + it('entity_details rejects sql-style schema table ref aliases', async () => { const fake = makeFakeServer(); const entityDetails = makeAllContextTools().entityDetails!; @@ -798,7 +880,7 @@ describe('createKtxMcpServer', () => { connectionId: '00000000-0000-4000-8000-000000000001', }), ).resolves.toEqual({ - content: [{ type: 'text', text: JSON.stringify({ runId: 'run-1' }, null, 2) }], + content: [{ type: 'text', text: JSON.stringify({ runId: 'run-1' }) }], structuredContent: { runId: 'run-1' }, }); expect(ingest.ingest).toHaveBeenCalledWith({ @@ -825,21 +907,17 @@ describe('createKtxMcpServer', () => { content: [ { type: 'text', - text: JSON.stringify( - { - runId: 'run-1', - status: 'done', - stage: 'done', - done: true, - captured: { wiki: ['revenue'], sl: [], xrefs: [] }, - error: null, - commitHash: 'abc123', - skillsLoaded: ['wiki_capture'], - signalDetected: true, - }, - null, - 2, - ), + text: JSON.stringify({ + runId: 'run-1', + status: 'done', + stage: 'done', + done: true, + captured: { wiki: ['revenue'], sl: [], xrefs: [] }, + error: null, + commitHash: 'abc123', + skillsLoaded: ['wiki_capture'], + signalDetected: true, + }), }, ], structuredContent: { @@ -1047,19 +1125,15 @@ describe('createKtxMcpServer', () => { content: [ { type: 'text', - text: JSON.stringify( - { - connections: [ - { - id: '00000000-0000-4000-8000-000000000001', - name: 'Warehouse', - connectionType: 'POSTGRES', - }, - ], - }, - null, - 2, - ), + text: JSON.stringify({ + connections: [ + { + id: '00000000-0000-4000-8000-000000000001', + name: 'Warehouse', + connectionType: 'POSTGRES', + }, + ], + }), }, ], structuredContent: { From 2e5f7f25aa0f586ca01f2aafeffa5e8e64cff1c5 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Sat, 30 May 2026 18:00:25 +0200 Subject: [PATCH 24/61] feat: report MCP client telemetry (#242) --- .../content/docs/community/telemetry.mdx | 20 ++++-- packages/cli/src/context/mcp/context-tools.ts | 27 +++++++- packages/cli/src/context/mcp/server.ts | 4 ++ packages/cli/src/context/mcp/types.ts | 12 ++++ packages/cli/src/telemetry/events.schema.json | 12 +++- packages/cli/src/telemetry/events.ts | 9 ++- packages/cli/src/telemetry/identity.ts | 22 +++--- packages/cli/src/telemetry/index.ts | 8 ++- packages/cli/test/context/mcp/server.test.ts | 46 ++++++++++++- .../test/telemetry/events.snapshot.test.ts | 4 +- packages/cli/test/telemetry/identity.test.ts | 69 +++++++++++++++++++ .../ktx_daemon/telemetry/events.schema.json | 12 +++- 12 files changed, 216 insertions(+), 29 deletions(-) diff --git a/docs-site/content/docs/community/telemetry.mdx b/docs-site/content/docs/community/telemetry.mdx index 9c22b432..81a4f91d 100644 --- a/docs-site/content/docs/community/telemetry.mdx +++ b/docs-site/content/docs/community/telemetry.mdx @@ -3,10 +3,14 @@ title: Telemetry description: Understand what anonymous usage telemetry ktx collects and how to opt out. --- -**ktx** collects anonymous, aggregated usage telemetry from interactive CLI -runs so maintainers can see which commands work, where setup fails, and which -parts of the data-agent workflow need improvement. Telemetry is opt-out and -disabled automatically in CI and non-interactive runs. +**ktx** collects anonymous, aggregated usage telemetry so maintainers can see +which commands work, where setup fails, and which parts of the data-agent +workflow need improvement. Telemetry is opt-out: it turns on the first time you +run **ktx** in an interactive terminal, which prints a one-time notice. From +then on the same install also reports background activity that has no terminal +of its own, such as the local MCP server your agent calls. It stays disabled in +CI, whenever an opt-out is set, and until that first interactive run has shown +the notice. ## Opt out @@ -17,8 +21,7 @@ Use any of these mechanisms to disable telemetry: | `export KTX_TELEMETRY_DISABLED=1` | Disables telemetry for the shell and child processes | | `export DO_NOT_TRACK=1` | Standard do-not-track environment variable | | `CI=1` | Automatic in CI | -| Non-TTY output | Automatic for pipes and scripts | -| Edit `~/.ktx/telemetry.json` and set `"enabled": false` | Persistent for the machine | +| Edit `~/.ktx/telemetry.json` and set `"enabled": false` | Persistent for the machine, including the MCP server | ## What we collect @@ -27,6 +30,11 @@ succeed or fail, and basic environment metadata (CLI version, Node version, OS platform). For project-level analysis, **ktx** sends a salted hash of the project directory — never the raw path. +When an agent reaches **ktx** through MCP, we also record the connecting client +tool's self-reported name and version (for example Claude Desktop, Cursor, or +Cline) so we can see which agents people use **ktx** with. That describes the +tool, never you or your data. + ## What we never collect - File paths, hostnames, environment variable values, or command arguments diff --git a/packages/cli/src/context/mcp/context-tools.ts b/packages/cli/src/context/mcp/context-tools.ts index 057e570b..03cd2ad4 100644 --- a/packages/cli/src/context/mcp/context-tools.ts +++ b/packages/cli/src/context/mcp/context-tools.ts @@ -6,6 +6,7 @@ import type { MemoryAgentInput } from '../../context/memory/types.js'; import { emitTelemetryEvent, mcpTelemetrySampleRate, shouldEmitMcpTelemetry } from '../../telemetry/index.js'; import { scrubErrorClass } from '../../telemetry/scrubber.js'; import type { + KtxMcpClientInfo, KtxMcpContextPorts, KtxMcpProgressCallback, KtxMcpServerLike, @@ -22,6 +23,7 @@ export interface RegisterKtxContextToolsDeps { userContext: KtxMcpUserContext; projectDir?: string; io?: KtxCliIo; + getClientInfo?: () => KtxMcpClientInfo | undefined; } const connectionIdSchema = z.string().min(1); @@ -526,9 +528,24 @@ function registerParsedTool( }); } +/** + * Resolves the connected client's identity into the raw telemetry fields. The + * strings are client-controlled and untrusted, so they only ever land in the + * telemetry property bag — never in paths, logs, or error messages. + */ +function clientTelemetryFields( + getClientInfo: (() => KtxMcpClientInfo | undefined) | undefined, +): { mcpClientName?: string; mcpClientVersion?: string } { + const client = getClientInfo?.(); + return { + ...(client?.name ? { mcpClientName: client.name } : {}), + ...(client?.version ? { mcpClientVersion: client.version } : {}), + }; +} + function instrumentMcpServer( server: KtxMcpServerLike, - telemetry: { projectDir?: string; io?: KtxCliIo }, + telemetry: { projectDir?: string; io?: KtxCliIo; getClientInfo?: () => KtxMcpClientInfo | undefined }, ): KtxMcpServerLike { return { registerTool(name, config, handler) { @@ -548,6 +565,7 @@ function instrumentMcpServer( outcome: isError ? 'error' : 'ok', durationMs: Math.max(0, performance.now() - startedAt), sampleRate: mcpTelemetrySampleRate(), + ...clientTelemetryFields(telemetry.getClientInfo), }, }); } @@ -565,6 +583,7 @@ function instrumentMcpServer( ...(errorClass ? { errorClass } : {}), durationMs: Math.max(0, performance.now() - startedAt), sampleRate: mcpTelemetrySampleRate(), + ...clientTelemetryFields(telemetry.getClientInfo), }, }); } @@ -577,7 +596,11 @@ function instrumentMcpServer( export function registerKtxContextTools(deps: RegisterKtxContextToolsDeps): void { const { ports, userContext } = deps; - const server = instrumentMcpServer(deps.server, { projectDir: deps.projectDir, io: deps.io }); + const server = instrumentMcpServer(deps.server, { + projectDir: deps.projectDir, + io: deps.io, + getClientInfo: deps.getClientInfo, + }); if (ports.connections) { const connections = ports.connections; diff --git a/packages/cli/src/context/mcp/server.ts b/packages/cli/src/context/mcp/server.ts index 97d79525..85871467 100644 --- a/packages/cli/src/context/mcp/server.ts +++ b/packages/cli/src/context/mcp/server.ts @@ -11,6 +11,7 @@ export function createKtxMcpServer(deps: KtxMcpServerDeps): KtxMcpServerDeps['se userContext: deps.userContext, projectDir: deps.projectDir, io: deps.io, + getClientInfo: deps.getClientInfo, }); } @@ -30,6 +31,9 @@ export function createDefaultKtxMcpServer( contextTools: deps.contextTools, projectDir: deps.projectDir, io: deps.io, + // The SDK populates the client identity after the initialize handshake, so + // read it lazily at emit time rather than at registration (undefined here). + getClientInfo: () => server.server.getClientVersion(), }); return server; } diff --git a/packages/cli/src/context/mcp/types.ts b/packages/cli/src/context/mcp/types.ts index e9fc0ff2..3694e3d6 100644 --- a/packages/cli/src/context/mcp/types.ts +++ b/packages/cli/src/context/mcp/types.ts @@ -50,6 +50,16 @@ export interface KtxMcpUserContext { userId: string; } +/** + * Identity of the connected MCP client tool (e.g. Claude Desktop, Cursor), + * read from the initialize handshake. Untrusted, client-controlled strings — + * use only as telemetry properties, never to build paths or log lines. + */ +export interface KtxMcpClientInfo { + name: string; + version: string; +} + export interface KtxMcpServerLike { registerTool( name: string, @@ -177,4 +187,6 @@ export interface KtxMcpServerDeps { contextTools?: KtxMcpContextPorts; projectDir?: string; io?: KtxCliIo; + /** Reads the connected client's identity once the initialize handshake completes. */ + getClientInfo?: () => KtxMcpClientInfo | undefined; } diff --git a/packages/cli/src/telemetry/events.schema.json b/packages/cli/src/telemetry/events.schema.json index 628c8f4b..acad7988 100644 --- a/packages/cli/src/telemetry/events.schema.json +++ b/packages/cli/src/telemetry/events.schema.json @@ -157,7 +157,9 @@ "outcome", "durationMs", "errorClass", - "sampleRate" + "sampleRate", + "mcpClientName", + "mcpClientVersion" ] }, { @@ -1131,7 +1133,13 @@ }, "sampleRate": { "type": "number", - "const": 0.1 + "const": 1 + }, + "mcpClientName": { + "type": "string" + }, + "mcpClientVersion": { + "type": "string" } }, "required": [ diff --git a/packages/cli/src/telemetry/events.ts b/packages/cli/src/telemetry/events.ts index 5e5b5335..e751cd70 100644 --- a/packages/cli/src/telemetry/events.ts +++ b/packages/cli/src/telemetry/events.ts @@ -156,7 +156,12 @@ const mcpRequestCompletedSchema = telemetryCommonEnvelopeSchema outcome: outcomeSchema, durationMs: z.number().nonnegative(), errorClass: z.string().optional(), - sampleRate: z.literal(0.1), + sampleRate: z.literal(1), + // Raw, client-tool-controlled identity from the MCP initialize handshake + // (clientInfo.name/version). Optional: clients may omit clientInfo. Stored + // verbatim — normalize the free-form names at query time, not at write time. + mcpClientName: z.string().optional(), + mcpClientVersion: z.string().optional(), }) .strict(); @@ -325,7 +330,7 @@ export const telemetryEventCatalog = [ { name: 'mcp_request_completed', description: 'Emitted for sampled MCP tool requests.', - fields: ['toolName', 'outcome', 'durationMs', 'errorClass', 'sampleRate'], + fields: ['toolName', 'outcome', 'durationMs', 'errorClass', 'sampleRate', 'mcpClientName', 'mcpClientVersion'], }, { name: 'daemon_started', diff --git a/packages/cli/src/telemetry/identity.ts b/packages/cli/src/telemetry/identity.ts index 4d46307c..69985f00 100644 --- a/packages/cli/src/telemetry/identity.ts +++ b/packages/cli/src/telemetry/identity.ts @@ -75,17 +75,14 @@ export async function loadTelemetryIdentity(options: LoadTelemetryIdentityOption const env = options.env ?? process.env; const path = telemetryPath(options.homeDir ?? homedir()); - if (envDisablesTelemetry(env) || options.stdoutIsTTY !== true) { - const existing = await readTelemetryFile(path); - return { - installId: existing?.installId, - enabled: false, - createdFile: false, - noticeShown: false, - path, - }; + if (envDisablesTelemetry(env)) { + return { enabled: false, createdFile: false, noticeShown: false, path }; } + // Honor an already-consented identity regardless of the current surface. + // Telemetry enablement follows the persisted decision and opt-out env vars, + // not whether this invocation happens to own a TTY — MCP servers always run + // headless (stdio stubs stdout; the HTTP server runs detached). const existing = await readTelemetryFile(path); if (existing) { return { @@ -97,6 +94,13 @@ export async function loadTelemetryIdentity(options: LoadTelemetryIdentityOption }; } + // No identity yet. Minting one means showing the one-time opt-out notice, so + // first-run creation requires an interactive surface; a headless first run + // stays disabled and defers enablement until the next interactive run. + if (options.stdoutIsTTY !== true) { + return { enabled: false, createdFile: false, noticeShown: false, path }; + } + const timestamp = (options.now ?? (() => new Date()))().toISOString(); const next = { installId: randomUUID(), diff --git a/packages/cli/src/telemetry/index.ts b/packages/cli/src/telemetry/index.ts index 27c5004a..c5b9b729 100644 --- a/packages/cli/src/telemetry/index.ts +++ b/packages/cli/src/telemetry/index.ts @@ -52,7 +52,11 @@ type TelemetryEventFields = Omit< >; const emittedProjectSnapshots = new Set(); -const MCP_SAMPLE_RATE = 0.1 as const; +// MCP tool calls are captured at full rate while ktx is early-stage: at current +// install counts any sampling below 1.0 yields too few events to be useful, and +// the recorded sampleRate lets us dial this down (and reweight history) once +// per-session call volume justifies it. +const MCP_SAMPLE_RATE = 1 as const; let mcpSampled: boolean | undefined; function telemetryDebugEnabled(): boolean { @@ -64,7 +68,7 @@ export function shouldEmitMcpTelemetry(): boolean { return mcpSampled; } -export function mcpTelemetrySampleRate(): 0.1 { +export function mcpTelemetrySampleRate(): 1 { return MCP_SAMPLE_RATE; } diff --git a/packages/cli/test/context/mcp/server.test.ts b/packages/cli/test/context/mcp/server.test.ts index 38bc4af9..95985d68 100644 --- a/packages/cli/test/context/mcp/server.test.ts +++ b/packages/cli/test/context/mcp/server.test.ts @@ -47,10 +47,10 @@ function makeFakeServer() { }; } -function makeIo() { +function makeIo(stdoutIsTTY = true) { let stderr = ''; return { - stdout: { isTTY: true, write() {} }, + stdout: { isTTY: stdoutIsTTY, write() {} }, stderr: { write(chunk: string) { stderr += chunk; @@ -272,8 +272,48 @@ describe('createKtxMcpServer', () => { expect(io.stderrText()).toContain('"event":"mcp_request_completed"'); expect(io.stderrText()).toContain('"toolName":"wiki_search"'); - expect(io.stderrText()).toContain('"sampleRate":0.1'); + expect(io.stderrText()).toContain('"sampleRate":1'); expect(io.stderrText()).not.toContain(projectDir); + // No client connected through the SDK here, so getClientInfo is absent: the + // event still emits and the optional client fields are simply omitted. + expect(io.stderrText()).not.toContain('mcpClientName'); + expect(io.stderrText()).not.toContain('mcpClientVersion'); + }); + + it('captures the connecting MCP client name and version', async () => { + vi.stubEnv('KTX_TELEMETRY_DEBUG', '1'); + vi.stubEnv('CI', ''); + // Non-TTY io keeps the test hermetic (no ~/.ktx/telemetry.json is created) + // and mirrors a real headless MCP server; debug mode still emits the payload. + const io = makeIo(false); + + const server = createDefaultKtxMcpServer({ + name: 'ktx-test', + version: '0.0.0-test', + userContext: { userId: 'mcp-user' }, + projectDir: '/tmp/ktx-mcp-client-telemetry', + io, + contextTools: { + knowledge: { + search: vi.fn().mockResolvedValue({ results: [], totalFound: 0 }), + read: vi.fn().mockResolvedValue(null), + }, + }, + }); + const client = new Client({ name: 'test-agent', version: '9.9.9' }); + const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair(); + await Promise.all([server.connect(serverTransport), client.connect(clientTransport)]); + + try { + await client.callTool({ name: 'wiki_search', arguments: { query: 'revenue recognition', limit: 5 } }); + } finally { + await client.close(); + await server.close(); + } + + expect(io.stderrText()).toContain('"event":"mcp_request_completed"'); + expect(io.stderrText()).toContain('"mcpClientName":"test-agent"'); + expect(io.stderrText()).toContain('"mcpClientVersion":"9.9.9"'); }); it('registers parser-gated sql_execution when the host provides a SQL execution port', async () => { diff --git a/packages/cli/test/telemetry/events.snapshot.test.ts b/packages/cli/test/telemetry/events.snapshot.test.ts index 7a1b76f7..1ea67339 100644 --- a/packages/cli/test/telemetry/events.snapshot.test.ts +++ b/packages/cli/test/telemetry/events.snapshot.test.ts @@ -128,7 +128,9 @@ describe('telemetry privacy snapshot', () => { outcome: 'error', errorClass: 'KtxProjectMissingAbortError', durationMs: 12, - sampleRate: 0.1, + sampleRate: 1, + mcpClientName: 'Claude Desktop', + mcpClientVersion: '0.7.1', }), ]; diff --git a/packages/cli/test/telemetry/identity.test.ts b/packages/cli/test/telemetry/identity.test.ts index 31c3bfb5..e5b6bddf 100644 --- a/packages/cli/test/telemetry/identity.test.ts +++ b/packages/cli/test/telemetry/identity.test.ts @@ -146,6 +146,75 @@ describe('telemetry identity', () => { }); }); + it('enables a consented identity without a TTY (MCP servers run headless)', async () => { + await mkdir(join(homeDir, '.ktx'), { recursive: true }); + await writeFile( + join(homeDir, '.ktx', 'telemetry.json'), + JSON.stringify( + { + installId: '00000000-0000-4000-8000-000000000000', + enabled: true, + noticeShownAt: '2026-05-22T14:33:02.000Z', + noticeShownVersion: 1, + createdAt: '2026-05-22T14:33:02.000Z', + }, + null, + 2, + ) + '\n', + 'utf-8', + ); + const testIo = makeIo(false); + + await expect( + loadTelemetryIdentity({ + homeDir, + env, + stdoutIsTTY: false, + stderr: testIo.io.stderr, + now: () => new Date('2026-05-22T15:00:00.000Z'), + }), + ).resolves.toMatchObject({ + installId: '00000000-0000-4000-8000-000000000000', + enabled: true, + createdFile: false, + noticeShown: false, + }); + // The one-time notice belongs to interactive surfaces only; a headless load + // must never write it (the MCP stdio protocol shares the process streams). + expect(testIo.stderr()).toBe(''); + }); + + it('keeps opt-outs suppressing a consented identity without a TTY', async () => { + await mkdir(join(homeDir, '.ktx'), { recursive: true }); + await writeFile( + join(homeDir, '.ktx', 'telemetry.json'), + JSON.stringify( + { + installId: '00000000-0000-4000-8000-000000000000', + enabled: true, + noticeShownAt: '2026-05-22T14:33:02.000Z', + noticeShownVersion: 1, + createdAt: '2026-05-22T14:33:02.000Z', + }, + null, + 2, + ) + '\n', + 'utf-8', + ); + + for (const optOut of [{ KTX_TELEMETRY_DISABLED: '1' }, { DO_NOT_TRACK: '1' }, { CI: '1' }]) { + await expect( + loadTelemetryIdentity({ + homeDir, + env: optOut, + stdoutIsTTY: false, + stderr: makeIo(false).io.stderr, + now: () => new Date('2026-05-22T15:00:00.000Z'), + }), + ).resolves.toMatchObject({ enabled: false }); + } + }); + it('recreates a corrupted file instead of surfacing an error to users', async () => { await mkdir(join(homeDir, '.ktx'), { recursive: true }); await writeFile(join(homeDir, '.ktx', 'telemetry.json'), '{bad json', 'utf-8'); diff --git a/python/ktx-daemon/src/ktx_daemon/telemetry/events.schema.json b/python/ktx-daemon/src/ktx_daemon/telemetry/events.schema.json index 628c8f4b..acad7988 100644 --- a/python/ktx-daemon/src/ktx_daemon/telemetry/events.schema.json +++ b/python/ktx-daemon/src/ktx_daemon/telemetry/events.schema.json @@ -157,7 +157,9 @@ "outcome", "durationMs", "errorClass", - "sampleRate" + "sampleRate", + "mcpClientName", + "mcpClientVersion" ] }, { @@ -1131,7 +1133,13 @@ }, "sampleRate": { "type": "number", - "const": 0.1 + "const": 1 + }, + "mcpClientName": { + "type": "string" + }, + "mcpClientVersion": { + "type": "string" } }, "required": [ From 95a265323a50971c83db6e8150f329a06fbc5566 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Sat, 30 May 2026 18:33:14 +0200 Subject: [PATCH 25/61] feat(telemetry): enable PostHog GeoIP enrichment (#243) Set disableGeoip: false on the CLI telemetry client so events are enriched with approximate, IP-based location at ingest. Update the first-run notice, public telemetry docs, and the AGENTS telemetry policy to drop the prior "anonymous" wording to match. --- AGENTS.md | 2 +- docs-site/content/docs/community/telemetry.mdx | 4 ++-- packages/cli/src/telemetry/emitter.ts | 2 +- packages/cli/src/telemetry/identity.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 2aa0dbed..ea79a0a9 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -278,7 +278,7 @@ use `PascalCase` without the suffix. ## Telemetry -**ktx** ships anonymous PostHog telemetry. When adding commands or events: +**ktx** ships PostHog usage telemetry. When adding commands or events: - **MUST NOT**: Add fields that carry user data — file paths, hostnames, environment values, SQL text, schema/table/column names, error messages, diff --git a/docs-site/content/docs/community/telemetry.mdx b/docs-site/content/docs/community/telemetry.mdx index 81a4f91d..c2a9af21 100644 --- a/docs-site/content/docs/community/telemetry.mdx +++ b/docs-site/content/docs/community/telemetry.mdx @@ -1,9 +1,9 @@ --- title: Telemetry -description: Understand what anonymous usage telemetry ktx collects and how to opt out. +description: Understand what usage telemetry ktx collects and how to opt out. --- -**ktx** collects anonymous, aggregated usage telemetry so maintainers can see +**ktx** collects aggregated usage telemetry so maintainers can see which commands work, where setup fails, and which parts of the data-agent workflow need improvement. Telemetry is opt-out: it turns on the first time you run **ktx** in an interactive terminal, which prints a one-time notice. From diff --git a/packages/cli/src/telemetry/emitter.ts b/packages/cli/src/telemetry/emitter.ts index 435a122b..3344e00b 100644 --- a/packages/cli/src/telemetry/emitter.ts +++ b/packages/cli/src/telemetry/emitter.ts @@ -44,7 +44,7 @@ async function getPostHogClient(projectApiKey: string, host: string): Promise new PostHog(projectApiKey, { host, flushAt: 1, flushInterval: 0 })) + .then(({ PostHog }) => new PostHog(projectApiKey, { host, flushAt: 1, flushInterval: 0, disableGeoip: false })) .catch(() => null); return await clientPromise; diff --git a/packages/cli/src/telemetry/identity.ts b/packages/cli/src/telemetry/identity.ts index 69985f00..d699ea1f 100644 --- a/packages/cli/src/telemetry/identity.ts +++ b/packages/cli/src/telemetry/identity.ts @@ -6,7 +6,7 @@ import { z } from 'zod'; /** @internal */ export const TELEMETRY_NOTICE = - 'ktx collects anonymous usage data to improve the product. Opt out: set KTX_TELEMETRY_DISABLED=1.'; + 'ktx collects usage data to improve the product. Opt out: set KTX_TELEMETRY_DISABLED=1.'; const NOTICE_VERSION = 1; From 2058c26e84304e6a2dede650e991b507f396d9cc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 30 May 2026 18:28:06 +0000 Subject: [PATCH 26/61] chore: refresh star history chart [skip ci] --- assets/star-history.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/star-history.svg b/assets/star-history.svg index 3f6c4a04..39efe2b6 100644 --- a/assets/star-history.svg +++ b/assets/star-history.svg @@ -1 +1 @@ -star-history.comMay 17May 24 100200300400kaelio/ktxStar HistoryDateGitHub Stars +star-history.comMay 17May 24 100200300400500kaelio/ktxStar HistoryDateGitHub Stars From c196d1f192d83f80abaaaa2a9da15a24802beaca Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 18:29:55 +0000 Subject: [PATCH 27/61] chore: refresh star history chart [skip ci] --- assets/star-history.svg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/star-history.svg b/assets/star-history.svg index 39efe2b6..16b5fc6a 100644 --- a/assets/star-history.svg +++ b/assets/star-history.svg @@ -1 +1 @@ -star-history.comMay 17May 24 100200300400500kaelio/ktxStar HistoryDateGitHub Stars +star-history.comMay 17May 24May 31 100200300400500600kaelio/ktxStar HistoryDateGitHub Stars From d320d54ab29f4d979027188665d3172f5a32e327 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Sun, 31 May 2026 23:44:33 +0200 Subject: [PATCH 28/61] feat(cli): shell completion for commands, flags, and entity names (#244) * feat(completion): complete known argument values * fix(completion): hide Commander-hidden subcommands from completions Replace the `__`-prefix name heuristic with Commander's `_hidden` flag so internal subcommands registered with { hidden: true } (e.g. `mcp serve-internal`) are excluded from completions, mirroring `ktx --help`. * test: cover wiki and sl read command routing * test: cover raw wiki and sl reads * feat: add wiki read command * feat: add sl read command * feat: complete read command entity names * docs: document wiki and sl read commands * test: include read commands in command tree * feat(sl): read and validate unique sources by name * feat(sl): make read and validate connection id optional * fix(completion): dedupe semantic source names * docs(sl): document connection-optional read and validate * fix(sl): require connection id for query command * docs(sl): clarify query connection requirement * fix(completion): don't resolve option values as subcommands resolveCommand skipped flag tokens but not the value consumed by a value-taking option in the `--flag value` form, so a connection id like `query` was matched as the `sl query` subcommand and yielded no `sl` completions. Track value-taking options and skip their consumed value before matching subcommands. * test(telemetry): assert first-run notice via TELEMETRY_NOTICE constant CI (which tests this branch merged with main) failed because #243 changed the first-run notice wording in identity.ts (dropped "anonymous") but left this test grepping for the old literal 'ktx collects anonymous usage data', so indexOf returned -1. Assert against the exported TELEMETRY_NOTICE constant instead so the test tracks the source of truth and cannot drift when the notice text changes again. --- .../docs/cli-reference/ktx-completion.mdx | 86 ++++++ .../content/docs/cli-reference/ktx-sl.mdx | 45 ++- .../content/docs/cli-reference/ktx-wiki.mdx | 28 +- docs-site/content/docs/cli-reference/ktx.mdx | 7 + .../content/docs/cli-reference/meta.json | 3 +- packages/cli/src/cli-program.ts | 7 + packages/cli/src/command-tree.ts | 6 +- .../cli/src/commands/completion-commands.ts | 44 +++ .../cli/src/commands/knowledge-commands.ts | 18 +- packages/cli/src/commands/sl-commands.ts | 29 +- .../cli/src/completion/complete-engine.ts | 172 ++++++++++++ .../cli/src/completion/completion-scripts.ts | 39 +++ .../cli/src/completion/dynamic-candidates.ts | 103 +++++++ packages/cli/src/context/sl/local-sl.ts | 42 +++ .../cli/src/context/wiki/local-knowledge.ts | 26 ++ packages/cli/src/knowledge.ts | 20 +- packages/cli/src/sl.ts | 59 +++- .../cli/test/cli-program-telemetry.test.ts | 3 +- .../commands/wiki-sl-read-commands.test.ts | 157 +++++++++++ .../test/completion/complete-engine.test.ts | 137 +++++++++ .../completion/completion-scripts.test.ts | 20 ++ .../completion/dynamic-candidates.test.ts | 103 +++++++ packages/cli/test/context/sl/local-sl.test.ts | 96 +++++++ .../test/context/wiki/local-knowledge.test.ts | 30 ++ packages/cli/test/index.test.ts | 55 +++- packages/cli/test/knowledge.test.ts | 40 +++ packages/cli/test/print-command-tree.test.ts | 14 +- packages/cli/test/sl.test.ts | 261 ++++++++++++++++++ 28 files changed, 1596 insertions(+), 54 deletions(-) create mode 100644 docs-site/content/docs/cli-reference/ktx-completion.mdx create mode 100644 packages/cli/src/commands/completion-commands.ts create mode 100644 packages/cli/src/completion/complete-engine.ts create mode 100644 packages/cli/src/completion/completion-scripts.ts create mode 100644 packages/cli/src/completion/dynamic-candidates.ts create mode 100644 packages/cli/test/commands/wiki-sl-read-commands.test.ts create mode 100644 packages/cli/test/completion/complete-engine.test.ts create mode 100644 packages/cli/test/completion/completion-scripts.test.ts create mode 100644 packages/cli/test/completion/dynamic-candidates.test.ts diff --git a/docs-site/content/docs/cli-reference/ktx-completion.mdx b/docs-site/content/docs/cli-reference/ktx-completion.mdx new file mode 100644 index 00000000..94f1c383 --- /dev/null +++ b/docs-site/content/docs/cli-reference/ktx-completion.mdx @@ -0,0 +1,86 @@ +--- +title: "ktx completion" +description: "Print a shell completion script for tab completion." +--- + +Print a shell completion script for **ktx**. Once installed, pressing Tab +completes commands, subcommands, and flags, and - inside a **ktx** project - the +names of things that already exist: semantic-layer source names for +`ktx sl read` and `ktx sl validate`, wiki page keys for `ktx wiki read`, and +configured connection ids for `ktx connection test`, `ktx ingest`, and +`ktx sql`. This saves you from remembering exact source, page, or connection +names. + +## Command signature + +```bash +ktx completion +``` + +`` must be `zsh` or `bash`. The command writes the script to stdout; it +does not modify any files. Enable completion by evaluating the script in your +shell startup file. + +## Installation + +Add the matching line to your shell startup file, then restart your shell (or +`source` the file). `ktx` must be on your `PATH`. + +```bash +# zsh — add to ~/.zshrc +eval "$(ktx completion zsh)" +``` + +```bash +# bash — add to ~/.bashrc +eval "$(ktx completion bash)" +``` + +To try it for the current session only, run the same `eval` line directly in +your terminal. + +## What gets completed + +| Position | Completions | +|----------|-------------| +| `ktx ` | Top-level commands (`setup`, `sl`, `wiki`, `ingest`, …) | +| `ktx sl ` | The `read` / `validate` / `query` subcommands | +| `ktx sl read ` | Existing semantic-layer source names | +| `ktx sl validate ` | Existing semantic-layer source names | +| `ktx wiki ` | The `read` subcommand | +| `ktx wiki read ` | Existing wiki page keys | +| `ktx connection test ` | Configured connection ids | +| `ktx ingest ` | Configured connection ids | +| `ktx sql --connection ` | Configured connection ids | +| `ktx completion ` | `zsh` or `bash` | +| `ktx --` | The command's flags and inherited global flags | +| `ktx sl --output ` | An option's allowed values (here `pretty`, `plain`, `json`) | +| `ktx sl --connection-id ` | Configured connection ids | + +Source names, wiki page keys, and connection ids are read from the **ktx** +project resolved from your current directory (or `--project-dir` / +`KTX_PROJECT_DIR`). Outside a **ktx** project, completion still suggests +commands and flags but no project entities. Bare `ktx sl ` and +`ktx wiki ` complete subcommands instead of entity names because their +positional arguments are free-text search queries. + +## Examples + +```bash +# Print the zsh completion script +ktx completion zsh + +# Print the bash completion script +ktx completion bash + +# Install for zsh +echo 'eval "$(ktx completion zsh)"' >> ~/.zshrc +``` + +## Common errors + +| Error | Cause | Recovery | +|-------|-------|----------| +| `error: command-argument value '' is invalid for argument 'shell'. Allowed choices are zsh, bash.` | A shell other than `zsh` or `bash` was requested | Re-run with `ktx completion zsh` or `ktx completion bash` | +| Tab completion does nothing | The script was not evaluated, or `ktx` is not on `PATH` | Confirm the `eval` line is in your startup file, restart the shell, and verify `ktx --version` runs | +| Source, page, or connection names are missing | The current directory is not inside a **ktx** project | Run from the project directory, or pass `--project-dir`, or set `KTX_PROJECT_DIR` | diff --git a/docs-site/content/docs/cli-reference/ktx-sl.mdx b/docs-site/content/docs/cli-reference/ktx-sl.mdx index 2dfba7ab..9e957d4e 100644 --- a/docs-site/content/docs/cli-reference/ktx-sl.mdx +++ b/docs-site/content/docs/cli-reference/ktx-sl.mdx @@ -11,13 +11,16 @@ the vocabulary agents use to generate correct SQL. ```bash ktx sl [options] [query...] # list (bare) or search (with query) -ktx sl validate [options] +ktx sl read +ktx sl validate ktx sl query [options] ``` - Bare `ktx sl` lists semantic sources. -- `ktx sl ` searches semantic sources (multi-word queries are - joined with a space). +- `ktx sl ` searches semantic sources. Multi-word queries are joined + with a space. +- `ktx sl read ` prints the YAML for one source. Add + `--connection-id` only when the source name exists in multiple connections. - `ktx sl validate` and `ktx sl query` remain as explicit subcommands. ## Subcommands @@ -26,6 +29,7 @@ ktx sl query [options] |-----------|-------------| | (none, no query) | List semantic sources | | (none, with query) | Search semantic sources | +| `read ` | Print the YAML for one semantic source | | `validate ` | Validate a semantic source against the database schema | | `query` | Compile or execute a semantic query | @@ -40,17 +44,23 @@ ktx sl query [options] | `--output ` | Output mode: `pretty` (default in TTY), `plain` (TSV), or `json` | `pretty` | | `--json` | Shortcut for `--output=json` (overrides `--output`) | `false` | +### `sl read` + +| Flag | Description | Default | +|------|-------------|---------| +| `--connection-id ` | Optional **ktx** connection id for disambiguation | - | + ### `sl validate` | Flag | Description | Default | |------|-------------|---------| -| `--connection-id ` | **ktx** connection id (required) | - | +| `--connection-id ` | Optional **ktx** connection id for disambiguation | - | ### `sl query` | Flag | Description | Default | |------|-------------|---------| -| `--connection-id ` | **ktx** connection id | - | +| `--connection-id ` | Required **ktx** connection id | - | | `--query-file ` | JSON semantic query file | - | | `--measure ` | Measure to query; repeatable (at least one required) | - | | `--dimension ` | Dimension to include; repeatable | - | @@ -65,8 +75,9 @@ ktx sl query [options] | `--no-input` | Disable interactive managed runtime installation | - | | `--max-rows ` | Maximum rows to return when executing | - | -`sl query` requires at least one `--measure` unless `--query-file` is set. -`--query-file` should point to a JSON semantic query object. +`sl query` requires `--connection-id` and at least one `--measure` unless +`--query-file` is set. `--query-file` must point to a JSON semantic query +object. ## Examples @@ -83,7 +94,16 @@ ktx sl --json # Search sources as JSON ktx sl "revenue" --json -# Validate a source against the live schema +# Print the YAML for a source name that is unique across connections +ktx sl read orders + +# Print the YAML for a source name that exists in multiple connections +ktx sl --connection-id my-warehouse read orders + +# Validate a source name that is unique across connections +ktx sl validate orders + +# Validate a source name that exists in multiple connections ktx sl validate orders --connection-id my-warehouse # Compile a query and view the generated SQL @@ -144,6 +164,12 @@ shows `#1`, `#2`, and later rank badges for the displayed results. Plain and JSON output keep the raw `score` value, which is a ranking score rather than a percentage. +`ktx sl read ` prints the source YAML directly to stdout when the +source name is unique across connections. If the name exists in multiple +connections, rerun the command with `--connection-id `. The command does +not wrap output in pretty, plain, or JSON formatting, so it can be piped to +other tools. + ```json { "sql": "SELECT orders.status, SUM(orders.total_amount) AS total_revenue FROM public.orders GROUP BY orders.status", @@ -160,7 +186,8 @@ percentage. | Error | Cause | Recovery | |-------|-------|----------| -| Source not found | Source name or connection id is wrong | Run `ktx sl --json` and retry with an exact source name and connection id | +| Source not found | Source name or connection id is wrong | Run `ktx sl ` or `ktx sl --connection-id ` to find the exact source name, then retry `ktx sl read ` or `ktx sl validate ` | +| Source name is ambiguous | The same source name exists in multiple connections | Rerun with `--connection-id ` from the error message | | Validation fails | YAML references missing columns, invalid joins, or invalid SQL expressions | Fix the source YAML and rerun `ktx sl validate` | | Query compile fails | Measure, dimension, filter, or segment name is invalid | Search sources with `ktx sl `, inspect the source YAML in your project files, then retry using declared fields | | Execution returns too many rows | `--max-rows` is missing or too high | Add `--max-rows` with a bounded value before executing | diff --git a/docs-site/content/docs/cli-reference/ktx-wiki.mdx b/docs-site/content/docs/cli-reference/ktx-wiki.mdx index 2d52d5af..7887a463 100644 --- a/docs-site/content/docs/cli-reference/ktx-wiki.mdx +++ b/docs-site/content/docs/cli-reference/ktx-wiki.mdx @@ -1,21 +1,24 @@ --- title: "ktx wiki" -description: "List or search wiki pages." +description: "List, search, or read wiki pages." --- -List and search wiki pages in your **ktx** project. Wiki pages are Markdown -documents that capture business definitions, rules, and gotchas. Agents search -them for context when answering questions about your data. +List, search, and read wiki pages in your **ktx** project. Wiki pages are +Markdown documents that capture business definitions, rules, and gotchas. +Agents search them for context when answering questions about your data. ## Command signature ```bash -ktx wiki [options] [query...] +ktx wiki [options] [query...] # list (bare) or search (with query) +ktx wiki read ``` - Bare `ktx wiki` lists local wiki pages. -- `ktx wiki ` searches local wiki pages (multi-word queries are - joined with a space). +- `ktx wiki ` searches local wiki pages. Multi-word queries are + joined with a space. +- `ktx wiki read ` prints the whole Markdown file for one wiki page, + including YAML frontmatter. Edit the Markdown files under `wiki/` directly, or ingest source content with `ktx ingest`, when you need to add or update wiki knowledge. @@ -50,6 +53,9 @@ ktx wiki "monthly recurring revenue" # Search wiki pages as JSON ktx wiki "monthly recurring revenue" --json --limit 10 +# Print the exact Markdown file for a known page key +ktx wiki read revenue-definitions + # Print search results as TSV ktx wiki "monthly recurring revenue" --output plain @@ -62,8 +68,10 @@ ktx --debug wiki "monthly recurring revenue" --json Wiki commands print clack-style pretty output in a TTY and TSV-style plain output when requested. JSON output wraps the items with a command metadata envelope. Search results include `matchReasons` and `lanes` metadata so you can -see whether lexical, token, or semantic search contributed to the ranking. Open -the matching Markdown files directly when you need the full page contents. +see whether lexical, token, or semantic search contributed to the ranking. Use +`ktx wiki read ` when you need the full page contents. Read output is the +exact Markdown file stored on disk, including YAML frontmatter, and is not +wrapped in pretty, plain, or JSON formatting. Pretty search output shows `#1`, `#2`, and later rank badges for the displayed results. Plain and JSON output keep the raw `score` value, which is a ranking score rather than a percentage. @@ -121,4 +129,4 @@ stays machine-readable: | Error | Cause | Recovery | |-------|-------|----------| | Search returns no results | The query terms do not match summaries, tags, or content, and the semantic lane is unavailable or has no positive matches | Run with `--debug`, check the semantic lane status, retry with business synonyms, then create a page if the knowledge is missing | -| A page is missing | No Markdown file exists for that business context | Add a file under `wiki/` or run `ktx ingest ` | +| A page is missing | No Markdown file exists for that business context or `ktx wiki read ` used the wrong key | Run `ktx wiki ` to find the page key, then retry `ktx wiki read ` | diff --git a/docs-site/content/docs/cli-reference/ktx.mdx b/docs-site/content/docs/cli-reference/ktx.mdx index 010100d8..8b9a2cc5 100644 --- a/docs-site/content/docs/cli-reference/ktx.mdx +++ b/docs-site/content/docs/cli-reference/ktx.mdx @@ -36,9 +36,11 @@ ktx wiki list search + read sl list search + read validate query sql @@ -57,6 +59,7 @@ ktx stop status reindex + completion ``` The public context-build entrypoint is `ktx ingest [connectionId]` or @@ -97,6 +100,10 @@ ktx ingest ktx sl "revenue" ktx wiki "revenue recognition" +# Print a known wiki page or semantic source +ktx wiki read revenue-definitions +ktx sl --connection-id warehouse read orders + # Execute read-only SQL ktx sql --connection warehouse "select count(*) from public.orders" diff --git a/docs-site/content/docs/cli-reference/meta.json b/docs-site/content/docs/cli-reference/meta.json index 49eb8ba7..2902f2c6 100644 --- a/docs-site/content/docs/cli-reference/meta.json +++ b/docs-site/content/docs/cli-reference/meta.json @@ -11,6 +11,7 @@ "ktx-wiki", "ktx-status", "ktx-mcp", - "ktx-admin" + "ktx-admin", + "ktx-completion" ] } diff --git a/packages/cli/src/cli-program.ts b/packages/cli/src/cli-program.ts index a3c27375..31ab8a03 100644 --- a/packages/cli/src/cli-program.ts +++ b/packages/cli/src/cli-program.ts @@ -2,6 +2,7 @@ import { existsSync } from 'node:fs'; import { join } from 'node:path'; import { Command, type CommandUnknownOpts, InvalidArgumentError } from '@commander-js/extra-typings'; import type { KtxCliDeps, KtxCliIo, KtxCliPackageInfo } from './cli-runtime.js'; +import { registerCompletionCommands } from './commands/completion-commands.js'; import { registerConnectionCommands } from './commands/connection-commands.js'; import { registerIngestCommands } from './commands/ingest-commands.js'; import { registerWikiCommands } from './commands/knowledge-commands.js'; @@ -431,6 +432,11 @@ export function collectCommandFlagsPresent(command: CommandUnknownOpts): Record< export function buildKtxProgram(options: BuildKtxProgramOptions): Command { const program = createBaseProgram(options.packageInfo, options.io); program.hook('preAction', async (_thisCommand, actionCommand) => { + // The hidden completion command must stay silent and side-effect free: skip + // the telemetry notice, command span, and project checks entirely. + if (commandPath(actionCommand as CommandPathNode).includes('__complete')) { + return; + } const telemetry = await import('./telemetry/index.js'); options.setTelemetryModule?.(telemetry); await telemetry.showTelemetryNoticeIfNeeded(options.io, options.packageInfo); @@ -476,6 +482,7 @@ export function buildKtxProgram(options: BuildKtxProgramOptions): Command { registerStatusCommands(program, context); registerMcpCommands(program, context); registerAdminCommands(program, context); + registerCompletionCommands(program, context); return program; } diff --git a/packages/cli/src/command-tree.ts b/packages/cli/src/command-tree.ts index 2eeb24e8..9b5bf729 100644 --- a/packages/cli/src/command-tree.ts +++ b/packages/cli/src/command-tree.ts @@ -16,7 +16,11 @@ export function walkCommandTree(command: CommandUnknownOpts): CommandTreeNode { description: command.description(), aliases: command.aliases(), arguments: command.registeredArguments.map(formatArgumentDeclaration), - children: command.commands.map((child) => walkCommandTree(child)), + // Internal commands (e.g. the shell-completion helper `__complete`) use a + // `__` prefix and are omitted from the human-facing command tree. + children: command.commands + .filter((child) => !child.name().startsWith('__')) + .map((child) => walkCommandTree(child)), }; } diff --git a/packages/cli/src/commands/completion-commands.ts b/packages/cli/src/commands/completion-commands.ts new file mode 100644 index 00000000..332f103b --- /dev/null +++ b/packages/cli/src/commands/completion-commands.ts @@ -0,0 +1,44 @@ +import { Argument, type Command } from '@commander-js/extra-typings'; +import type { KtxCliCommandContext } from '../cli-program.js'; +import { computeCompletions } from '../completion/complete-engine.js'; +import { completionScript } from '../completion/completion-scripts.js'; +import { createProjectCompletionProviders } from '../completion/dynamic-candidates.js'; +import { profileMark } from '../startup-profile.js'; + +profileMark('module:commands/completion-commands'); + +export function registerCompletionCommands(program: Command, context: KtxCliCommandContext): void { + program + .command('completion') + .description('Print a shell completion script for ktx') + .addArgument(new Argument('', 'Target shell').choices(['zsh', 'bash'])) + .addHelpText( + 'after', + '\nEnable completion by adding the matching line to your shell startup file:\n' + + ' zsh: eval "$(ktx completion zsh)"\n' + + ' bash: eval "$(ktx completion bash)"\n', + ) + .action((shell) => { + context.io.stdout.write(completionScript(shell)); + }); + + // Hidden command invoked by the generated shell scripts. It must only ever + // print newline-separated candidates to stdout and exit 0, so a TAB press is + // never disrupted by an error, a telemetry notice, or a parse failure. + program + .command('__complete', { hidden: true }) + .argument('[words...]') + .allowUnknownOption(true) + .helpOption(false) + .action(async (words: string[]) => { + try { + const candidates = await computeCompletions(program, words, createProjectCompletionProviders()); + if (candidates.length > 0) { + context.io.stdout.write(`${candidates.join('\n')}\n`); + } + } catch { + // Swallow: completion must never break the shell. + } + context.setExitCode(0); + }); +} diff --git a/packages/cli/src/commands/knowledge-commands.ts b/packages/cli/src/commands/knowledge-commands.ts index c7b7c8d7..b601b688 100644 --- a/packages/cli/src/commands/knowledge-commands.ts +++ b/packages/cli/src/commands/knowledge-commands.ts @@ -21,9 +21,9 @@ function isDebugEnabled(command: CommandWithGlobalOptions): boolean { } export function registerWikiCommands(program: Command, context: KtxCliCommandContext): void { - program + const wiki = program .command('wiki') - .description('List or search local wiki pages') + .description('List, search, or read local wiki pages') .usage('[options] [query...]') .argument('[query...]', 'Search query; omit to list all pages') .option('--user-id ', 'Local user id', 'local') @@ -76,4 +76,18 @@ export function registerWikiCommands(program: Command, context: KtxCliCommandCon }); }, ); + + wiki + .command('read') + .description('Read a wiki page file by key') + .argument('', 'Wiki page key') + .action(async (key: string, _options, command) => { + const parentOpts = command.parent?.opts() as { userId?: string } | undefined; + await runKnowledgeArgs(context, { + command: 'read', + projectDir: resolveCommandProjectDir(command), + key, + userId: parentOpts?.userId ?? 'local', + }); + }); } diff --git a/packages/cli/src/commands/sl-commands.ts b/packages/cli/src/commands/sl-commands.ts index a4cb644c..8f2f05a3 100644 --- a/packages/cli/src/commands/sl-commands.ts +++ b/packages/cli/src/commands/sl-commands.ts @@ -94,19 +94,28 @@ export function registerSlCommands(program: Command, context: KtxCliCommandConte }, ); - sl.command('validate') - .description('Validate a semantic-layer source (set --connection-id on `ktx sl`)') + sl.command('read') + .description('Read a semantic-layer source YAML file') + .argument('', 'Semantic-layer source name') + .action(async (sourceName: string, _options, command) => { + const parentOpts = command.parent?.opts() as { connectionId?: string } | undefined; + await runSlArgs(context, { + command: 'read', + projectDir: resolveCommandProjectDir(command), + connectionId: parentOpts?.connectionId, + sourceName, + }); + }); + + sl.command('validate') + .description('Validate a semantic-layer source') .argument('', 'Semantic-layer source name') .action(async (sourceName: string, _options, command) => { const parentOpts = command.parent?.opts() as { connectionId?: string } | undefined; - const connectionId = parentOpts?.connectionId; - if (connectionId === undefined) { - command.error("error: required option '--connection-id ' not specified"); - } await runSlArgs(context, { command: 'validate', projectDir: resolveCommandProjectDir(command), - connectionId: connectionId as string, + connectionId: parentOpts?.connectionId, sourceName, }); }); @@ -131,10 +140,14 @@ export function registerSlCommands(program: Command, context: KtxCliCommandConte throw new Error('sl query requires at least one --measure'); } const parentOpts = command.parent?.opts() as { connectionId?: string } | undefined; + const connectionId = parentOpts?.connectionId; + if (connectionId === undefined) { + command.error("error: required option '--connection-id ' not specified"); + } const args = slQueryCommandSchema.parse({ command: 'query', projectDir: resolveCommandProjectDir(command), - connectionId: parentOpts?.connectionId, + connectionId, ...(options.queryFile ? { queryFile: options.queryFile } : { diff --git a/packages/cli/src/completion/complete-engine.ts b/packages/cli/src/completion/complete-engine.ts new file mode 100644 index 00000000..7268d397 --- /dev/null +++ b/packages/cli/src/completion/complete-engine.ts @@ -0,0 +1,172 @@ +import type { CommandUnknownOpts, Option } from '@commander-js/extra-typings'; + +/** + * Dynamic completion candidates that depend on project state (semantic-layer + * source names, wiki page keys, connection ids). Injected so the engine stays + * pure and unit-testable without touching the filesystem. + */ +export interface CompletionProviders { + /** Candidate operands for a positional argument of the active command path. */ + positionalCandidates(commandPath: string[], typedTokens: string[]): Promise; + /** Candidate values for an option that has no static `choices` (e.g. `--connection-id`). */ + optionValueCandidates(commandPath: string[], optionFlag: string, typedTokens: string[]): Promise; +} + +interface ResolvedCommand { + command: CommandUnknownOpts; + /** Subcommand names from the root down to the active command (root name excluded). */ + commandPath: string[]; +} + +function isHiddenCommand(command: CommandUnknownOpts): boolean { + // Completion mirrors `ktx --help`: commands registered with `{ hidden: true }` + // (the `__complete` helper and `mcp serve-internal`) are internal and must not + // surface. Commander exposes this only through the private `_hidden` field its + // own help renderer reads, so a name heuristic like a `__` prefix is not enough. + return (command as { _hidden?: boolean })._hidden === true; +} + +function resolveCommand(program: CommandUnknownOpts, typedTokens: string[]): ResolvedCommand { + let command: CommandUnknownOpts = program; + const commandPath: string[] = []; + for (let index = 0; index < typedTokens.length; index += 1) { + const token = typedTokens[index]; + if (token.startsWith('-')) { + // A value-taking option in the `--flag value` form consumes the next token + // as its value, so skip that value before matching subcommands. Otherwise a + // connection id like `query` would be resolved as the `sl query` subcommand + // instead of being treated as the `--connection-id` value. The `--flag=value` + // form carries its own value and consumes nothing extra. + if (!token.includes('=')) { + const option = findOption(command, token); + if (option && !option.isBoolean()) { + index += 1; + } + } + continue; + } + const sub = command.commands.find((candidate) => candidate.name() === token || candidate.aliases().includes(token)); + if (sub) { + command = sub; + commandPath.push(sub.name()); + } + } + return { command, commandPath }; +} + +function collectOptions(command: CommandUnknownOpts): Option[] { + const options: Option[] = []; + let current: CommandUnknownOpts | null = command; + while (current) { + options.push(...current.options); + current = current.parent; + } + return options; +} + +function findOption(command: CommandUnknownOpts, flag: string): Option | undefined { + return collectOptions(command).find((option) => option.long === flag || option.short === flag); +} + +function isRepeatableOption(option: Option): boolean { + // Variadic options, and options backed by a collector with an array default + // (e.g. `--measure`/`--dimension`), may be supplied more than once. + return option.variadic || Array.isArray(option.defaultValue); +} + +function flagCandidates(command: CommandUnknownOpts, typedTokens: string[]): string[] { + const present = new Set(typedTokens.filter((token) => token.startsWith('-'))); + const candidates: string[] = []; + for (const option of collectOptions(command)) { + if (option.hidden || !option.long) { + continue; + } + if (present.has(option.long) && !isRepeatableOption(option)) { + continue; + } + candidates.push(option.long); + } + return candidates; +} + +async function optionValueCandidates( + resolved: ResolvedCommand, + option: Option, + typedTokens: string[], + providers: CompletionProviders, +): Promise { + if (option.argChoices && option.argChoices.length > 0) { + return option.argChoices; + } + return providers.optionValueCandidates(resolved.commandPath, option.long ?? option.name(), typedTokens); +} + +function dedupeSortFilter(candidates: string[], partial: string): string[] { + const seen = new Set(); + const matches: string[] = []; + for (const candidate of candidates) { + if (!candidate.startsWith(partial) || seen.has(candidate)) { + continue; + } + seen.add(candidate); + matches.push(candidate); + } + return matches.sort(); +} + +/** + * Compute completion candidates for the partial last element of `words` + * (everything the shell has on the line after `ktx`). The active command and + * its flags are derived by walking the live Commander tree, so completion never + * drifts from the real command structure. + */ +export async function computeCompletions( + program: CommandUnknownOpts, + words: string[], + providers: CompletionProviders, +): Promise { + const partial = words.length > 0 ? (words[words.length - 1] ?? '') : ''; + const typedTokens = words.slice(0, -1); + const resolved = resolveCommand(program, typedTokens); + + // (a) Option value via the `--opt=value` form. + const equalsMatch = /^(--[^=]+)=(.*)$/.exec(partial); + if (equalsMatch) { + const [, flag, valuePartial] = equalsMatch; + const option = findOption(resolved.command, flag); + if (!option || option.isBoolean()) { + return []; + } + const values = await optionValueCandidates(resolved, option, typedTokens, providers); + return dedupeSortFilter( + values.map((value) => `${flag}=${value}`), + `${flag}=${valuePartial}`, + ); + } + + // (b) Option value via the `--opt value` form (previous token is a value-taking option). + const previous = typedTokens[typedTokens.length - 1]; + if (previous && previous.startsWith('-') && !partial.startsWith('-')) { + const option = findOption(resolved.command, previous); + if (option && !option.isBoolean()) { + return dedupeSortFilter(await optionValueCandidates(resolved, option, typedTokens, providers), partial); + } + } + + // (c) Flag completion. + if (partial.startsWith('-')) { + return dedupeSortFilter(flagCandidates(resolved.command, typedTokens), partial); + } + + // (d) Positional: subcommand names union static argument choices union dynamic operand candidates. + const candidates: string[] = resolved.command.commands + .filter((sub) => !isHiddenCommand(sub)) + .map((sub) => sub.name()); + for (const argument of resolved.command.registeredArguments) { + if (argument.argChoices) { + candidates.push(...argument.argChoices); + } + } + candidates.push(...(await providers.positionalCandidates(resolved.commandPath, typedTokens))); + return dedupeSortFilter(candidates, partial); +} diff --git a/packages/cli/src/completion/completion-scripts.ts b/packages/cli/src/completion/completion-scripts.ts new file mode 100644 index 00000000..5761c6e0 --- /dev/null +++ b/packages/cli/src/completion/completion-scripts.ts @@ -0,0 +1,39 @@ +// Static shell completion scripts emitted by `ktx completion `. +// +// Both scripts gather the words on the current command line (excluding the +// leading `ktx`), append the partial word under the cursor, and delegate to the +// hidden `ktx __complete` command, which prints newline-separated candidates. +// All command/flag/entity knowledge lives in `ktx __complete` so these scripts +// never have to encode the command tree. +// +// Lines are single-quoted JS strings so the shell `${...}` expansions are +// emitted verbatim (a template literal would try to interpolate them). + +const ZSH_SCRIPT = [ + '#compdef ktx', + '_ktx() {', + ' local -a candidates', + ' local out', + ' out="$(ktx __complete -- "${words[@]:1:$((CURRENT-1))}" 2>/dev/null)" || return 0', + ' candidates=("${(@f)out}")', + ' compadd -- $candidates', + '}', + 'compdef _ktx ktx', + '', +].join('\n'); + +const BASH_SCRIPT = [ + '_ktx() {', + ' local cur out', + ' cur="${COMP_WORDS[COMP_CWORD]}"', + ' out="$(ktx __complete -- "${COMP_WORDS[@]:1:COMP_CWORD}" 2>/dev/null)" || { COMPREPLY=(); return 0; }', + " local IFS=$'\\n'", + ' COMPREPLY=($(compgen -W "${out}" -- "$cur"))', + '}', + 'complete -F _ktx ktx', + '', +].join('\n'); + +export function completionScript(shell: 'zsh' | 'bash'): string { + return shell === 'zsh' ? ZSH_SCRIPT : BASH_SCRIPT; +} diff --git a/packages/cli/src/completion/dynamic-candidates.ts b/packages/cli/src/completion/dynamic-candidates.ts new file mode 100644 index 00000000..2be512c9 --- /dev/null +++ b/packages/cli/src/completion/dynamic-candidates.ts @@ -0,0 +1,103 @@ +import { existsSync } from 'node:fs'; +import { join } from 'node:path'; +import type { KtxLocalProject } from '../context/project/project.js'; +import { resolveKtxProjectDir } from '../project-resolver.js'; +import type { CompletionProviders } from './complete-engine.js'; + +/** Extract an option value from already-typed tokens (`--flag value` or `--flag=value`). */ +function extractOptionValue(tokens: string[], flag: string): string | undefined { + const prefix = `${flag}=`; + for (let index = 0; index < tokens.length; index += 1) { + const token = tokens[index]; + if (token === flag) { + const next = tokens[index + 1]; + if (next !== undefined && !next.startsWith('-')) { + return next; + } + } else if (token.startsWith(prefix)) { + return token.slice(prefix.length); + } + } + return undefined; +} + +/** + * Resolve and load the project the user is completing against. Honors a + * `--project-dir` typed on the line, then `KTX_PROJECT_DIR`, then the nearest + * `ktx.yaml`. Returns null (no completions) when there is no project, without + * creating any files. + */ +async function loadCompletionProject(typedTokens: string[]): Promise { + const explicitProjectDir = extractOptionValue(typedTokens, '--project-dir'); + const projectDir = resolveKtxProjectDir(explicitProjectDir !== undefined ? { explicitProjectDir } : {}); + if (!existsSync(join(projectDir, 'ktx.yaml'))) { + return null; + } + const { loadKtxProject } = await import('../context/project/project.js'); + return loadKtxProject({ projectDir }); +} + +async function sourceNames(typedTokens: string[]): Promise { + const project = await loadCompletionProject(typedTokens); + if (!project) { + return []; + } + const connectionId = extractOptionValue(typedTokens, '--connection-id'); + const { listLocalSlSources } = await import('../context/sl/local-sl.js'); + const summaries = await listLocalSlSources(project, connectionId !== undefined ? { connectionId } : {}); + return [...new Set(summaries.map((summary) => summary.name))]; +} + +async function wikiPageKeys(typedTokens: string[]): Promise { + const project = await loadCompletionProject(typedTokens); + if (!project) { + return []; + } + const userId = extractOptionValue(typedTokens, '--user-id'); + const { listLocalKnowledgePageKeys } = await import('../context/wiki/local-knowledge.js'); + return listLocalKnowledgePageKeys(project, userId !== undefined ? { userId } : {}); +} + +async function connectionIds(typedTokens: string[]): Promise { + const project = await loadCompletionProject(typedTokens); + if (!project) { + return []; + } + return Object.keys(project.config.connections).sort(); +} + +/** + * Project-backed completion providers. Every entry swallows its own errors so a + * failed lookup never breaks the shell — completion degrades to commands/flags. + */ +export function createProjectCompletionProviders(): CompletionProviders { + return { + async positionalCandidates(commandPath, typedTokens) { + try { + const key = commandPath.join(' '); + if (key === 'sl read' || key === 'sl validate') { + return await sourceNames(typedTokens); + } + if (key === 'wiki read') { + return await wikiPageKeys(typedTokens); + } + if (key === 'connection test' || key === 'ingest') { + return await connectionIds(typedTokens); + } + return []; + } catch { + return []; + } + }, + async optionValueCandidates(_commandPath, optionFlag, typedTokens) { + try { + if (optionFlag === '--connection-id' || optionFlag === '--connection') { + return await connectionIds(typedTokens); + } + return []; + } catch { + return []; + } + }, + }; +} diff --git a/packages/cli/src/context/sl/local-sl.ts b/packages/cli/src/context/sl/local-sl.ts index 243ba94d..fb573392 100644 --- a/packages/cli/src/context/sl/local-sl.ts +++ b/packages/cli/src/context/sl/local-sl.ts @@ -50,6 +50,7 @@ export interface LocalSlSearchInput { pglite?: PgliteSlSearchPrototypeOwnerOptions; } +/** @internal */ export interface LocalSlSource extends LocalSlSourceSummary { yaml: string; } @@ -63,6 +64,11 @@ export interface LocalSlValidationResult { errors: string[]; } +export type ResolvedSlSource = + | { kind: 'found'; source: LocalSlSource } + | { kind: 'not-found' } + | { kind: 'ambiguous'; connectionIds: string[] }; + const LOCAL_AUTHOR = 'ktx'; const LOCAL_AUTHOR_EMAIL = 'ktx@example.com'; @@ -311,6 +317,7 @@ export async function writeLocalSlSource( ); } +/** @internal */ export async function readLocalSlSource( project: KtxLocalProject, input: { connectionId: string; sourceName: string }, @@ -331,6 +338,41 @@ export async function readLocalSlSource( } } +export async function resolveLocalSlSource( + project: KtxLocalProject, + input: { sourceName: string; connectionId?: string }, +): Promise { + if (input.connectionId !== undefined) { + const source = await readLocalSlSource(project, { + connectionId: input.connectionId, + sourceName: input.sourceName, + }); + return source ? { kind: 'found', source } : { kind: 'not-found' }; + } + + const summaries = await listLocalSlSources(project, {}); + const matches = summaries.filter((summary) => summary.name === input.sourceName); + if (matches.length === 0) { + return { kind: 'not-found' }; + } + if (matches.length > 1) { + return { + kind: 'ambiguous', + connectionIds: [...new Set(matches.map((match) => match.connectionId))].sort(), + }; + } + + const match = matches[0]; + if (match === undefined) { + return { kind: 'not-found' }; + } + const source = await readLocalSlSource(project, { + connectionId: match.connectionId, + sourceName: input.sourceName, + }); + return source ? { kind: 'found', source } : { kind: 'not-found' }; +} + export async function listLocalSlSources( project: KtxLocalProject, input: { connectionId?: string } = {}, diff --git a/packages/cli/src/context/wiki/local-knowledge.ts b/packages/cli/src/context/wiki/local-knowledge.ts index b7132b50..dd9b9ad7 100644 --- a/packages/cli/src/context/wiki/local-knowledge.ts +++ b/packages/cli/src/context/wiki/local-knowledge.ts @@ -201,6 +201,32 @@ export async function listLocalKnowledgePages( return pages.sort((left, right) => left.path.localeCompare(right.path)); } +/** + * List wiki page keys without reading or parsing file contents. + * + * Keys are derived purely from file paths, so this stays cheap enough for + * shell tab-completion (unlike `listLocalKnowledgePages`, which reads every + * page to populate summaries). + */ +export async function listLocalKnowledgePageKeys( + project: KtxLocalProject, + input: { userId?: string } = {}, +): Promise { + const userId = input.userId ?? 'local'; + const keys = new Set(); + for (const scope of ['GLOBAL', 'USER'] as const) { + const root = scope === 'GLOBAL' ? 'wiki/global' : `wiki/user/${assertSafePathToken('user id', userId)}`; + const listed = await project.fileStore.listFiles(root); + for (const path of listed.files.filter((file) => file.endsWith('.md'))) { + const key = keyFromKnowledgePath(path, scope, userId); + if (key) { + keys.add(key); + } + } + } + return [...keys].sort(); +} + function scorePage(page: LocalKnowledgePage, terms: string[]): number { const haystack = buildKnowledgeSearchText(page.key, page.summary, page.content, page.tags).toLowerCase(); return terms.some((term) => haystack.includes(term)) ? 3 : 0; diff --git a/packages/cli/src/knowledge.ts b/packages/cli/src/knowledge.ts index d6246fef..346d3d9a 100644 --- a/packages/cli/src/knowledge.ts +++ b/packages/cli/src/knowledge.ts @@ -1,7 +1,13 @@ import { KtxIngestEmbeddingPortAdapter } from './context/llm/embedding-port.js'; import type { KtxEmbeddingPort } from './context/core/embedding.js'; import { loadKtxProject } from './context/project/project.js'; -import { type LocalKnowledgeSearchResult, type LocalKnowledgeSummary, listLocalKnowledgePages, searchLocalKnowledgePages as defaultSearchLocalKnowledgePages } from './context/wiki/local-knowledge.js'; +import { + type LocalKnowledgeSearchResult, + type LocalKnowledgeSummary, + listLocalKnowledgePages, + readLocalKnowledgePage, + searchLocalKnowledgePages as defaultSearchLocalKnowledgePages, +} from './context/wiki/local-knowledge.js'; import { resolveProjectEmbeddingProvider, type EmbeddingProviderResolution, @@ -22,7 +28,8 @@ export type KtxKnowledgeArgs = limit?: number; debug?: boolean; cliVersion: string; - }; + } + | { command: 'read'; projectDir: string; key: string; userId: string }; type KtxKnowledgeIo = import('./cli-runtime.js').KtxCliIo; @@ -128,6 +135,15 @@ export async function runKtxKnowledge( }); return 0; } + if (args.command === 'read') { + const page = await readLocalKnowledgePage(project, { key: args.key, userId: args.userId }); + if (!page) { + throw new Error(`No wiki page found for key '${args.key}'`); + } + const raw = await project.fileStore.readFile(page.path); + io.stdout.write(raw.content); + return 0; + } if (args.command === 'search') { const embeddingService = await wikiSearchEmbeddingService(project, deps, { cliVersion: args.cliVersion }, io); const search = deps.searchLocalKnowledgePages ?? defaultSearchLocalKnowledgePages; diff --git a/packages/cli/src/sl.ts b/packages/cli/src/sl.ts index 76e1092a..f3eeb33e 100644 --- a/packages/cli/src/sl.ts +++ b/packages/cli/src/sl.ts @@ -7,7 +7,14 @@ import type { KtxEmbeddingPort } from './context/core/embedding.js'; import type { KtxSemanticLayerComputePort } from './context/daemon/semantic-layer-compute.js'; import { loadKtxProject, type KtxLocalProject } from './context/project/project.js'; import { compileLocalSlQuery } from './context/sl/local-query.js'; -import { listLocalSlSources, readLocalSlSource, searchLocalSlSources as defaultSearchLocalSlSources, validateLocalSlSource, type LocalSlSourceSearchResult, type LocalSlSourceSummary } from './context/sl/local-sl.js'; +import { + listLocalSlSources, + resolveLocalSlSource, + searchLocalSlSources as defaultSearchLocalSlSources, + validateLocalSlSource, + type LocalSlSourceSearchResult, + type LocalSlSourceSummary, +} from './context/sl/local-sl.js'; import type { SemanticLayerQueryInput } from './context/sl/types.js'; import { resolveProjectEmbeddingProvider, @@ -45,7 +52,8 @@ export type KtxSlArgs = json?: boolean; cliVersion: string; } - | { command: 'validate'; projectDir: string; connectionId: string; sourceName: string } + | { command: 'read'; projectDir: string; connectionId?: string; sourceName: string } + | { command: 'validate'; projectDir: string; connectionId?: string; sourceName: string } | { command: 'query'; projectDir: string; @@ -185,6 +193,12 @@ async function readSlQueryFile(path: string): Promise { return parsed as SemanticLayerQueryInput; } +function ambiguousSourceMessage(sourceName: string, connectionIds: readonly string[]): string { + return `Source '${sourceName}' exists in multiple connections: ${connectionIds.join( + ', ', + )}. Re-run with --connection-id .`; +} + export async function runKtxSl(args: KtxSlArgs, io: KtxSlIo = process, deps: KtxSlDeps = {}): Promise { const startedAt = performance.now(); let queryForTelemetry: SemanticLayerQueryInput | undefined; @@ -232,25 +246,50 @@ export async function runKtxSl(args: KtxSlArgs, io: KtxSlIo = process, deps: Ktx }); return 0; } - if (args.command === 'validate') { - const source = await readLocalSlSource(project, { + if (args.command === 'read') { + const resolved = await resolveLocalSlSource(project, { connectionId: args.connectionId, sourceName: args.sourceName, }); - if (!source) { - throw new Error(`Semantic-layer source "${args.connectionId}/${args.sourceName}" was not found`); + if (resolved.kind === 'not-found') { + throw new Error( + args.connectionId !== undefined + ? `No semantic-layer source '${args.sourceName}' for connection '${args.connectionId}'` + : `No semantic-layer source '${args.sourceName}'`, + ); } - const result = await validateLocalSlSource(source.yaml, { - project, + if (resolved.kind === 'ambiguous') { + throw new Error(ambiguousSourceMessage(args.sourceName, resolved.connectionIds)); + } + io.stdout.write(resolved.source.yaml); + return 0; + } + if (args.command === 'validate') { + const resolved = await resolveLocalSlSource(project, { connectionId: args.connectionId, sourceName: args.sourceName, }); + if (resolved.kind === 'not-found') { + throw new Error( + args.connectionId !== undefined + ? `Semantic-layer source "${args.connectionId}/${args.sourceName}" was not found` + : `Semantic-layer source "${args.sourceName}" was not found`, + ); + } + if (resolved.kind === 'ambiguous') { + throw new Error(ambiguousSourceMessage(args.sourceName, resolved.connectionIds)); + } + const result = await validateLocalSlSource(resolved.source.yaml, { + project, + connectionId: resolved.source.connectionId, + sourceName: args.sourceName, + }); await emitTelemetryEvent({ name: 'sl_validate_completed', projectDir: args.projectDir, io, fields: { - sourceCount: source ? 1 : 0, + sourceCount: 1, modelCount: 0, validationErrorCount: result.valid ? 0 : result.errors.length, outcome: result.valid ? 'ok' : 'error', @@ -263,7 +302,7 @@ export async function runKtxSl(args: KtxSlArgs, io: KtxSlIo = process, deps: Ktx } return 1; } - io.stdout.write(`Valid semantic-layer source: ${args.connectionId}/${args.sourceName}\n`); + io.stdout.write(`Valid semantic-layer source: ${resolved.source.connectionId}/${args.sourceName}\n`); return 0; } if (args.command === 'query') { diff --git a/packages/cli/test/cli-program-telemetry.test.ts b/packages/cli/test/cli-program-telemetry.test.ts index 8088e7f2..4e7130b3 100644 --- a/packages/cli/test/cli-program-telemetry.test.ts +++ b/packages/cli/test/cli-program-telemetry.test.ts @@ -5,6 +5,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { runCommanderKtxCli } from '../src/cli-program.js'; import type { KtxCliDeps, KtxCliIo, KtxCliPackageInfo } from '../src/cli-runtime.js'; +import { TELEMETRY_NOTICE } from '../src/telemetry/identity.js'; function makeIo(stdoutIsTTY = true): { io: KtxCliIo; stdout: () => string; stderr: () => string } { let stdout = ''; @@ -85,7 +86,7 @@ describe('runCommanderKtxCli telemetry', () => { expect(statusIo.stderr()).toContain('"connectionCount"'); expect(statusIo.stderr()).not.toContain(tempDir); - const noticeIndex = statusIo.stderr().indexOf('ktx collects anonymous usage data'); + const noticeIndex = statusIo.stderr().indexOf(TELEMETRY_NOTICE); const firstTelemetryIndex = statusIo.stderr().indexOf('[telemetry]'); expect(noticeIndex).toBeGreaterThanOrEqual(0); expect(firstTelemetryIndex).toBeGreaterThan(noticeIndex); diff --git a/packages/cli/test/commands/wiki-sl-read-commands.test.ts b/packages/cli/test/commands/wiki-sl-read-commands.test.ts new file mode 100644 index 00000000..69e3c51a --- /dev/null +++ b/packages/cli/test/commands/wiki-sl-read-commands.test.ts @@ -0,0 +1,157 @@ +import { Command } from '@commander-js/extra-typings'; +import { describe, expect, it, vi } from 'vitest'; +import type { KtxCliCommandContext } from '../../src/cli-program.js'; +import { registerWikiCommands } from '../../src/commands/knowledge-commands.js'; +import { registerSlCommands } from '../../src/commands/sl-commands.js'; + +function makeContext(overrides: Partial = {}): KtxCliCommandContext { + let exitCode = 0; + return { + io: { + stdout: { write: vi.fn() }, + stderr: { write: vi.fn() }, + }, + deps: {}, + packageInfo: { name: '@kaelio/ktx', version: '0.0.0-test' }, + setExitCode: (code) => { + exitCode = code; + }, + runInit: vi.fn(), + writeDebug: vi.fn(), + ...overrides, + get exitCode() { + return exitCode; + }, + } as KtxCliCommandContext; +} + +describe('wiki and sl read command routing', () => { + it('routes wiki read through the knowledge runner', async () => { + const program = new Command().exitOverride().option('--project-dir '); + const knowledge = vi.fn(async () => 0); + const context = makeContext({ deps: { knowledge } }); + registerWikiCommands(program, context); + + await expect( + program.parseAsync(['--project-dir', '/tmp/ktx-project', 'wiki', 'read', 'metrics-revenue'], { + from: 'user', + }), + ).resolves.toBe(program); + + expect(knowledge).toHaveBeenCalledWith( + { + command: 'read', + projectDir: '/tmp/ktx-project', + key: 'metrics-revenue', + userId: 'local', + }, + context.io, + ); + }); + + it('routes wiki read with the parent --user-id option', async () => { + const program = new Command().exitOverride().option('--project-dir '); + const knowledge = vi.fn(async () => 0); + const context = makeContext({ deps: { knowledge } }); + registerWikiCommands(program, context); + + await expect( + program.parseAsync( + ['--project-dir', '/tmp/ktx-project', 'wiki', '--user-id', 'alex', 'read', 'handoff'], + { from: 'user' }, + ), + ).resolves.toBe(program); + + expect(knowledge).toHaveBeenCalledWith( + { + command: 'read', + projectDir: '/tmp/ktx-project', + key: 'handoff', + userId: 'alex', + }, + context.io, + ); + }); + + it('routes sl read through the semantic-layer runner', async () => { + const program = new Command().exitOverride().option('--project-dir '); + const sl = vi.fn(async () => 0); + const context = makeContext({ deps: { sl } }); + registerSlCommands(program, context); + + await expect( + program.parseAsync( + ['--project-dir', '/tmp/ktx-project', 'sl', '--connection-id', 'warehouse', 'read', 'orders'], + { from: 'user' }, + ), + ).resolves.toBe(program); + + expect(sl).toHaveBeenCalledWith( + { + command: 'read', + projectDir: '/tmp/ktx-project', + connectionId: 'warehouse', + sourceName: 'orders', + }, + context.io, + ); + }); + + it('routes sl read without --connection-id through the semantic-layer runner', async () => { + const program = new Command().exitOverride().option('--project-dir '); + const sl = vi.fn(async () => 0); + const context = makeContext({ deps: { sl } }); + registerSlCommands(program, context); + + await expect( + program.parseAsync(['--project-dir', '/tmp/ktx-project', 'sl', 'read', 'orders'], { from: 'user' }), + ).resolves.toBe(program); + + expect(sl).toHaveBeenCalledWith( + { + command: 'read', + projectDir: '/tmp/ktx-project', + connectionId: undefined, + sourceName: 'orders', + }, + context.io, + ); + }); + + it('routes sl validate without --connection-id through the semantic-layer runner', async () => { + const program = new Command().exitOverride().option('--project-dir '); + const sl = vi.fn(async () => 0); + const context = makeContext({ deps: { sl } }); + registerSlCommands(program, context); + + await expect( + program.parseAsync(['--project-dir', '/tmp/ktx-project', 'sl', 'validate', 'orders'], { from: 'user' }), + ).resolves.toBe(program); + + expect(sl).toHaveBeenCalledWith( + { + command: 'validate', + projectDir: '/tmp/ktx-project', + connectionId: undefined, + sourceName: 'orders', + }, + context.io, + ); + }); + + it('keeps sl query requiring --connection-id before invoking the runner', async () => { + const program = new Command().exitOverride().option('--project-dir '); + const sl = vi.fn(async () => 0); + const context = makeContext({ deps: { sl } }); + registerSlCommands(program, context); + + await expect( + program.parseAsync( + ['--project-dir', '/tmp/ktx-project', 'sl', 'query', '--measure', 'orders.count'], + { from: 'user' }, + ), + ).rejects.toThrow("error: required option '--connection-id ' not specified"); + + expect(sl).not.toHaveBeenCalled(); + }); +}); diff --git a/packages/cli/test/completion/complete-engine.test.ts b/packages/cli/test/completion/complete-engine.test.ts new file mode 100644 index 00000000..f3893340 --- /dev/null +++ b/packages/cli/test/completion/complete-engine.test.ts @@ -0,0 +1,137 @@ +import type { Command } from '@commander-js/extra-typings'; +import { describe, expect, it } from 'vitest'; +import { buildKtxProgram } from '../../src/cli-program.js'; +import type { KtxCliIo, KtxCliPackageInfo } from '../../src/cli-runtime.js'; +import { type CompletionProviders, computeCompletions } from '../../src/completion/complete-engine.js'; + +function stubIo(): KtxCliIo { + return { stdout: { isTTY: false, columns: 80, write: () => {} }, stderr: { write: () => {} } }; +} + +function stubPackageInfo(): KtxCliPackageInfo { + return { name: '@kaelio/ktx', version: '0.0.0-test' }; +} + +function buildProgram(): Command { + return buildKtxProgram({ io: stubIo(), deps: {}, packageInfo: stubPackageInfo(), runInit: async () => 0 }); +} + +const SOURCES = ['orders', 'customers']; +const WIKI_KEYS = ['revenue', 'churn']; +const CONNECTIONS = ['warehouse']; + +function fakeProviders(overrides: Partial = {}): CompletionProviders { + return { + async positionalCandidates(commandPath) { + const key = commandPath.join(' '); + if (key === 'sl read' || key === 'sl validate') { + return SOURCES; + } + if (key === 'wiki read') { + return WIKI_KEYS; + } + return []; + }, + async optionValueCandidates(_commandPath, optionFlag) { + return optionFlag === '--connection-id' ? CONNECTIONS : []; + }, + ...overrides, + }; +} + +function complete(words: string[], providers: CompletionProviders = fakeProviders()): Promise { + return computeCompletions(buildProgram(), words, providers); +} + +describe('computeCompletions', () => { + it('lists top-level commands and hides internal ones', async () => { + const result = await complete(['']); + expect(result).toContain('sl'); + expect(result).toContain('wiki'); + expect(result).toContain('completion'); + expect(result).not.toContain('__complete'); + }); + + it('filters top-level commands by prefix', async () => { + expect(await complete(['co'])).toEqual(['completion', 'connection']); + }); + + it('hides Commander-hidden subcommands such as `mcp serve-internal`', async () => { + const result = await complete(['mcp', '']); + expect(result).not.toContain('serve-internal'); + expect(result).toEqual(['logs', 'start', 'status', 'stdio', 'stop']); + }); + + it('offers only sl subcommands at the bare sl positional', async () => { + expect(await complete(['sl', ''])).toEqual(['query', 'read', 'validate']); + }); + + it('offers source names for sl read and sl validate', async () => { + expect(await complete(['sl', 'read', ''])).toEqual(['customers', 'orders']); + expect(await complete(['sl', 'validate', ''])).toEqual(['customers', 'orders']); + }); + + it('offers only the wiki read subcommand at the bare wiki positional', async () => { + expect(await complete(['wiki', ''])).toEqual(['read']); + }); + + it('offers wiki page keys for wiki read', async () => { + expect(await complete(['wiki', 'read', ''])).toEqual(['churn', 'revenue']); + }); + + it('does not complete entity names for bare search positionals', async () => { + expect(await complete(['sl', 'o'])).toEqual([]); + expect(await complete(['wiki', 'r'])).toEqual(['read']); + }); + + it('completes flags (own + inherited globals) when the partial starts with a dash', async () => { + const result = await complete(['sl', '-']); + expect(result).toContain('--connection-id'); + expect(result).toContain('--output'); + expect(result).toContain('--json'); + expect(result).toContain('--debug'); + expect(result).toContain('--project-dir'); + }); + + it('completes option choices for the `--opt value` form', async () => { + expect(await complete(['sl', '--output', ''])).toEqual(['json', 'plain', 'pretty']); + }); + + it('completes option choices for the `--opt=value` form', async () => { + expect(await complete(['sl', '--output=pr'])).toEqual(['--output=pretty']); + }); + + it('completes option values from a provider for options without static choices', async () => { + expect(await complete(['sl', '--connection-id', ''])).toEqual(['warehouse']); + }); + + it('falls through to positional completion after a boolean flag', async () => { + const result = await complete(['sl', '--json', '']); + expect(result).toEqual(['query', 'read', 'validate']); + }); + + it('does not treat a value-taking option value as a subcommand', async () => { + // A connection id that happens to match a subcommand name (`query`, `read`) + // is the `--connection-id` value, not a subcommand: the next positional must + // still offer the `sl` subcommands rather than resolving into `sl query`/`sl read`. + expect(await complete(['sl', '--connection-id', 'query', ''])).toEqual(['query', 'read', 'validate']); + expect(await complete(['sl', '--connection-id', 'read', ''])).toEqual(['query', 'read', 'validate']); + }); + + it('still returns subcommands/flags when dynamic providers yield nothing (no project)', async () => { + const empty = fakeProviders({ + positionalCandidates: async () => [], + optionValueCandidates: async () => [], + }); + expect(await complete(['sl', ''], empty)).toEqual(['query', 'read', 'validate']); + expect(await complete(['-'], empty)).toContain('--debug'); + }); + + it('completes the completion command shell positional from its static choices', async () => { + expect(await complete(['completion', ''])).toEqual(['bash', 'zsh']); + }); + + it('filters positional argument choices by prefix', async () => { + expect(await complete(['completion', 'z'])).toEqual(['zsh']); + }); +}); diff --git a/packages/cli/test/completion/completion-scripts.test.ts b/packages/cli/test/completion/completion-scripts.test.ts new file mode 100644 index 00000000..24723a95 --- /dev/null +++ b/packages/cli/test/completion/completion-scripts.test.ts @@ -0,0 +1,20 @@ +import { describe, expect, it } from 'vitest'; +import { completionScript } from '../../src/completion/completion-scripts.js'; + +describe('completionScript', () => { + it('emits a zsh script that registers _ktx and delegates to ktx __complete', () => { + const script = completionScript('zsh'); + expect(script).toContain('#compdef ktx'); + expect(script).toContain('compdef _ktx ktx'); + expect(script).toContain('ktx __complete --'); + expect(script).toContain('compadd -- $candidates'); + }); + + it('emits a bash script that registers _ktx and preserves newline-split candidates', () => { + const script = completionScript('bash'); + expect(script).toContain('complete -F _ktx ktx'); + expect(script).toContain('ktx __complete --'); + expect(script).toContain("local IFS=$'\\n'"); + expect(script).toContain('COMPREPLY=($(compgen -W "${out}" -- "$cur"))'); + }); +}); diff --git a/packages/cli/test/completion/dynamic-candidates.test.ts b/packages/cli/test/completion/dynamic-candidates.test.ts new file mode 100644 index 00000000..560f38f0 --- /dev/null +++ b/packages/cli/test/completion/dynamic-candidates.test.ts @@ -0,0 +1,103 @@ +import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { createProjectCompletionProviders } from '../../src/completion/dynamic-candidates.js'; + +const KTX_YAML = ['connections:', ' warehouse:', ' driver: sqlite', ' analytics:', ' driver: sqlite', ''].join( + '\n', +); + +describe('createProjectCompletionProviders', () => { + let projectDir: string; + + beforeEach(async () => { + projectDir = await mkdtemp(join(tmpdir(), 'ktx-completion-')); + await writeFile(join(projectDir, 'ktx.yaml'), KTX_YAML, 'utf-8'); + }); + + afterEach(async () => { + await rm(projectDir, { recursive: true, force: true }); + }); + + async function seedProjectEntities(): Promise { + await mkdir(join(projectDir, 'semantic-layer', 'warehouse'), { recursive: true }); + await writeFile( + join(projectDir, 'semantic-layer', 'warehouse', 'orders.yaml'), + ['name: orders', 'table: public.orders', 'grain: [order_id]', 'columns: []', ''].join('\n'), + 'utf-8', + ); + await mkdir(join(projectDir, 'semantic-layer', 'analytics'), { recursive: true }); + await writeFile( + join(projectDir, 'semantic-layer', 'analytics', 'orders.yaml'), + ['name: orders', 'table: public.analytics_orders', 'grain: [order_id]', 'columns: []', ''].join('\n'), + 'utf-8', + ); + await writeFile( + join(projectDir, 'semantic-layer', 'analytics', 'tickets.yaml'), + ['name: tickets', 'table: public.tickets', 'grain: [ticket_id]', 'columns: []', ''].join('\n'), + 'utf-8', + ); + await mkdir(join(projectDir, 'wiki', 'global'), { recursive: true }); + await writeFile( + join(projectDir, 'wiki', 'global', 'revenue.md'), + ['---', 'summary: Revenue', 'tags: []', 'refs: []', 'sl_refs: []', '---', '', 'Revenue rules.', ''].join('\n'), + 'utf-8', + ); + } + + it('completes connection ids for the `connection test` positional', async () => { + const providers = createProjectCompletionProviders(); + const result = await providers.positionalCandidates(['connection', 'test'], ['--project-dir', projectDir]); + expect(result).toEqual(['analytics', 'warehouse']); + }); + + it('completes connection ids for the `ingest` positional', async () => { + const providers = createProjectCompletionProviders(); + const result = await providers.positionalCandidates(['ingest'], ['--project-dir', projectDir]); + expect(result).toEqual(['analytics', 'warehouse']); + }); + + it('completes entity names only for read and validate subcommands', async () => { + await seedProjectEntities(); + const providers = createProjectCompletionProviders(); + + await expect(providers.positionalCandidates(['sl'], ['--project-dir', projectDir])).resolves.toEqual([]); + await expect(providers.positionalCandidates(['sl', 'read'], ['--project-dir', projectDir])).resolves.toEqual([ + 'orders', + 'tickets', + ]); + await expect(providers.positionalCandidates(['sl', 'validate'], ['--project-dir', projectDir])).resolves.toEqual([ + 'orders', + 'tickets', + ]); + await expect( + providers.positionalCandidates(['sl', 'read'], ['--project-dir', projectDir, '--connection-id', 'warehouse']), + ).resolves.toEqual(['orders']); + await expect( + providers.positionalCandidates(['sl', 'validate'], ['--project-dir', projectDir, '--connection-id', 'analytics']), + ).resolves.toEqual(['orders', 'tickets']); + await expect(providers.positionalCandidates(['wiki'], ['--project-dir', projectDir])).resolves.toEqual([]); + await expect(providers.positionalCandidates(['wiki', 'read'], ['--project-dir', projectDir])).resolves.toEqual([ + 'revenue', + ]); + }); + + it('returns no positional candidates outside a project', async () => { + const providers = createProjectCompletionProviders(); + const result = await providers.positionalCandidates(['connection', 'test'], ['--project-dir', join(projectDir, 'nope')]); + expect(result).toEqual([]); + }); + + it('completes connection ids for the sql --connection option', async () => { + const providers = createProjectCompletionProviders(); + const result = await providers.optionValueCandidates(['sql'], '--connection', ['--project-dir', projectDir]); + expect(result).toEqual(['analytics', 'warehouse']); + }); + + it('still completes connection ids for the --connection-id option', async () => { + const providers = createProjectCompletionProviders(); + const result = await providers.optionValueCandidates(['ingest'], '--connection-id', ['--project-dir', projectDir]); + expect(result).toEqual(['analytics', 'warehouse']); + }); +}); diff --git a/packages/cli/test/context/sl/local-sl.test.ts b/packages/cli/test/context/sl/local-sl.test.ts index 1115f387..b3a9b7d6 100644 --- a/packages/cli/test/context/sl/local-sl.test.ts +++ b/packages/cli/test/context/sl/local-sl.test.ts @@ -6,6 +6,7 @@ import { initKtxProject, type KtxLocalProject } from '../../../src/context/proje import { listLocalSlSources, readLocalSlSource, + resolveLocalSlSource, searchLocalSlSources, validateLocalSlSource, writeLocalSlSource, @@ -90,6 +91,101 @@ describe('local semantic-layer helpers', () => { await expect(validateLocalSlSource(ORDERS_YAML)).resolves.toEqual({ valid: true, errors: [] }); }); + it('resolves a scoped source by connection id', async () => { + await writeLocalSlSource(project, { + connectionId: 'warehouse', + sourceName: 'orders', + yaml: ORDERS_YAML, + }); + + await expect( + resolveLocalSlSource(project, { + connectionId: 'warehouse', + sourceName: 'orders', + }), + ).resolves.toEqual({ + kind: 'found', + source: expect.objectContaining({ + connectionId: 'warehouse', + name: 'orders', + path: 'semantic-layer/warehouse/orders.yaml', + yaml: ORDERS_YAML, + }), + }); + }); + + it('returns not-found for a missing scoped source', async () => { + await writeLocalSlSource(project, { + connectionId: 'warehouse', + sourceName: 'orders', + yaml: ORDERS_YAML, + }); + + await expect( + resolveLocalSlSource(project, { + connectionId: 'warehouse', + sourceName: 'missing_orders', + }), + ).resolves.toEqual({ kind: 'not-found' }); + }); + + it('resolves a unique source name across all connections', async () => { + await writeLocalSlSource(project, { + connectionId: 'warehouse', + sourceName: 'orders', + yaml: ORDERS_YAML, + }); + await writeLocalSlSource(project, { + connectionId: 'analytics', + sourceName: 'tickets', + yaml: SUPPORT_YAML, + }); + + await expect( + resolveLocalSlSource(project, { + sourceName: 'tickets', + }), + ).resolves.toEqual({ + kind: 'found', + source: expect.objectContaining({ + connectionId: 'analytics', + name: 'tickets', + path: 'semantic-layer/analytics/tickets.yaml', + yaml: SUPPORT_YAML, + }), + }); + }); + + it('returns not-found for a missing unscoped source', async () => { + await writeLocalSlSource(project, { + connectionId: 'warehouse', + sourceName: 'orders', + yaml: ORDERS_YAML, + }); + + await expect(resolveLocalSlSource(project, { sourceName: 'missing_orders' })).resolves.toEqual({ + kind: 'not-found', + }); + }); + + it('reports sorted ambiguous connection ids for duplicate source names', async () => { + await writeLocalSlSource(project, { + connectionId: 'warehouse', + sourceName: 'orders', + yaml: ORDERS_YAML, + }); + await writeLocalSlSource(project, { + connectionId: 'analytics', + sourceName: 'orders', + yaml: ORDERS_YAML, + }); + + await expect(resolveLocalSlSource(project, { sourceName: 'orders' })).resolves.toEqual({ + kind: 'ambiguous', + connectionIds: ['analytics', 'warehouse'], + }); + }); + it('validates table-backed sources against matching physical manifests when project context is provided', async () => { await project.fileStore.writeFile( 'semantic-layer/postgres-warehouse/_schema/orbit_analytics.yaml', diff --git a/packages/cli/test/context/wiki/local-knowledge.test.ts b/packages/cli/test/context/wiki/local-knowledge.test.ts index fa70bcc5..cda5ca1a 100644 --- a/packages/cli/test/context/wiki/local-knowledge.test.ts +++ b/packages/cli/test/context/wiki/local-knowledge.test.ts @@ -4,6 +4,7 @@ import { join } from 'node:path'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { initKtxProject, type KtxLocalProject } from '../../../src/context/project/project.js'; import { + listLocalKnowledgePageKeys, listLocalKnowledgePages, readLocalKnowledgePage, searchLocalKnowledgePages, @@ -102,6 +103,35 @@ describe('local knowledge helpers', () => { await expect(access(join(project.projectDir, '.ktx', 'db.sqlite'))).resolves.toBeUndefined(); }); + it('lists page keys across scopes, deduped and sorted, for completion', async () => { + await writeLocalKnowledgePage(project, { + key: 'metrics-revenue', + scope: 'GLOBAL', + summary: 'Revenue metric definition', + content: 'Revenue is recognized when an order is paid.', + }); + await writeLocalKnowledgePage(project, { + key: 'metrics-churn', + scope: 'USER', + userId: 'local', + summary: 'Churn metric definition', + content: 'Churn is measured monthly.', + }); + // Same key in both scopes must collapse to a single completion candidate. + await writeLocalKnowledgePage(project, { + key: 'metrics-revenue', + scope: 'USER', + userId: 'local', + summary: 'User override of revenue', + content: 'Local revenue note.', + }); + + await expect(listLocalKnowledgePageKeys(project, { userId: 'local' })).resolves.toEqual([ + 'metrics-churn', + 'metrics-revenue', + ]); + }); + it('adds the token lane alongside lexical wiki matches', async () => { await writeLocalKnowledgePage(project, { key: 'metrics-revenue', diff --git a/packages/cli/test/index.test.ts b/packages/cli/test/index.test.ts index bd17e641..57ac4901 100644 --- a/packages/cli/test/index.test.ts +++ b/packages/cli/test/index.test.ts @@ -132,9 +132,12 @@ describe('runKtxCli', () => { } expect(testIo.stdout()).not.toMatch(/^ dev\s/m); expect(testIo.stdout()).not.toMatch(/^ scan\s/m); - for (const removed of ['demo', 'init', 'connect', 'ask', 'knowledge', 'agent', 'completion', 'serve']) { + for (const removed of ['demo', 'init', 'connect', 'ask', 'knowledge', 'agent', 'serve']) { expect(testIo.stdout()).not.toMatch(new RegExp(`^\\s+${removed}(?:\\s|\\[|$)`, 'm')); } + // `completion` is a public command; the internal `__complete` helper is hidden. + expect(testIo.stdout()).toMatch(/^\s+completion /m); + expect(testIo.stdout()).not.toContain('__complete'); expect(testIo.stdout()).toContain('--project-dir '); expect(testIo.stdout()).toContain('KTX_PROJECT_DIR'); expect(testIo.stdout()).toContain('--debug'); @@ -414,12 +417,17 @@ describe('runKtxCli', () => { const promptIo = makeIo(); await expect( - runKtxCli(['--project-dir', tempDir, 'sl', 'query', '--measure', 'orders.order_count'], promptIo.io, { sl }), + runKtxCli( + ['--project-dir', tempDir, 'sl', 'query', '--connection-id', 'warehouse', '--measure', 'orders.order_count'], + promptIo.io, + { sl }, + ), ).resolves.toBe(0); expect(sl).toHaveBeenLastCalledWith( expect.objectContaining({ command: 'query', projectDir: tempDir, + connectionId: 'warehouse', cliVersion, runtimeInstallPolicy: 'prompt', query: expect.objectContaining({ measures: ['orders.order_count'], dimensions: [] }), @@ -429,9 +437,21 @@ describe('runKtxCli', () => { const autoIo = makeIo(); await expect( - runKtxCli(['--project-dir', tempDir, 'sl', 'query', '--measure', 'orders.order_count', '--yes'], autoIo.io, { - sl, - }), + runKtxCli( + [ + '--project-dir', + tempDir, + 'sl', + 'query', + '--connection-id', + 'warehouse', + '--measure', + 'orders.order_count', + '--yes', + ], + autoIo.io, + { sl }, + ), ).resolves.toBe(0); expect(sl).toHaveBeenLastCalledWith( expect.objectContaining({ @@ -444,7 +464,17 @@ describe('runKtxCli', () => { const noInputIo = makeIo(); await expect( runKtxCli( - ['--project-dir', tempDir, 'sl', 'query', '--measure', 'orders.order_count', '--no-input'], + [ + '--project-dir', + tempDir, + 'sl', + 'query', + '--connection-id', + 'warehouse', + '--measure', + 'orders.order_count', + '--no-input', + ], noInputIo.io, { sl }, ), @@ -464,7 +494,18 @@ describe('runKtxCli', () => { await expect( runKtxCli( - ['--project-dir', tempDir, 'sl', 'query', '--measure', 'orders.order_count', '--yes', '--no-input'], + [ + '--project-dir', + tempDir, + 'sl', + 'query', + '--connection-id', + 'warehouse', + '--measure', + 'orders.order_count', + '--yes', + '--no-input', + ], io.io, { sl }, ), diff --git a/packages/cli/test/knowledge.test.ts b/packages/cli/test/knowledge.test.ts index 339eb659..94e4bb63 100644 --- a/packages/cli/test/knowledge.test.ts +++ b/packages/cli/test/knowledge.test.ts @@ -98,6 +98,46 @@ describe('runKtxKnowledge', () => { expect(searchIo.stdout()).toContain('metrics-revenue'); }); + it('reads a wiki page as raw markdown with frontmatter', async () => { + const projectDir = join(tempDir, 'read-project'); + await initKtxProject({ projectDir }); + await seedWikiPage(projectDir, { + key: 'metrics-revenue', + summary: 'Revenue', + content: 'Revenue is paid order value.', + tags: ['finance'], + slRefs: ['orders'], + }); + + const readIo = makeIo(); + await expect( + runKtxKnowledge({ command: 'read', projectDir, key: 'metrics-revenue', userId: 'local' }, readIo.io), + ).resolves.toBe(0); + + expect(readIo.stdout()).toContain('---\n'); + expect(readIo.stdout()).toContain('summary: Revenue'); + expect(readIo.stdout()).toContain('tags:'); + expect(readIo.stdout()).toContain('- finance'); + expect(readIo.stdout()).toContain('sl_refs:'); + expect(readIo.stdout()).toContain('- orders'); + expect(readIo.stdout()).toContain('usage_mode: auto'); + expect(readIo.stdout()).toContain('Revenue is paid order value.'); + expect(readIo.stderr()).toBe(''); + }); + + it('reports a clear error when a wiki page key is missing', async () => { + const projectDir = join(tempDir, 'missing-read-project'); + await initKtxProject({ projectDir }); + + const readIo = makeIo(); + await expect( + runKtxKnowledge({ command: 'read', projectDir, key: 'missing-page', userId: 'local' }, readIo.io), + ).resolves.toBe(1); + + expect(readIo.stdout()).toBe(''); + expect(readIo.stderr()).toBe("No wiki page found for key 'missing-page'\n"); + }); + it('emits debug telemetry for wiki search without query text', async () => { vi.stubEnv('KTX_TELEMETRY_DEBUG', '1'); vi.stubEnv('CI', ''); diff --git a/packages/cli/test/print-command-tree.test.ts b/packages/cli/test/print-command-tree.test.ts index 688818ab..387874b3 100644 --- a/packages/cli/test/print-command-tree.test.ts +++ b/packages/cli/test/print-command-tree.test.ts @@ -12,10 +12,14 @@ describe('renderKtxCommandTree', () => { .filter((line) => /^ {2}[├└]── \S/.test(line)) .map((line) => line.replace(/^ {2}[├└]── /, '').trim().split(' ')[0]); - for (const expected of ['setup', 'connection', 'ingest', 'sl', 'mcp', 'admin']) { + for (const expected of ['setup', 'connection', 'ingest', 'sl', 'mcp', 'admin', 'completion']) { expect(topLevel).toContain(expected); } + // The internal completion helper is hidden and must not appear in the tree. + expect(topLevel).not.toContain('__complete'); + expect(output).not.toContain('__complete'); + expect(output).toContain('│ └── test [connectionId]'); expect(output).toContain('│ ├── status Show KTX MCP daemon status'); expect(output).not.toContain('│ ├── add'); @@ -27,10 +31,14 @@ describe('renderKtxCommandTree', () => { expect(output).not.toContain('scan '); expect(output).not.toContain('│ ├── replay'); expect(output).not.toContain('│ └── replay'); - expect(output).not.toContain('│ ├── run'); + // Match `run` as a whole command name, not the `run` prefix of `runtime`. + expect(output).not.toMatch(/[├└]── run(\s|$)/m); expect(output).not.toContain('│ ├── watch'); expect(output).not.toContain('│ └── watch'); - expect(output).not.toContain('│ ├── read'); + expect(output).toContain('│ └── read Read a wiki page file by key'); + expect(output).toContain( + '│ ├── read Read a semantic-layer source YAML file', + ); expect(output).not.toContain('│ ├── write'); expect(output).not.toContain('│ └── write'); }); diff --git a/packages/cli/test/sl.test.ts b/packages/cli/test/sl.test.ts index 7b4b7795..ff9c1489 100644 --- a/packages/cli/test/sl.test.ts +++ b/packages/cli/test/sl.test.ts @@ -113,6 +113,267 @@ describe('runKtxSl', () => { }); }); + it('reads a semantic-layer source as raw YAML', async () => { + const projectDir = join(tempDir, 'read-project'); + await seedSlSource({ projectDir }); + + const readIo = makeIo(); + await expect( + runKtxSl( + { + command: 'read', + projectDir, + connectionId: 'warehouse', + sourceName: 'orders', + }, + readIo.io, + ), + ).resolves.toBe(0); + + expect(readIo.stdout()).toBe(ORDERS_YAML); + expect(readIo.stderr()).toBe(''); + }); + + it('reads a unique semantic-layer source without a connection id', async () => { + const projectDir = join(tempDir, 'read-unique-project'); + const project = await initKtxProject({ projectDir }); + await project.fileStore.writeFile( + 'semantic-layer/warehouse/orders.yaml', + ORDERS_YAML, + 'ktx', + 'ktx@example.com', + 'Add semantic-layer source', + ); + await project.fileStore.writeFile( + 'semantic-layer/analytics/tickets.yaml', + [ + 'name: tickets', + 'table: public.tickets', + 'grain:', + ' - ticket_id', + 'columns:', + ' - name: ticket_id', + ' type: string', + '', + ].join('\n'), + 'ktx', + 'ktx@example.com', + 'Add semantic-layer source', + ); + + const readIo = makeIo(); + await expect( + runKtxSl( + { + command: 'read', + projectDir, + sourceName: 'tickets', + }, + readIo.io, + ), + ).resolves.toBe(0); + + expect(readIo.stdout()).toContain('name: tickets'); + expect(readIo.stderr()).toBe(''); + }); + + it('reports ambiguous unscoped reads with sorted connection ids', async () => { + const projectDir = join(tempDir, 'read-ambiguous-project'); + const project = await initKtxProject({ projectDir }); + await project.fileStore.writeFile( + 'semantic-layer/warehouse/orders.yaml', + ORDERS_YAML, + 'ktx', + 'ktx@example.com', + 'Add semantic-layer source', + ); + await project.fileStore.writeFile( + 'semantic-layer/analytics/orders.yaml', + ORDERS_YAML, + 'ktx', + 'ktx@example.com', + 'Add semantic-layer source', + ); + + const readIo = makeIo(); + await expect( + runKtxSl( + { + command: 'read', + projectDir, + sourceName: 'orders', + }, + readIo.io, + ), + ).resolves.toBe(1); + + expect(readIo.stdout()).toBe(''); + expect(readIo.stderr()).toBe( + "Source 'orders' exists in multiple connections: analytics, warehouse. Re-run with --connection-id .\n", + ); + }); + + it('reports a clear error when an unscoped semantic-layer source is missing', async () => { + const projectDir = join(tempDir, 'missing-unscoped-read-project'); + await seedSlSource({ projectDir }); + + const readIo = makeIo(); + await expect( + runKtxSl( + { + command: 'read', + projectDir, + sourceName: 'missing_orders', + }, + readIo.io, + ), + ).resolves.toBe(1); + + expect(readIo.stdout()).toBe(''); + expect(readIo.stderr()).toBe("No semantic-layer source 'missing_orders'\n"); + }); + + it('reports a clear error when a semantic-layer source is missing', async () => { + const projectDir = join(tempDir, 'missing-read-project'); + await seedSlSource({ projectDir }); + + const readIo = makeIo(); + await expect( + runKtxSl( + { + command: 'read', + projectDir, + connectionId: 'warehouse', + sourceName: 'missing_orders', + }, + readIo.io, + ), + ).resolves.toBe(1); + + expect(readIo.stdout()).toBe(''); + expect(readIo.stderr()).toBe("No semantic-layer source 'missing_orders' for connection 'warehouse'\n"); + }); + + it('validates a unique semantic-layer source without a connection id', async () => { + const projectDir = join(tempDir, 'validate-unique-project'); + const project = await initKtxProject({ projectDir }); + await project.fileStore.writeFile( + 'semantic-layer/warehouse/orders.yaml', + ORDERS_YAML, + 'ktx', + 'ktx@example.com', + 'Add semantic-layer source', + ); + await project.fileStore.writeFile( + 'semantic-layer/analytics/tickets.yaml', + [ + 'name: tickets', + 'table: public.tickets', + 'grain:', + ' - ticket_id', + 'columns:', + ' - name: ticket_id', + ' type: string', + '', + ].join('\n'), + 'ktx', + 'ktx@example.com', + 'Add semantic-layer source', + ); + + const validateIo = makeIo(); + await expect( + runKtxSl( + { + command: 'validate', + projectDir, + sourceName: 'tickets', + }, + validateIo.io, + ), + ).resolves.toBe(0); + + expect(validateIo.stdout()).toBe('Valid semantic-layer source: analytics/tickets\n'); + expect(validateIo.stderr()).toBe(''); + }); + + it('reports ambiguous unscoped validation with sorted connection ids', async () => { + const projectDir = join(tempDir, 'validate-ambiguous-project'); + const project = await initKtxProject({ projectDir }); + await project.fileStore.writeFile( + 'semantic-layer/warehouse/orders.yaml', + ORDERS_YAML, + 'ktx', + 'ktx@example.com', + 'Add semantic-layer source', + ); + await project.fileStore.writeFile( + 'semantic-layer/analytics/orders.yaml', + ORDERS_YAML, + 'ktx', + 'ktx@example.com', + 'Add semantic-layer source', + ); + + const validateIo = makeIo(); + await expect( + runKtxSl( + { + command: 'validate', + projectDir, + sourceName: 'orders', + }, + validateIo.io, + ), + ).resolves.toBe(1); + + expect(validateIo.stdout()).toBe(''); + expect(validateIo.stderr()).toBe( + "Source 'orders' exists in multiple connections: analytics, warehouse. Re-run with --connection-id .\n", + ); + }); + + it('reports a clear error when an unscoped semantic-layer source validation target is missing', async () => { + const projectDir = join(tempDir, 'missing-unscoped-validate-project'); + await seedSlSource({ projectDir }); + + const validateIo = makeIo(); + await expect( + runKtxSl( + { + command: 'validate', + projectDir, + sourceName: 'missing_orders', + }, + validateIo.io, + ), + ).resolves.toBe(1); + + expect(validateIo.stdout()).toBe(''); + expect(validateIo.stderr()).toBe('Semantic-layer source "missing_orders" was not found\n'); + }); + + it('keeps scoped validation not-found wording', async () => { + const projectDir = join(tempDir, 'missing-scoped-validate-project'); + await seedSlSource({ projectDir }); + + const validateIo = makeIo(); + await expect( + runKtxSl( + { + command: 'validate', + projectDir, + connectionId: 'warehouse', + sourceName: 'missing_orders', + }, + validateIo.io, + ), + ).resolves.toBe(1); + + expect(validateIo.stdout()).toBe(''); + expect(validateIo.stderr()).toBe('Semantic-layer source "warehouse/missing_orders" was not found\n'); + }); + it('prints semantic-layer search rank badges in pretty output', async () => { const projectDir = join(tempDir, 'rank-project'); await seedSlSource({ projectDir }); From ba5bb92ab77fda7522621312539e65fff75c2564 Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Mon, 1 Jun 2026 12:06:27 +0200 Subject: [PATCH 29/61] feat: README architecture diagrams + React Flow diagram studio (#245) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the tall portrait README ingestion SVG with two landscape diagrams — "1 · Ingestion" (build the context layer) and "2 · Serving" (agents query it through MCP) — wired in as transparent 2x PNGs that read on GitHub light and dark. Add docs-site/diagram-studio: a static React Flow page with custom themed nodes and the inlined ktx mascot that renders both diagrams and exports them to PNG via html-to-image (the diagrams' reproducible source). Remove the superseded ingestion-flow SVGs. --- README.md | 7 +- docs-site/app/diagram-studio/page.tsx | 12 + docs-site/components/diagram-studio/flows.ts | 328 ++++++++++++ .../components/diagram-studio/mascot.tsx | 57 ++ docs-site/components/diagram-studio/nodes.tsx | 493 ++++++++++++++++++ .../components/diagram-studio/studio.tsx | 242 +++++++++ docs-site/package.json | 1 + .../images/ingestion-flow-transparent.svg | 210 -------- docs-site/public/images/ingestion-flow.png | Bin 140531 -> 354604 bytes docs-site/public/images/mcp-runtime-flow.png | Bin 0 -> 179902 bytes pnpm-lock.yaml | 8 + 11 files changed, 1147 insertions(+), 211 deletions(-) create mode 100644 docs-site/app/diagram-studio/page.tsx create mode 100644 docs-site/components/diagram-studio/flows.ts create mode 100644 docs-site/components/diagram-studio/mascot.tsx create mode 100644 docs-site/components/diagram-studio/nodes.tsx create mode 100644 docs-site/components/diagram-studio/studio.tsx delete mode 100644 docs-site/public/images/ingestion-flow-transparent.svg create mode 100644 docs-site/public/images/mcp-runtime-flow.png diff --git a/README.md b/README.md index 686ece22..e235bab1 100644 --- a/README.md +++ b/README.md @@ -34,9 +34,14 @@ business knowledge it builds and maintains for you. > No extra usage billing from **ktx**.

- ktx ingestion flow from source systems through validation to wiki and semantic-layer outputs + Ingestion: ktx ingests databases, BI tools, modeling code, and docs through its context engine (source connectors, context builder, reconciliation, validation) into wiki Markdown and semantic-layer YAML

+

+ Serving: an agent queries ktx through MCP, which searches the wiki and semantic layer, returns approved metrics, and compiles them into read-only SQL run against the warehouse +

+ + ## Why ktx General-purpose agents struggle on data tasks. They re-explore your warehouse diff --git a/docs-site/app/diagram-studio/page.tsx b/docs-site/app/diagram-studio/page.tsx new file mode 100644 index 00000000..205ebd7a --- /dev/null +++ b/docs-site/app/diagram-studio/page.tsx @@ -0,0 +1,12 @@ +import type { Metadata } from "next"; + +import { DiagramStudio } from "@/components/diagram-studio/studio"; + +export const metadata: Metadata = { + title: "Diagram studio", + robots: { index: false, follow: false }, +}; + +export default function DiagramStudioPage() { + return ; +} diff --git a/docs-site/components/diagram-studio/flows.ts b/docs-site/components/diagram-studio/flows.ts new file mode 100644 index 00000000..cddf75cb --- /dev/null +++ b/docs-site/components/diagram-studio/flows.ts @@ -0,0 +1,328 @@ +import { type Edge, MarkerType, type Node } from "@xyflow/react"; + +import { C } from "./nodes"; + +const EDGE_COLOR = "#b3bcc4"; +const MARKER_COLOR = "#9aa6ad"; + +const labelStyle = { + fontFamily: "var(--font-inter), system-ui, sans-serif", + fontSize: 15, + fontWeight: 600, + fill: C.inkMuted, +}; +const labelBgStyle = { fill: "#ffffff", stroke: C.chipBorder, strokeWidth: 1 }; +const labelBg = { + labelBgPadding: [8, 4] as [number, number], + labelBgBorderRadius: 6, + labelStyle, + labelBgStyle, +}; + +const marker = { type: MarkerType.ArrowClosed, color: MARKER_COLOR, width: 16, height: 16 }; +const edgeStyle = { stroke: EDGE_COLOR, strokeWidth: 2 }; + +/* ============================== INGESTION =============================== */ + +const SRC_W = 300; +const SRC_H = 138; +const SRC_GAP = 24; +const srcY = (i: number) => i * (SRC_H + SRC_GAP); + +export const ingestionNodes: Node[] = [ + { + id: "title", + type: "title", + position: { x: 0, y: -96 }, + data: { + width: 560, + eyebrow: "1 · Ingestion", + title: "ktx builds your context layer", + }, + }, + { + id: "db", + type: "card", + position: { x: 0, y: srcY(0) }, + data: { + width: SRC_W, + height: SRC_H, + accent: C.teal, + rows: [ + { kind: "title", text: "Databases" }, + { kind: "desc", text: "Schemas, keys, query history" }, + { kind: "muted", text: "Postgres · Snowflake · BigQuery · …" }, + ], + handles: [{ side: "right", type: "source", id: "out" }], + }, + }, + { + id: "bi", + type: "card", + position: { x: 0, y: srcY(1) }, + data: { + width: SRC_W, + height: SRC_H, + accent: C.orange, + rows: [ + { kind: "title", text: "BI tools" }, + { kind: "desc", text: "Dashboards, explores, usage" }, + { kind: "muted", text: "Metabase · Looker · …" }, + ], + handles: [{ side: "right", type: "source", id: "out" }], + }, + }, + { + id: "model", + type: "card", + position: { x: 0, y: srcY(2) }, + data: { + width: SRC_W, + height: SRC_H, + accent: C.amber, + rows: [ + { kind: "title", text: "Modeling code" }, + { kind: "desc", text: "Metrics, models, joins, entities" }, + { kind: "muted", text: "dbt · LookML · MetricFlow · …" }, + ], + handles: [{ side: "right", type: "source", id: "out" }], + }, + }, + { + id: "docs", + type: "card", + position: { x: 0, y: srcY(3) }, + data: { + width: SRC_W, + height: SRC_H, + accent: C.emerald, + rows: [ + { kind: "title", text: "Docs & notes" }, + { kind: "desc", text: "Policies, definitions, notes" }, + { kind: "muted", text: "Notion · any text · …" }, + ], + handles: [{ side: "right", type: "source", id: "out" }], + }, + }, + { + id: "engine", + type: "engine", + position: { x: 420, y: 52 }, + data: { + width: 380, + height: 520, + steps: [ + { n: 1, title: "Source connectors", desc: "Read each source in its shape" }, + { n: 2, title: "Context builder", desc: "Evidence into proposed updates" }, + { n: 3, title: "Reconciliation", desc: "Merge with existing context" }, + { n: 4, title: "Validation", desc: "Check references & semantics" }, + ], + handles: [ + { side: "left", type: "target", id: "in" }, + { side: "right", type: "source", id: "out" }, + ], + }, + }, + { + id: "wiki", + type: "card", + position: { x: 900, y: 66 }, + data: { + width: 320, + height: 220, + accent: C.emerald, + rows: [ + { kind: "mono", text: "wiki/*.md", color: C.emerald }, + { kind: "title", text: "Wiki" }, + { kind: "chips", items: ["free-form", "auto-maintained"] }, + { kind: "desc", text: "Definitions, caveats, policies," }, + { kind: "desc", text: "and notes agents can search." }, + ], + handles: [{ side: "left", type: "target", id: "in" }], + }, + }, + { + id: "sl", + type: "card", + position: { x: 900, y: 338 }, + data: { + width: 320, + height: 220, + accent: C.teal, + rows: [ + { kind: "mono", text: "semantic-layer/*.yaml", color: C.teal }, + { kind: "title", text: "Semantic layer" }, + { kind: "chips", items: ["executable", "auto-maintained"] }, + { kind: "desc", text: "Metrics, joins, dimensions, and" }, + { kind: "desc", text: "filters ktx compiles into SQL." }, + ], + handles: [{ side: "left", type: "target", id: "in" }], + }, + }, +]; + +const ingestEdge = (source: string, target: string): Edge => ({ + id: `${source}-${target}`, + source, + target, + sourceHandle: "out", + targetHandle: "in", + type: "default", + style: edgeStyle, + markerEnd: marker, +}); + +export const ingestionEdges: Edge[] = [ + ingestEdge("db", "engine"), + ingestEdge("bi", "engine"), + ingestEdge("model", "engine"), + ingestEdge("docs", "engine"), + ingestEdge("engine", "wiki"), + ingestEdge("engine", "sl"), +]; + +/* =============================== RUNTIME ================================ */ + +export const runtimeNodes: Node[] = [ + { + id: "title", + type: "title", + position: { x: 0, y: -84 }, + data: { + width: 560, + eyebrow: "2 · Serving", + title: "agents query it through MCP", + }, + }, + { + id: "agent", + type: "card", + position: { x: 0, y: 115 }, + data: { + width: 280, + height: 190, + accent: C.neutral, + align: "center", + rows: [ + { kind: "title", text: "Your agent" }, + { kind: "muted", text: "Claude Code · Cursor" }, + { kind: "muted", text: "Codex · OpenCode" }, + ], + handles: [ + { side: "right", type: "source", id: "ask", top: "42%" }, + { side: "right", type: "target", id: "answer", top: "62%" }, + ], + }, + }, + { + id: "hub", + type: "hub", + position: { x: 420, y: 85 }, + data: { + width: 360, + height: 250, + rows: [ + "Search wiki + semantic layer", + "Return approved metrics", + "Compile metrics → SQL", + ], + handles: [ + { side: "left", type: "target", id: "ask", top: "42%" }, + { side: "left", type: "source", id: "answer", top: "62%" }, + { side: "right", type: "source", id: "to-context", top: "30%" }, + { side: "right", type: "source", id: "to-warehouse", top: "72%" }, + ], + }, + }, + { + id: "context", + type: "card", + position: { x: 920, y: 15 }, + data: { + width: 300, + height: 150, + accent: C.teal, + rows: [ + { kind: "title", text: "Context layer" }, + { kind: "mono", text: "wiki/*.md", color: C.emerald }, + { kind: "mono", text: "semantic-layer/*.yaml", color: C.teal }, + ], + handles: [{ side: "left", type: "target", id: "in" }], + }, + }, + { + id: "warehouse", + type: "card", + position: { x: 920, y: 255 }, + data: { + width: 300, + height: 150, + accent: C.slate, + rows: [ + { kind: "title", text: "Warehouse" }, + { + kind: "badge", + text: "read-only", + bg: "#ecf6f8", + border: "#bfe3ea", + color: C.teal, + }, + { kind: "desc", text: "Runs the compiled SQL" }, + ], + handles: [{ side: "left", type: "target", id: "in" }], + }, + }, +]; + +export const runtimeEdges: Edge[] = [ + { + id: "ask", + source: "agent", + sourceHandle: "ask", + target: "hub", + targetHandle: "ask", + type: "default", + label: "ask", + ...labelBg, + style: edgeStyle, + markerEnd: marker, + }, + { + id: "answer", + source: "hub", + sourceHandle: "answer", + target: "agent", + targetHandle: "answer", + type: "default", + label: "answer", + ...labelBg, + style: edgeStyle, + markerEnd: marker, + }, + { + id: "search", + source: "hub", + sourceHandle: "to-context", + target: "context", + targetHandle: "in", + type: "default", + label: "search", + ...labelBg, + style: edgeStyle, + markerStart: marker, + markerEnd: marker, + }, + { + id: "readonly", + source: "hub", + sourceHandle: "to-warehouse", + target: "warehouse", + targetHandle: "in", + type: "default", + label: "read-only", + ...labelBg, + style: edgeStyle, + markerStart: marker, + markerEnd: marker, + }, +]; diff --git a/docs-site/components/diagram-studio/mascot.tsx b/docs-site/components/diagram-studio/mascot.tsx new file mode 100644 index 00000000..467f6ee5 --- /dev/null +++ b/docs-site/components/diagram-studio/mascot.tsx @@ -0,0 +1,57 @@ +/** + * Inlined ktx mascot, ported from assets/ktx-mascot.svg. + * + * - `light` renders the dark-bodied mascot for light surfaces. + * - `dark` renders the cream-bodied mascot for dark surfaces (e.g. the ktx + * hub panel), mirroring brand/ktx-mascot-dark.svg. + */ +export function KtxMascot({ + variant = "light", + size = 56, +}: { + variant?: "light" | "dark"; + size?: number; +}) { + const body = variant === "dark" ? "#F5F1EA" : "#1B3139"; + const eye = variant === "dark" ? "#1B3139" : "#F5F1EA"; + return ( + + + + + + + + + + + + ); +} diff --git a/docs-site/components/diagram-studio/nodes.tsx b/docs-site/components/diagram-studio/nodes.tsx new file mode 100644 index 00000000..f648a905 --- /dev/null +++ b/docs-site/components/diagram-studio/nodes.tsx @@ -0,0 +1,493 @@ +"use client"; + +import { Handle, Position, type Node, type NodeProps } from "@xyflow/react"; + +import { KtxMascot } from "./mascot"; + +/** Fixed palette mirrored from the approved SVG diagrams so the exported PNG + * is theme-independent (one image that reads on light and dark GitHub). */ +export const C = { + ink: "#1b1b18", + inkSoft: "#57534e", + inkMuted: "#8c857f", + cardBorder: "#e2dfd9", + engineBg: "#15323a", + engineBorder: "#23474f", + cyan: "#55dced", + stepNum: "#06262c", + stepTitle: "#f3f1ec", + stepDesc: "#9fb6bc", + hubRow: "#eef4f5", + chipBg: "#faf9f6", + chipBorder: "#e7e5e4", + teal: "#0e7490", + emerald: "#059669", + orange: "#f97316", + amber: "#d97706", + slate: "#334155", + neutral: "#94a3b8", +} as const; + +const DISPLAY = "var(--font-display), system-ui, sans-serif"; +const BODY = "var(--font-inter), system-ui, sans-serif"; +const MONO = "var(--font-mono), ui-monospace, monospace"; + +const CARD_SHADOW = "0 3px 12px rgba(27, 49, 57, 0.10)"; +const ENGINE_SHADOW = "0 6px 22px rgba(2, 12, 15, 0.30)"; + +/** ktx logo mascot size, shared by the engine and hub headers. */ +const LOGO_SIZE = 56; + +type HandleSpec = { + side: "left" | "right"; + type: "source" | "target"; + id: string; + top?: string; +}; + +function Handles({ specs }: { specs?: HandleSpec[] }) { + if (!specs) return null; + return ( + <> + {specs.map((h) => ( + + ))} + + ); +} + +/* ------------------------------- Card node ------------------------------- */ + +type CardRow = + | { kind: "title"; text: string } + | { kind: "mono"; text: string; color: string } + | { kind: "desc"; text: string } + | { kind: "muted"; text: string } + | { kind: "chips"; items: string[] } + | { kind: "badge"; text: string; bg: string; border: string; color: string }; + +type CardData = { + width: number; + height: number; + accent: string; + align?: "center"; + rows: CardRow[]; + handles?: HandleSpec[]; +}; + +function gapFor(kind: CardRow["kind"], prev?: CardRow["kind"]): number { + if (!prev) return 0; + if (kind === "desc" && prev === "desc") return 3; + if (kind === "mono" && prev === "mono") return 2; + if (kind === "title") return 6; + return 10; +} + +function CardRowView({ row }: { row: CardRow }) { + switch (row.kind) { + case "title": + return ( + + {row.text} + + ); + case "mono": + return ( + + {row.text} + + ); + case "desc": + return ( + + {row.text} + + ); + case "muted": + return ( + + {row.text} + + ); + case "chips": + return ( +
+ {row.items.map((c) => ( + + {c} + + ))} +
+ ); + case "badge": + return ( + + {row.text} + + ); + } +} + +function CardNode({ data }: NodeProps>) { + const center = data.align === "center"; + return ( +
+ + + {data.rows.map((row, i) => ( +
+ +
+ ))} +
+ ); +} + +/* ------------------------------ Engine node ------------------------------ */ + +type EngineStep = { n: number; title: string; desc: string }; + +type EngineData = { + width: number; + height: number; + steps: EngineStep[]; + handles?: HandleSpec[]; +}; + +function EngineNode({ data }: NodeProps>) { + return ( +
+ + +
+ + + ktx + +
+
+ {data.steps.map((s) => ( +
+ + {s.n} + +
+ + {s.title} + + + {s.desc} + +
+
+ ))} +
+
+ ); +} + +/* -------------------------------- Hub node ------------------------------- */ + +type HubData = { + width: number; + height: number; + rows: string[]; + handles?: HandleSpec[]; +}; + +function HubNode({ data }: NodeProps>) { + return ( +
+ + +
+ + + ktx + +
+
+ {data.rows.map((r) => ( +
+ + + {r} + +
+ ))} +
+
+ ); +} + +/* ------------------------------- Title node ------------------------------ */ + +type TitleData = { width: number; eyebrow: string; title: string }; + +function TitleNode({ data }: NodeProps>) { + return ( +
+ + {data.eyebrow} + + + {data.title} + +
+ ); +} + +export const nodeTypes = { + card: CardNode, + engine: EngineNode, + hub: HubNode, + title: TitleNode, +}; diff --git a/docs-site/components/diagram-studio/studio.tsx b/docs-site/components/diagram-studio/studio.tsx new file mode 100644 index 00000000..7b96ae7b --- /dev/null +++ b/docs-site/components/diagram-studio/studio.tsx @@ -0,0 +1,242 @@ +"use client"; + +import "@xyflow/react/dist/style.css"; + +import { useCallback, useRef, useState } from "react"; +import { + Background, + BackgroundVariant, + type Edge, + getNodesBounds, + type Node, + ReactFlow, + ReactFlowProvider, + useEdgesState, + useNodesState, + useReactFlow, +} from "@xyflow/react"; +import { toPng } from "html-to-image"; + +import { + ingestionEdges, + ingestionNodes, + runtimeEdges, + runtimeNodes, +} from "./flows"; +import { nodeTypes } from "./nodes"; + +const EXPORT_PADDING = 48; +const EXPORT_PIXEL_RATIO = 2; + +function DiagramCanvasInner({ + initialNodes, + initialEdges, + fileName, + height, + dark, +}: { + initialNodes: Node[]; + initialEdges: Edge[]; + fileName: string; + height: number; + dark: boolean; +}) { + const wrapperRef = useRef(null); + const [nodes, , onNodesChange] = useNodesState(initialNodes); + const [edges, , onEdgesChange] = useEdgesState(initialEdges); + const { getNodes } = useReactFlow(); + const [busy, setBusy] = useState(false); + + const download = useCallback(async () => { + const viewport = wrapperRef.current?.querySelector( + ".react-flow__viewport", + ); + if (!viewport) return; + setBusy(true); + try { + await document.fonts.ready; + const bounds = getNodesBounds(getNodes()); + const outW = Math.ceil(bounds.width + EXPORT_PADDING * 2); + const outH = Math.ceil(bounds.height + EXPORT_PADDING * 2); + const tx = EXPORT_PADDING - bounds.x; + const ty = EXPORT_PADDING - bounds.y; + const dataUrl = await toPng(viewport, { + width: outW, + height: outH, + pixelRatio: EXPORT_PIXEL_RATIO, + // transparent background so one PNG works on light and dark GitHub + style: { + width: `${outW}px`, + height: `${outH}px`, + transform: `translate(${tx}px, ${ty}px) scale(1)`, + }, + }); + const link = document.createElement("a"); + link.download = fileName; + link.href = dataUrl; + link.click(); + } finally { + setBusy(false); + } + }, [fileName, getNodes]); + + return ( +
+
+ +
+
+ + + +
+
+ ); +} + +function btnStyle(disabled: boolean): React.CSSProperties { + return { + fontFamily: "var(--font-inter), system-ui, sans-serif", + fontSize: 13, + fontWeight: 600, + padding: "7px 14px", + borderRadius: 8, + border: "1px solid #0e7490", + background: disabled ? "#9bbdc6" : "#0e7490", + color: "#ffffff", + cursor: disabled ? "default" : "pointer", + }; +} + +function DiagramCanvas(props: { + initialNodes: Node[]; + initialEdges: Edge[]; + fileName: string; + height: number; + dark: boolean; +}) { + return ( + + + + ); +} + +export function DiagramStudio() { + const [dark, setDark] = useState(false); + return ( +
+
+

+ ktx diagram studio +

+

+ Static diagrams. Export is a transparent 2× PNG framed to the node + bounds — the dark-background toggle is only for previewing. +

+ +
+ +
+

1 · Ingestion — building the context layer

+ +
+ +
+

2 · Serving — answering agents at runtime

+ +
+
+ ); +} + +const sectionTitle: React.CSSProperties = { + fontFamily: "var(--font-display), system-ui, sans-serif", + fontSize: 18, + fontWeight: 600, + color: "#1b1b18", + marginBottom: 12, +}; diff --git a/docs-site/package.json b/docs-site/package.json index 2af1c19d..f418c0ee 100644 --- a/docs-site/package.json +++ b/docs-site/package.json @@ -14,6 +14,7 @@ "fumadocs-core": "16.8.10", "fumadocs-mdx": "15.0.7", "fumadocs-ui": "16.8.10", + "html-to-image": "1.11.11", "next": "^16", "react": "19.2.6", "react-dom": "19.2.6" diff --git a/docs-site/public/images/ingestion-flow-transparent.svg b/docs-site/public/images/ingestion-flow-transparent.svg deleted file mode 100644 index 86356d6b..00000000 --- a/docs-site/public/images/ingestion-flow-transparent.svg +++ /dev/null @@ -1,210 +0,0 @@ - - ktx ingestion flow - Source systems flow through source connectors, context builder, reconciliation, and validation to create wiki Markdown and semantic-layer YAML outputs. - - - - - - - - - - - - - - - - - - - - - - - - - Databases - Schemas, columns, keys, - row counts, and query - history. - - - PostgreSQL - - Snowflake - - BigQuery - - SQLite - - - - - - - BI tools - Dashboards, questions, - explores, usage, and trusted - examples. - - - Metabase - - Looker - - - - - - - Modeling code - Existing metrics, dimensions, - models, joins, and entities. - - - dbt - - LookML - - MetricFlow - - - - - - - Docs and notes - Policies, caveats, team - definitions, and analyst - context. - - - Notion - - Any text - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 1 - Source connectors - Read each configured system in - its native shape. - - - - - - 2 - Context builder - Turn source evidence into - proposed context updates. - - - - - - 3 - Reconciliation - Merge new evidence with the - context that already exists. - - - - - - 4 - Validation - Check references and semantics - before agents rely on them. - - - - - - - - wiki/*.md - Wiki - - - free-form - - auto-maintained - - Definitions, caveats, policies, analyst notes, and - business language that agents can search. - - - - - - semantic-layer/*.yaml - Semantic layer - - - structured - - executable - - auto-maintained - - Metrics, joins, tables, dimensions, filters, and - segments that ktx can validate and compile into - SQL. - - - - - references - - - diff --git a/docs-site/public/images/ingestion-flow.png b/docs-site/public/images/ingestion-flow.png index 49bc544ff89bfcc72e6a25205ca24a1a0879a33f..59f6ad176939ae5b02334a25f2fdb206fd8c9e98 100644 GIT binary patch literal 354604 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%0AA^#Jv3d8l%Di{j5v|KN-DzS)UPM}8& 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
C+{X$ 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

%x$dLVd(7X)BoC-ZmUgc?g_q;EeQ1nY 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%0DdL^Zrvu!4$idnq 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 diff --git a/docs-site/public/images/mcp-runtime-flow.png b/docs-site/public/images/mcp-runtime-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..ec56dff1e531d63670ef292c4b25ed4c00475e18 GIT binary patch literal 179902 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%0D6?{q*MHMsaC^4`|Z8oaJZD} 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 literal 0 HcmV?d00001 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bf496066..15bc75f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -85,6 +85,9 @@ importers: fumadocs-ui: specifier: 16.8.10 version: 16.8.10(@tailwindcss/oxide@4.3.0)(@types/mdx@2.0.13)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(fumadocs-core@16.8.10(@mdx-js/mdx@3.1.1)(@types/estree-jsx@1.0.5)(@types/hast@3.0.4)(@types/mdast@4.0.4)(@types/react@19.2.15)(lucide-react@1.16.0(react@19.2.6))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(zod@4.4.3))(next@16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(tailwindcss@4.3.0) + html-to-image: + specifier: 1.11.11 + version: 1.11.11 next: specifier: ^16 version: 16.2.6(@opentelemetry/api@1.9.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -3722,6 +3725,9 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-to-image@1.11.11: + resolution: {integrity: sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA==} + html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} @@ -9623,6 +9629,8 @@ snapshots: html-escaper@2.0.2: {} + html-to-image@1.11.11: {} + html-void-elements@3.0.0: {} http-errors@2.0.1: From 1959f493d6f064f3b2d82e33b8a41ed36fe7075b Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Mon, 1 Jun 2026 13:18:37 +0200 Subject: [PATCH 30/61] fix(brand): README lockup wordmark in Outfit to match docs-site (#246) --- assets/ktx-lockup.svg | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/assets/ktx-lockup.svg b/assets/ktx-lockup.svg index f1bcd2dd..2e45f8a6 100644 --- a/assets/ktx-lockup.svg +++ b/assets/ktx-lockup.svg @@ -19,14 +19,9 @@ - - ktx + + + + From 5faa16b32c9eb0c7a30096e04c6f3b2525fdae5e Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Mon, 1 Jun 2026 14:08:58 +0200 Subject: [PATCH 31/61] docs(ktx skill): harden setup guidance from agent-driven demo run (#247) Fold field-tested fixes into the ktx skill, verified against current CLI source: - prefer file: secret refs over env: (env: re-resolves per-process and resolves empty in later ingest/mcp shells) - pass --skip-agents on data-only setup runs; explain the trailing agent step's misleading exit 1 on otherwise-successful runs - dbt ignores --source-warehouse-connection-id (maps by table name); required only for Metabase/Looker/LookML - never go silent during slow setup/ingest: poll .ktx mtimes and post progress so a long run does not look stuck - judge readiness from verdict, connections[].status, localStats.semanticLayer and wikiPages; perConnection under-reports - add troubleshooting entries for the 'Run in a TTY' exit 1 and secrets that resolve empty only during ingest/mcp --- skills/ktx/SKILL.md | 104 ++++++++++++++++++++++++++-------- skills/ktx/troubleshooting.md | 41 ++++++++++++++ 2 files changed, 120 insertions(+), 25 deletions(-) diff --git a/skills/ktx/SKILL.md b/skills/ktx/SKILL.md index 58893d7f..ef316b63 100644 --- a/skills/ktx/SKILL.md +++ b/skills/ktx/SKILL.md @@ -20,11 +20,25 @@ a local **ktx** setup. `https://docs.kaelio.com/ktx/` or this skill — not against `--help` output. - Ask only for values you cannot infer: project directory, connection targets, credentials, account identifiers, and source selections. -- Never ask the user to paste secrets when an `env:VAR_NAME` or `file:/path` - reference would work. Pasting a literal URL is also safe — `ktx setup` - auto-externalizes URLs into `.ktx/secrets/-url` (see workflow step 2). +- Prefer `file:/abs/path` secret refs over `env:VAR_NAME`. `env:` refs are + re-resolved against the process environment on **every** `ktx` run, so a var + exported only in the setup shell is gone when `ktx ingest` or `ktx mcp start` + runs later — the secret silently resolves to empty and the connection fails. + `file:` refs read from disk and survive across shells. The same caveat + applies to `--*-api-key-env` flags: the named var must be present in every + shell that runs `ktx`, including the `ktx mcp` daemon's environment. +- A literal database URL is safe to pass — `ktx setup` auto-externalizes it + into `.ktx/secrets/-url` and rewrites `ktx.yaml` to a `file:` ref (see + workflow step 2). Source credential refs are **not** auto-externalized: write + the secret to a file under `.ktx/secrets/` (`chmod 600`) and pass a `file:` + ref. Never ask the user to paste a secret when a `file:` or `env:` ref works. - Do not commit `.ktx/secrets/*`. - Print each command you run and its result. +- Setup and ingest can run for many minutes (LLM-heavy source ingests take the + longest), and from the outside a slow step looks identical to a stuck one. + Don't go silent: say what's about to run and that it may take a while, then + post brief progress/liveness updates while it runs (see step 4) so the user + never has to wonder whether it stalled — otherwise they may kill it mid-run. - If a command fails, identify the cause and change something before retrying. ## Gather inputs once @@ -68,9 +82,10 @@ Do not discover these inputs across multiple setup runs. --llm-backend claude-code \ --embedding-backend sentence-transformers \ --database --database-connection-id \ - --database-url '' \ + --database-url '' \ --database-schema \ - --skip-sources + --skip-sources \ + --skip-agents ``` - Configure one new database connection per setup invocation. For multiple @@ -78,6 +93,13 @@ Do not discover these inputs across multiple setup runs. - Pasting a literal `--database-url` is safe: the CLI relocates the URL into `.ktx/secrets/-url` and rewrites `ktx.yaml` to a `file:` ref automatically. + - `ktx setup` runs agent integration as its **last** step. In `--no-input` + mode with neither `--target` nor `--skip-agents`, that step has no input, + prints `Run in a TTY, or pass --target .`, and the command exits + non-zero **even though every database/LLM/embedding step succeeded**. Pass + `--skip-agents` to defer agents to step 5 (as above), or `--target ` + to install them inline and exit 0. Judge data-layer success from + `ktx status`, not from this exit code. 3. **Resumability and `--skip-*`.** Re-running `ktx setup` against an existing project resumes its config. Use `--skip-llm`, `--skip-databases`, @@ -99,6 +121,23 @@ Do not discover these inputs across multiple setup runs. together with `--no-input` (*Choose only one runtime install mode*); `ktx setup` accepts both. Use `--no-input` only for ingest. + Ingest one connection at a time. It can run for many minutes with **no + stdout** until it exits (LLM-heavy sources like Metabase are the slowest), so + don't assume it hung, and don't pipe it through `tail`/`head` — that buffers + all output to the end, so run it raw. Tell the user up front that the step is + slow, then keep them posted instead of blocking silently: run the ingest in + the background and poll for liveness every minute or so, reporting a one-line + update each time (which connection, roughly how long it's been running, and + that `.ktx` files are still changing) so a long run never looks stuck: + + ```bash + find /.ktx/worktrees /.ktx/ingest-transcripts -type f -mmin -3 + ``` + + On success, the `Ingest finished` summary table shows `done` in the + `Source ingest` and `Memory update` columns with no `Failed sources:` + section. + 5. **Install agent integration:** ```bash @@ -117,29 +156,33 @@ Do not discover these inputs across multiple setup runs. Context sources (dbt, Metabase, Looker, LookML, MetricFlow, Notion) are added **one at a time** — `--source` is not repeatable, so run `ktx setup` once per source. Source setup is resumable against an existing project: pass -`--skip-databases --skip-llm --skip-embeddings` so only the source is -configured. Map warehouse-backed sources (dbt, Metabase, Looker) to an existing -database connection with `--source-warehouse-connection-id `. -Prefer `env:VAR` / `file:/abs/path` refs for keys and tokens over literals. +`--skip-databases --skip-llm --skip-embeddings --skip-agents` so only the source +is configured (the trailing agent step otherwise fails the run — see install +step 2). Map Metabase, Looker, and LookML to an existing database connection +with `--source-warehouse-connection-id ` (required for those). +**dbt ignores `--source-warehouse-connection-id`** — it maps to the warehouse by +table name — so omit it for dbt. Use `file:/abs/path` refs for keys and tokens +(see the secrets rule above); `env:` refs must be exported in every later `ktx` +shell. ```bash -# dbt — pick exactly one of --source-path (local) or --source-git-url (remote) -ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings \ +# dbt — pick exactly one of --source-path (local) or --source-git-url (remote). +# No --source-warehouse-connection-id: dbt maps to the warehouse by table name. +ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings --skip-agents \ --source dbt --source-connection-id \ - --source-git-url --source-branch \ - --source-warehouse-connection-id + --source-git-url --source-branch # Metabase -ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings \ +ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings --skip-agents \ --source metabase --source-connection-id \ - --source-url --source-api-key-ref env:METABASE_API_KEY \ + --source-url --source-api-key-ref file:/abs/path/metabase-api-key \ --source-warehouse-connection-id \ --metabase-database-id # Notion -ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings \ +ktx setup --no-input --yes --skip-databases --skip-llm --skip-embeddings --skip-agents \ --source notion --source-connection-id \ - --source-auth-token-ref env:NOTION_TOKEN \ + --source-auth-token-ref file:/abs/path/notion-token \ --notion-crawl-mode selected_roots --notion-root-page-id ``` @@ -171,25 +214,36 @@ After setup, run: ```bash ktx connection test ktx status --json --no-input +ktx sl --output plain # lists compiled semantic sources; `ktx sl` has no --no-input ``` **Judge readiness from `ktx status --json` fields, not the exit code.** -`ktx status` exits 1 whenever the LLM is `none`, even when embeddings and -every database connection are healthy. Treat success as: +`ktx status` exits 1 whenever the LLM is `none` (`verdict: "blocked"`), even +when embeddings and every database connection are healthy. Treat success as: - `verdict: "ready"` at the top of the JSON, and -- every `connections[].status === "ok"`, and -- every `ktx connection test ` exited 0. +- every `connections[].status === "ok"` (other levels: `warn`, `fail`, + `skipped`), and +- every `ktx connection test ` exited 0, and +- for each ingested source, `localStats.semanticLayer[].sourceCount > 0` and + `localStats.wikiPages[].count > 0` — these confirm the source actually + produced context. Do **not** rely on `localStats.ingest.perConnection` to + confirm source ingests: it reflects only completed warehouse ingest reports + and under-reports (often lists just the warehouse connection). -A non-zero exit with only the LLM unconfigured is still a usable context -layer — report it as "ready, LLM optional" rather than retrying setup. +If the LLM is intentionally left unconfigured, `verdict` is `blocked` and the +exit is non-zero by design — that is still a usable context layer, so report it +as "ready, LLM optional" and judge the data layer by the connection and +`localStats` fields above rather than retrying setup. ## Troubleshooting For known failure signatures (`invalid ELF header`, `Native CLI binary for not found`, `Missing Anthropic API key`, -`claude-code` probe failure, `KTX cannot work without a database` on resume), -see [troubleshooting.md](troubleshooting.md). +`claude-code` probe failure, `KTX cannot work without a database` on resume, +`Run in a TTY, or pass --target .` with a misleading exit 1, and a +secret that resolves empty only during `ktx ingest`/`ktx mcp`), see +[troubleshooting.md](troubleshooting.md). ## Final report diff --git a/skills/ktx/troubleshooting.md b/skills/ktx/troubleshooting.md index 812b45fc..20f72d23 100644 --- a/skills/ktx/troubleshooting.md +++ b/skills/ktx/troubleshooting.md @@ -77,3 +77,44 @@ ktx setup --no-input \ --database --database-connection-id \ --llm-backend claude-code ``` + +## `Run in a TTY, or pass --target .` and `ktx setup` exits 1 + +`ktx setup` runs agent integration as its last step. In `--no-input` mode with +neither `--target` nor `--skip-agents`, that step has no input and the whole +command exits non-zero — even when every database, LLM, and embedding step +already succeeded. The exit code is misleading here. + +Fix — pass one of these to the data-only setup runs: + +```bash +# Defer agents; install them later with `ktx setup --agents --target `: +ktx setup --no-input --yes ...other flags... --skip-agents + +# Or install agents inline and exit 0: +ktx setup --no-input --yes ...other flags... --target claude-code +``` + +Either way, confirm the data work landed with `ktx status --json` rather than +trusting the exit code. + +## A secret resolves empty only during `ktx ingest` or `ktx mcp` + +Setup succeeded, but a later `ktx ingest`/`ktx mcp start` fails to connect or +authenticate. The connection used an `env:VAR_NAME` ref (or a `--*-api-key-env` +flag) and the variable was exported only in the setup shell. `env:` refs are +re-resolved against the process environment on every `ktx` run, so they resolve +to empty wherever the var is absent — including the `ktx mcp` daemon. + +Fix — write the secret to a file and use a `file:` ref, which reads from disk +and survives across shells: + +```bash +mkdir -p "$PROJECT/.ktx/secrets" +printf '%s\n' '' > "$PROJECT/.ktx/secrets/-" +chmod 600 "$PROJECT/.ktx/secrets/"* +# then pass: --source-api-key-ref file:$PROJECT/.ktx/secrets/- +``` + +Alternatively, ensure the var is exported in every shell that runs `ktx`, +including the environment of the `ktx mcp` daemon. From 22ddf5524cbcf5863aa7b05dd7ac7a9cf3be659c Mon Sep 17 00:00:00 2001 From: Andrey Avtomonov Date: Mon, 1 Jun 2026 15:42:42 +0200 Subject: [PATCH 32/61] docs(readme): add launch video to README hero (#248) Add a clickable launch-video poster (linking to YouTube) directly after the intro note and before the architecture diagrams. GitHub Markdown can not embed a YouTube player, so the poster image links out instead. --- README.md | 6 ++++++ assets/launch-video-thumb.png | Bin 0 -> 138135 bytes 2 files changed, 6 insertions(+) create mode 100644 assets/launch-video-thumb.png diff --git a/README.md b/README.md index e235bab1..d44905d5 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,12 @@ business knowledge it builds and maintains for you. > Run **ktx** with your own LLM API keys or a **Claude Pro/Max** subscription. > No extra usage billing from **ktx**. +

+

Ingestion: ktx ingests databases, BI tools, modeling code, and docs through its context engine (source connectors, context builder, reconciliation, validation) into wiki Markdown and semantic-layer YAML

diff --git a/assets/launch-video-thumb.png b/assets/launch-video-thumb.png new file mode 100644 index 0000000000000000000000000000000000000000..c7505732586c241341ffb2b052bc2f035575e540 GIT binary patch literal 138135 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

+ + Watch the ktx launch video (1:56) + +