diff --git a/.gitignore b/.gitignore index 935c404..e77beed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules/ .pnpm-store/ dist/ +lib/ *.log .env .DS_Store diff --git a/README.md b/README.md index c248c18..38e5dca 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ # OpenClaw Memory (PowerMem) Plugin -This plugin lets [OpenClaw](https://github.com/openclaw/openclaw) use long-term memory via [PowerMem](https://github.com/oceanbase/powermem): intelligent extraction, Ebbinghaus forgetting curve, multi-agent isolation. +This plugin lets [OpenClaw](https://github.com/openclaw/openclaw) use long-term memory via [PowerMem](https://github.com/oceanbase/powermem): intelligent extraction, Ebbinghaus forgetting curve, multi-agent isolation. Supports HTTP v2 (per-request config + agent memory sharing), LLM-based experience extraction, and optional dual-write to local SQLite. **Default:** **CLI mode** — the plugin runs `pmem` locally (no `powermem-server`). Use **HTTP mode** when you already run a shared PowerMem API (teams / enterprise). @@ -185,13 +185,13 @@ openclaw plugins install -l /path/to/memory-powermem **Note:** Running `npm i memory-powermem` in a Node project only adds the package to that project’s `node_modules`; it does **not** register the plugin with OpenClaw. To use this as an OpenClaw plugin, you must run `openclaw plugins install memory-powermem` (or install from a path as above), then restart the gateway. -After install, run `openclaw plugins list` and confirm `memory-powermem` is listed. With **no** `plugins.entries["memory-powermem"].config`, the plugin uses **defaults**: `mode: "cli"`, `envFile` under `~/.openclaw/powermem/powermem.env`, `pmemPath: "pmem"`, plus `autoCapture` / `autoRecall` / `inferOnAdd` enabled. Ensure `pmem` is on PATH (or set `pmemPath`) and the env file exists and is valid. +After install, run `openclaw plugins list` and confirm `memory-powermem` is listed. With **no** `plugins.entries["memory-powermem"].config`, the plugin uses **defaults**: `mode: "cli"`, `pmemPath: "bundled"` (npm `powermem` from plugin dependencies), `useOpenClawModel: true` (SQLite under OpenClaw state + LLM from `agents.defaults.model`), plus `autoCapture` / `autoRecall` / `inferOnAdd` enabled. No separate `powermem.env` is required unless you opt out of OpenClaw model injection. --- ## Step 3: Configure OpenClaw (optional) -If you use **CLI mode** with the default paths and `pmem` on PATH, you can skip this step. Customize for HTTP, a different URL/API key, or a non-default `envFile` / `pmemPath`. +If you use **CLI mode** with defaults (`bundled` + OpenClaw model injection), you can skip this step. Customize for HTTP, a different URL/API key, Python `pmem` (`pmemPath: "auto"` or an absolute path), or a `powermem` `.env` via `envFile`. **CLI (default):** @@ -205,7 +205,7 @@ If you use **CLI mode** with the default paths and `pmem` on PATH, you can skip "config": { "mode": "cli", "envFile": "/home/you/.openclaw/powermem/powermem.env", - "pmemPath": "pmem", + "pmemPath": "bundled", "autoCapture": true, "autoRecall": true, "inferOnAdd": true @@ -222,15 +222,19 @@ If you use **CLI mode** with the default paths and `pmem` on PATH, you can skip "config": { "mode": "http", "baseUrl": "http://localhost:8000", + "httpApiVersion": "v2", + "requestConfig": { "memory_db": { "host": "db-host", "port": 2881 } }, "autoCapture": true, "autoRecall": true, + "autoExperience": true, + "experienceRecall": true, "inferOnAdd": true } ``` Notes: -- **CLI (default):** You may omit `mode` and use CLI when `baseUrl` is empty; use `envFile` + `pmemPath`. +- **CLI (default):** You may omit `mode` and use CLI when `baseUrl` is empty. Default `pmemPath` is `bundled` (npm CLI). Use `envFile` and/or `pmemPath` when you need a custom setup. - **HTTP:** When `mode` is `http`, `baseUrl` is required; if you set `baseUrl` without `mode`, the plugin treats it as HTTP. Do **not** append `/api/v1` to `baseUrl`. If the server uses API key auth, add `"apiKey"`. - **Restart the OpenClaw gateway** (or Mac menubar app) after changing config. @@ -283,16 +287,32 @@ After installing, uninstalling, or changing config, restart the OpenClaw gateway | Option | Required | Description | |---------------|----------|-------------| -| `mode` | No | Backend: `"cli"` (default) or `"http"`. If omitted, non-empty `baseUrl` implies `http`. | -| `baseUrl` | Yes (http) | PowerMem API base URL when `mode` is `http`, e.g. `http://localhost:8000`, no `/api/v1` suffix. | -| `apiKey` | No | Set when PowerMem server has API key authentication enabled (http mode). | -| `envFile` | No | CLI: path to PowerMem `.env` (default when using plugin defaults: `~/.openclaw/powermem/powermem.env`). | -| `pmemPath` | No | CLI: path to `pmem` executable; default `pmem`. | -| `userId` | No | User isolation (multi-user); default `openclaw-user`. | -| `agentId` | No | Agent isolation (multi-agent); default `openclaw-agent`. | -| `autoCapture` | No | Auto-store from conversations after agent ends; default `true`. | -| `autoRecall` | No | Auto-inject relevant memories before agent starts; default `true`. | -| `inferOnAdd` | No | Use PowerMem intelligent extraction when adding; default `true`. | +| `mode` | No | Backend: `"cli"` (default) or `"http"`. If omitted, non-empty `baseUrl` implies `http`. | +| `baseUrl` | Yes (http) | PowerMem API base URL when `mode` is `http`, e.g. `http://localhost:8000`, no `/api/v1` suffix. | +| `apiKey` | No | Set when PowerMem server has API key authentication enabled (http mode). | +| `httpApiVersion` | No | HTTP API version: `"v1"` (default) or `"v2"`. | +| `requestConfig` | No | HTTP v2 only: forwarded as `config` in each request (e.g. `memory_db` settings). | +| `envFile` | No | CLI: path to PowerMem `.env` (default when using plugin defaults: `~/.openclaw/powermem/powermem.env`). | +| `pmemPath` | No | CLI: `bundled` (default), `auto`, or path/command for `pmem`. | +| `userId` | No | User isolation (multi-user). If omitted or set to `"auto"`, a stable ID is generated and stored in `/powermem/identity.json`. | +| `agentId` | No | Agent isolation (multi-agent). If omitted or set to `"auto"`, a stable ID is generated and stored in `/powermem/identity.json`. | +| `autoCapture` | No | Auto-store from conversations after agent ends; default `true`. | +| `autoRecall` | No | Auto-inject relevant memories before agent starts; default `true`. | +| `autoExperience` | No | Auto-extract procedural experiences via LLM; default `true`. | +| `experienceRecall` | No | Include experiences in recall results; default `true`. | +| `inferOnAdd` | No | Use PowerMem intelligent extraction when adding; default `true`. | +| `dualWrite` | No | HTTP only: write to remote + local SQLite and queue failed writes. | +| `localDbPath` | No | Local SQLite path for `dualWrite`. | +| `localUserId` | No | Local namespace for `dualWrite` (defaults to `userId`). | +| `localAgentId` | No | Local namespace for `dualWrite` (defaults to `agentId`). | +| `syncOnResume` | No | Whether to sync pending writes on startup; default `true`. | +| `syncBatchSize` | No | Pending sync batch size; default `50`. | +| `syncMinIntervalMs` | No | Minimum interval between sync attempts; default `5000`. | +| `syncBaseDelayMs` | No | Base delay for retry backoff; default `5000`. | +| `syncMaxDelayMs` | No | Max delay for retry backoff; default `60000`. | +| `syncMaxRetries` | No | Max retry count per pending item; default `10`. | + +**Memory partitioning and sharing:** Use `userId` / `agentId` for logical isolation. In HTTP v2, `agent_memory_share` supports cross-agent sharing within the same `userId`; use `cross_scope_share` when you need to copy memories across both `userId` and `agentId` scopes. **Auto-capture:** When a session ends, this round’s user/assistant text is sent to PowerMem (`infer: true`) for extraction and storage. At most 3 items per round, each up to about 6000 characters. @@ -305,6 +325,13 @@ Exposed to OpenClaw agents: - **memory_recall** — Search long-term memories by query. - **memory_store** — Store one memory (optional intelligent extraction on write). - **memory_forget** — Delete by memory ID or by search query. +- **experience_store** — Store a procedural experience. +- **experience_recall** — Search stored experiences. +- **agent_memory_add** — Add memory to another agent (HTTP v2 only). +- **agent_memory_list** — List an agent’s memories (HTTP v2 only). +- **agent_memory_share** — Share memories across agents (HTTP v2 only). +- **agent_memory_shared** — List memories shared with an agent (HTTP v2 only). +- **cross_scope_share** — Copy memories across `userId`/`agentId` scopes (HTTP v2 only). Parameters: `fromUserId`, `fromAgentId`, `toUserId`, `toAgentId`, `query`; optional `limit`, `scoreThreshold`, `inferOnTarget`. --- @@ -320,7 +347,7 @@ Exposed to OpenClaw agents: **1. `openclaw ltm health` fails or cannot connect** -- **CLI:** `pmem` on PATH or correct `pmemPath`; valid `.env` at `envFile`. +- **CLI:** npm `powermem` installed with the plugin (`bundled`), or correct `pmemPath`; optional `.env` at `envFile` if not using OpenClaw model injection. - **HTTP:** PowerMem is running (HTTP server in a terminal, or Docker); `baseUrl` is correct (e.g. `http://localhost:8000`; watch for `127.0.0.1` vs `localhost` mismatches). - Remote server: use the host IP or hostname instead of `localhost`. diff --git a/README_CN.md b/README_CN.md index 8456c71..5b4b579 100644 --- a/README_CN.md +++ b/README_CN.md @@ -8,7 +8,7 @@ # OpenClaw Memory (PowerMem) 插件 -本插件让 [OpenClaw](https://github.com/openclaw/openclaw) 通过 [PowerMem](https://github.com/oceanbase/powermem) 使用长期记忆:智能抽取、艾宾浩斯遗忘曲线、多 Agent 隔离。 +本插件让 [OpenClaw](https://github.com/openclaw/openclaw) 通过 [PowerMem](https://github.com/oceanbase/powermem) 使用长期记忆:智能抽取、艾宾浩斯遗忘曲线、多 Agent 隔离。支持 HTTP v2(按请求配置 + 代理共享)、LLM 经验提炼与本地 SQLite 双写。 **默认:CLI 模式** — 插件在本机执行 `pmem`,无需 `powermem-server`。**HTTP 模式** 适合已有共享 PowerMem API 的场景(团队 / 企业)。 @@ -186,13 +186,13 @@ openclaw plugins install -l /path/to/memory-powermem **说明:** 在某个 Node 项目里执行 `npm i memory-powermem` 只会把包装进该项目的 `node_modules`,**不会**在 OpenClaw 里注册插件。若要在 OpenClaw 里使用本插件,必须执行 `openclaw plugins install memory-powermem`(或按上面用本地路径安装),再重启 gateway。 -安装成功后,可用 `openclaw plugins list` 确认能看到 `memory-powermem`。若未写 `plugins.entries["memory-powermem"].config`,插件 **默认**:`mode: "cli"`、`envFile` 为 `~/.openclaw/powermem/powermem.env`、`pmemPath: "pmem"`,并开启 `autoCapture`、`autoRecall`、`inferOnAdd`。请确保 `pmem` 在 PATH 上(或配置 `pmemPath`),且上述 `.env` 有效。 +安装成功后,可用 `openclaw plugins list` 确认能看到 `memory-powermem`。若未写 `plugins.entries["memory-powermem"].config`,插件 **默认**:`mode: "cli"`、`pmemPath: "bundled"`(优先插件旁的 npm `powermem`,否则用 PATH 上的 `pmem`)、`useOpenClawModel: true`(SQLite 在 OpenClaw 状态目录 + 从 `agents.defaults.model` 注入 LLM),并开启 `autoCapture`、`autoRecall`、`inferOnAdd`。若不使用 OpenClaw 注入模型,再准备 `powermem` 的 `.env`(`envFile`)。 --- ## 第三步:配置 OpenClaw(可选) -若使用 **CLI 默认路径** 且 `pmem` 已在 PATH,可跳过。需要 HTTP、改 URL/API Key、或自定义 `envFile` / `pmemPath` 时再改配置。 +若使用 **CLI 默认**(`bundled` + OpenClaw 模型注入),可跳过。需要 HTTP、改 URL/API Key、使用 Python 版 `pmem`(`pmemPath: "auto"` 或绝对路径)、或通过 `envFile` 时再改配置。 **CLI(默认):** @@ -206,7 +206,7 @@ openclaw plugins install -l /path/to/memory-powermem "config": { "mode": "cli", "envFile": "/home/you/.openclaw/powermem/powermem.env", - "pmemPath": "pmem", + "pmemPath": "bundled", "autoCapture": true, "autoRecall": true, "inferOnAdd": true @@ -223,15 +223,19 @@ openclaw plugins install -l /path/to/memory-powermem "config": { "mode": "http", "baseUrl": "http://localhost:8000", + "httpApiVersion": "v2", + "requestConfig": { "memory_db": { "host": "db-host", "port": 2881 } }, "autoCapture": true, "autoRecall": true, + "autoExperience": true, + "experienceRecall": true, "inferOnAdd": true } ``` 说明: -- **CLI(默认):** 可不写 `mode` 且 `baseUrl` 为空时走 CLI;使用 `envFile` + `pmemPath`。 +- **CLI(默认):** 可不写 `mode` 且 `baseUrl` 为空时走 CLI。默认 `pmemPath` 为 `bundled`(npm CLI)。需要时再配 `envFile` / `pmemPath`。 - **HTTP:** `mode` 为 `http` 时必须配置 `baseUrl`;若只写 `baseUrl` 不写 `mode`,插件会按 HTTP 处理。**不要**在 `baseUrl` 上加 `/api/v1`。若服务开了 API Key,加 `"apiKey"`。 - 改完配置后**重启 OpenClaw gateway**(或 Mac 菜单栏应用)。 @@ -284,16 +288,32 @@ openclaw ltm search "咖啡" | 选项 | 必填 | 说明 | |---------------|------|------| -| `mode` | 否 | 后端:`"cli"`(默认)或 `"http"`。不写 `mode` 但填了 `baseUrl` 时按 HTTP 处理。 | -| `baseUrl` | 是(http) | `mode` 为 `http` 时必填,PowerMem API 根地址,如 `http://localhost:8000`,不要带 `/api/v1`。 | -| `apiKey` | 否 | PowerMem 开启 API Key 鉴权时填写(http 模式)。 | -| `envFile` | 否 | CLI:PowerMem `.env`;插件默认约定 `~/.openclaw/powermem/powermem.env`。 | -| `pmemPath` | 否 | CLI 模式:`pmem` 可执行路径,默认 `pmem`。 | -| `userId` | 否 | 用于多用户隔离,默认 `openclaw-user`。 | -| `agentId` | 否 | 用于多 Agent 隔离,默认 `openclaw-agent`。 | -| `autoCapture` | 否 | 会话结束后是否自动把对话交给 PowerMem 抽取记忆,默认 `true`。 | -| `autoRecall` | 否 | 会话开始前是否自动注入相关记忆,默认 `true`。 | -| `inferOnAdd` | 否 | 写入时是否用 PowerMem 智能抽取,默认 `true`。 | +| `mode` | 否 | 后端:`"cli"`(默认)或 `"http"`。不写 `mode` 但填了 `baseUrl` 时按 HTTP 处理。 | +| `baseUrl` | 是(http) | `mode` 为 `http` 时必填,PowerMem API 根地址,如 `http://localhost:8000`,不要带 `/api/v1`。 | +| `apiKey` | 否 | PowerMem 开启 API Key 鉴权时填写(http 模式)。 | +| `httpApiVersion` | 否 | HTTP 版本:`"v1"`(默认)或 `"v2"`。 | +| `requestConfig` | 否 | HTTP v2 专用:按请求透传 `config`(如 `memory_db`)。 | +| `envFile` | 否 | CLI:PowerMem `.env`;插件默认约定 `~/.openclaw/powermem/powermem.env`。 | +| `pmemPath` | 否 | CLI:`bundled`(默认)、`auto` 或 `pmem` 的路径/命令。 | +| `userId` | 否 | 用于多用户隔离。未填或为 `"auto"` 时自动生成并保存到 `/powermem/identity.json`。 | +| `agentId` | 否 | 用于多 Agent 隔离。未填或为 `"auto"` 时自动生成并保存到 `/powermem/identity.json`。 | +| `autoCapture` | 否 | 会话结束后是否自动把对话交给 PowerMem 抽取记忆,默认 `true`。 | +| `autoRecall` | 否 | 会话开始前是否自动注入相关记忆,默认 `true`。 | +| `autoExperience` | 否 | LLM 自动提炼经验,默认 `true`。 | +| `experienceRecall` | 否 | 召回结果是否包含经验,默认 `true`。 | +| `inferOnAdd` | 否 | 写入时是否用 PowerMem 智能抽取,默认 `true`。 | +| `dualWrite` | 否 | 仅 HTTP:远端 + 本地 SQLite 双写,远端失败自动排队补传。 | +| `localDbPath` | 否 | 本地 SQLite 路径(`dualWrite`)。 | +| `localUserId` | 否 | 本地命名空间(`dualWrite`,默认 `userId`)。 | +| `localAgentId` | 否 | 本地命名空间(`dualWrite`,默认 `agentId`)。 | +| `syncOnResume` | 否 | 是否启动时补传,默认 `true`。 | +| `syncBatchSize` | 否 | 每批补传数量,默认 `50`。 | +| `syncMinIntervalMs` | 否 | 补传最小间隔,默认 `5000`。 | +| `syncBaseDelayMs` | 否 | 重试基础延迟,默认 `5000`。 | +| `syncMaxDelayMs` | 否 | 重试最大延迟,默认 `60000`。 | +| `syncMaxRetries` | 否 | 单条最大重试次数,默认 `10`。 | + +**记忆划分与分享:** 建议用 `userId` / `agentId` 做逻辑隔离;HTTP v2 可用 `agent_memory_share` 在同一 `userId` 下做跨 Agent 共享。若需跨 `userId` + `agentId`,可用 `cross_scope_share` 按 `query` 检索源记忆并复制到目标命名空间。 **自动抓取**:会话结束时,会把本轮用户/助手文本发给 PowerMem(`infer: true`),由 PowerMem 抽取并落库。每轮最多 3 条,每条约 6000 字符以内。 @@ -306,6 +326,13 @@ openclaw ltm search "咖啡" - **memory_recall** — 按查询搜索长期记忆 - **memory_store** — 写入一条记忆(可选是否智能抽取) - **memory_forget** — 按记忆 ID 或按搜索条件删除 +- **experience_store** — 写入经验 +- **experience_recall** — 查询经验 +- **agent_memory_add** — 给其它 Agent 增加记忆(HTTP v2) +- **agent_memory_list** — 列出 Agent 记忆(HTTP v2) +- **agent_memory_share** — 共享 Agent 记忆(HTTP v2) +- **agent_memory_shared** — 列出共享记忆(HTTP v2) +- **cross_scope_share** — 跨 `userId` / `agentId` 复制共享记忆(HTTP v2)。参数:`fromUserId`、`fromAgentId`、`toUserId`、`toAgentId`、`query`,可选 `limit`、`scoreThreshold`、`inferOnTarget`。 --- @@ -321,7 +348,7 @@ openclaw ltm search "咖啡" **1. `openclaw ltm health` 报错连不上** -- **CLI:** `pmem` 在 PATH 或 `pmemPath` 正确;`envFile` 指向有效 `.env`。 +- **CLI:** 插件已安装 npm `powermem`(`bundled`),或 `pmemPath` 正确;未用 OpenClaw 注入时再保证 `envFile`。 - **HTTP:** PowerMem 已启动(方式 A 终端或 Docker);`baseUrl` 正确(本机常用 `http://localhost:8000`,注意与 `127.0.0.1` 一致性问题)。 - 若 OpenClaw 和 PowerMem 不在同一台机器,把 `localhost` 改成 PowerMem 所在机器的 IP 或域名。 diff --git a/config.ts b/config.ts deleted file mode 100644 index cde55d2..0000000 --- a/config.ts +++ /dev/null @@ -1,194 +0,0 @@ -/** - * PowerMem memory plugin configuration. - * Validates baseUrl, optional apiKey, and user/agent mapping. - */ - -import { homedir } from "node:os"; -import { join } from "node:path"; - -function assertAllowedKeys( - value: Record, - allowed: string[], - label: string, -) { - const unknown = Object.keys(value).filter((key) => !allowed.includes(key)); - if (unknown.length === 0) return; - throw new Error(`${label} has unknown keys: ${unknown.join(", ")}`); -} - -function resolveEnvVars(value: string): string { - return value.replace(/\$\{([^}]+)\}/g, (_, envVar) => { - const envValue = process.env[envVar]; - if (!envValue) { - throw new Error(`Environment variable ${envVar} is not set`); - } - return envValue; - }); -} - -export type PowerMemMode = "http" | "cli"; - -export type PowerMemConfig = { - mode: PowerMemMode; - baseUrl: string; - apiKey?: string; - /** CLI mode: path to .env (optional; pmem discovers if omitted). */ - envFile?: string; - /** CLI mode: path to pmem binary (default "pmem"). */ - pmemPath?: string; - /** - * When true (default), inject LLM/embedding from OpenClaw gateway config into `pmem` - * (overrides the same keys from an optional .env file). SQLite defaults live under the OpenClaw state dir. - */ - useOpenClawModel?: boolean; - userId?: string; - agentId?: string; - /** Max memories to return in recall / inject in auto-recall. Default 5. */ - recallLimit?: number; - /** Min score (0–1) for recall; memories below are filtered. Default 0. */ - recallScoreThreshold?: number; - autoCapture: boolean; - autoRecall: boolean; - inferOnAdd: boolean; -}; - -const DEFAULT_RECALL_LIMIT = 5; -const DEFAULT_RECALL_SCORE_THRESHOLD = 0; - -const ALLOWED_KEYS = [ - "mode", - "baseUrl", - "apiKey", - "envFile", - "pmemPath", - "useOpenClawModel", - "userId", - "agentId", - "recallLimit", - "recallScoreThreshold", - "autoCapture", - "autoRecall", - "inferOnAdd", -] as const; - -export const powerMemConfigSchema = { - parse(value: unknown): PowerMemConfig { - if (!value || typeof value !== "object" || Array.isArray(value)) { - throw new Error("memory-powermem config required"); - } - const cfg = value as Record; - assertAllowedKeys(cfg, [...ALLOWED_KEYS], "memory-powermem config"); - - const modeExplicit = - cfg.mode === "cli" || cfg.mode === "http" ? cfg.mode : undefined; - const baseUrlForInfer = - typeof cfg.baseUrl === "string" ? cfg.baseUrl.trim() : ""; - const mode = - modeExplicit ?? (baseUrlForInfer ? "http" : "cli"); - - let baseUrl = ""; - let apiKey: string | undefined; - if (mode === "http") { - const baseUrlRaw = cfg.baseUrl; - if (typeof baseUrlRaw !== "string" || !baseUrlRaw.trim()) { - throw new Error("memory-powermem baseUrl is required when mode is http"); - } - baseUrl = resolveEnvVars(baseUrlRaw.trim()).replace(/\/+$/, ""); - const apiKeyRaw = cfg.apiKey; - apiKey = - typeof apiKeyRaw === "string" && apiKeyRaw.trim() - ? resolveEnvVars(apiKeyRaw.trim()) - : undefined; - } - - const envFileRaw = cfg.envFile; - const envFile = - typeof envFileRaw === "string" && envFileRaw.trim() - ? envFileRaw.trim() - : undefined; - - const pmemPathRaw = cfg.pmemPath; - const pmemPath = - typeof pmemPathRaw === "string" && pmemPathRaw.trim() - ? pmemPathRaw.trim() - : "pmem"; - - return { - mode, - baseUrl, - apiKey, - envFile, - pmemPath, - useOpenClawModel: cfg.useOpenClawModel !== false, - userId: - typeof cfg.userId === "string" && cfg.userId.trim() - ? cfg.userId.trim() - : undefined, - agentId: - typeof cfg.agentId === "string" && cfg.agentId.trim() - ? cfg.agentId.trim() - : undefined, - recallLimit: toRecallLimit(cfg.recallLimit), - recallScoreThreshold: toRecallScoreThreshold(cfg.recallScoreThreshold), - autoCapture: cfg.autoCapture !== false, - autoRecall: cfg.autoRecall !== false, - inferOnAdd: cfg.inferOnAdd !== false, - }; - }, -}; - -function toRecallLimit(v: unknown): number { - if (typeof v === "number" && Number.isFinite(v) && v >= 1) { - return Math.min(100, Math.floor(v)); - } - if (typeof v === "string" && /^\d+$/.test(v)) { - const n = parseInt(v, 10); - return n >= 1 ? Math.min(100, n) : DEFAULT_RECALL_LIMIT; - } - return DEFAULT_RECALL_LIMIT; -} - -function toRecallScoreThreshold(v: unknown): number { - if (typeof v === "number" && Number.isFinite(v)) { - return Math.max(0, Math.min(1, v)); - } - if (typeof v === "string" && v.trim() !== "") { - const n = Number(v); - if (Number.isFinite(n)) return Math.max(0, Math.min(1, n)); - } - return DEFAULT_RECALL_SCORE_THRESHOLD; -} - -/** Default user/agent IDs when not configured (single-tenant style). */ -export const DEFAULT_USER_ID = "openclaw-user"; -export const DEFAULT_AGENT_ID = "openclaw-agent"; - -/** Canonical PowerMem `.env` path for consumer (CLI) setups; matches install.sh. */ -export function defaultConsumerPowermemEnvPath(): string { - return join(homedir(), ".openclaw", "powermem", "powermem.env"); -} - -/** - * Default plugin config when openclaw.json has no plugins.entries["memory-powermem"].config. - * Consumer default: CLI, no .env required — SQLite under OpenClaw state dir + LLM from OpenClaw `agents.defaults.model`. - * Optional: set `envFile` to merge a powermem .env under OpenClaw-derived vars. - * Enterprise / shared server: set `mode: "http"` and `baseUrl`. - */ -export const DEFAULT_PLUGIN_CONFIG: PowerMemConfig = { - mode: "cli", - baseUrl: "", - envFile: undefined, - pmemPath: "pmem", - useOpenClawModel: true, - autoCapture: true, - autoRecall: true, - inferOnAdd: true, -}; - -export function resolveUserId(cfg: PowerMemConfig): string { - return cfg.userId ?? DEFAULT_USER_ID; -} - -export function resolveAgentId(cfg: PowerMemConfig): string { - return cfg.agentId ?? DEFAULT_AGENT_ID; -} diff --git a/index.ts b/index.ts deleted file mode 100644 index 98611c9..0000000 --- a/index.ts +++ /dev/null @@ -1,579 +0,0 @@ -/** - * OpenClaw Memory (PowerMem) Plugin - * - * Long-term memory via PowerMem: intelligent extraction, Ebbinghaus - * forgetting curve, multi-agent isolation. Supports two backends: - * - CLI (default): runs pmem locally; SQLite + LLM from OpenClaw state / agents.defaults.model (optional .env). - * - HTTP: powermem-server (e.g. --port 8000) for shared / enterprise setups. - */ - -import { Type } from "@sinclair/typebox"; -import type { - OpenClawPluginApi, - OpenClawPluginCliContext, -} from "openclaw/plugin-sdk/memory-core"; -import type { OpenClawPluginServiceContext } from "openclaw/plugin-sdk"; - -import { - powerMemConfigSchema, - DEFAULT_PLUGIN_CONFIG, - resolveUserId, - resolveAgentId, - type PowerMemConfig, -} from "./config.js"; -import { homedir } from "node:os"; -import { join } from "node:path"; - -import { PowerMemClient } from "./client.js"; -import { PowerMemCLIClient } from "./client-cli.js"; -import { - buildDefaultSqlitePowermemEnv, - buildPowermemCliProcessEnv, -} from "./openclaw-powermem-env.js"; - -type GatewayApi = OpenClawPluginApi & { - config?: unknown; - runtime?: { - state?: { resolveStateDir?: (env?: NodeJS.ProcessEnv) => string }; - modelAuth?: { - resolveApiKeyForProvider?: (params: { - provider: string; - cfg?: unknown; - }) => Promise<{ apiKey?: string }>; - }; - }; -}; - -function resolveOpenClawStateDir(api: GatewayApi): string { - const fn = api.runtime?.state?.resolveStateDir; - if (typeof fn === "function") { - try { - return fn(process.env); - } catch { - /* ignore */ - } - } - return join(homedir(), ".openclaw"); -} - -// ============================================================================ -// Plugin Definition -// ============================================================================ - -const memoryPlugin = { - id: "memory-powermem", - name: "Memory (PowerMem)", - description: - "PowerMem-backed long-term memory (intelligent extraction, forgetting curve). Default: local CLI (pmem); optional HTTP server for shared deployments.", - kind: "memory" as const, - configSchema: powerMemConfigSchema, - - register(api: OpenClawPluginApi) { - const gw = api as GatewayApi; - const raw = api.pluginConfig; - const toParse = - raw && - typeof raw === "object" && - !Array.isArray(raw) && - Object.keys(raw).length > 0 - ? { ...DEFAULT_PLUGIN_CONFIG, ...raw } - : DEFAULT_PLUGIN_CONFIG; - const cfg = powerMemConfigSchema.parse(toParse) as PowerMemConfig; - const userId = resolveUserId(cfg); - const agentId = resolveAgentId(cfg); - const stateDir = resolveOpenClawStateDir(gw); - const buildProcessEnv = - cfg.mode === "cli" - ? cfg.useOpenClawModel !== false - ? () => - buildPowermemCliProcessEnv({ - openclawConfig: gw.config, - stateDir, - resolveProviderAuth: async (provider) => { - const fn = gw.runtime?.modelAuth?.resolveApiKeyForProvider; - if (typeof fn !== "function") return {}; - try { - return await fn({ provider, cfg: gw.config }); - } catch { - return {}; - } - }, - warn: (m) => api.logger.warn(m), - }) - : () => Promise.resolve(buildDefaultSqlitePowermemEnv(stateDir)) - : undefined; - const client = - cfg.mode === "cli" - ? PowerMemCLIClient.fromConfig(cfg, userId, agentId, { buildProcessEnv }) - : PowerMemClient.fromConfig(cfg, userId, agentId); - const modeLabel = cfg.mode === "cli" ? `cli (${cfg.pmemPath ?? "pmem"})` : cfg.baseUrl; - - api.logger.info( - `memory-powermem: plugin registered (mode: ${cfg.mode}, ${modeLabel}, user: ${userId}, agent: ${agentId})`, - ); - - // ======================================================================== - // Tools - // ======================================================================== - - api.registerTool( - { - name: "memory_recall", - label: "Memory Recall", - description: - "Search through long-term memories. Use when you need context about user preferences, past decisions, or previously discussed topics.", - parameters: Type.Object({ - query: Type.String({ description: "Search query" }), - limit: Type.Optional( - Type.Number({ description: "Max results (default: plugin recallLimit)" }), - ), - scoreThreshold: Type.Optional( - Type.Number({ description: "Min score 0–1 to include (default: plugin recallScoreThreshold)" }), - ), - }), - async execute(_toolCallId: string, params: Record) { - const limit = - typeof (params as { limit?: number }).limit === "number" - ? Math.max(1, Math.min(100, Math.floor((params as { limit: number }).limit))) - : cfg.recallLimit ?? 5; - const scoreThreshold = - typeof (params as { scoreThreshold?: number }).scoreThreshold === "number" - ? Math.max(0, Math.min(1, (params as { scoreThreshold: number }).scoreThreshold)) - : (cfg.recallScoreThreshold ?? 0); - const query = String((params as { query?: string }).query ?? ""); - - try { - const requestLimit = Math.min(100, Math.max(limit * 2, limit + 10)); - const raw = await client.search(query, requestLimit); - const results = raw - .filter((r) => (r.score ?? 0) >= scoreThreshold) - .slice(0, limit); - - if (results.length === 0) { - return { - content: [{ type: "text", text: "No relevant memories found." }], - details: { count: 0 }, - }; - } - - const text = results - .map( - (r, i) => - `${i + 1}. ${r.content} (${((r.score ?? 0) * 100).toFixed(0)}%)`, - ) - .join("\n"); - - const sanitizedResults = results.map((r) => ({ - id: String(r.memory_id), - text: r.content, - score: r.score, - })); - - return { - content: [ - { type: "text", text: `Found ${results.length} memories:\n\n${text}` }, - ], - details: { count: results.length, memories: sanitizedResults }, - }; - } catch (err) { - api.logger.warn(`memory-powermem: recall failed: ${String(err)}`); - return { - content: [ - { - type: "text", - text: `Memory search failed: ${err instanceof Error ? err.message : String(err)}`, - }, - ], - details: { error: String(err) }, - }; - } - }, - }, - { name: "memory_recall" }, - ); - - api.registerTool( - { - name: "memory_store", - label: "Memory Store", - description: - "Save important information in long-term memory. Use for preferences, facts, decisions.", - parameters: Type.Object({ - text: Type.String({ description: "Information to remember" }), - importance: Type.Optional( - Type.Number({ description: "Importance 0-1 (default: 0.7)" }), - ), - }), - async execute(_toolCallId: string, params: Record) { - const { text, importance = 0.7 } = params as { - text: string; - importance?: number; - }; - - try { - const created = await client.add(text, { - infer: cfg.inferOnAdd, - metadata: { importance }, - }); - - if (created.length === 0) { - return { - content: [{ type: "text", text: "Stored (no inferred items)." }], - details: { action: "created" }, - }; - } - - const summary = - created.length === 1 - ? created[0].content.slice(0, 80) - : `${created.length} items stored`; - return { - content: [ - { type: "text", text: `Stored: ${summary}${summary.length >= 80 ? "..." : ""}` }, - ], - details: { - action: "created", - count: created.length, - ids: created.map((c) => String(c.memory_id)), - }, - }; - } catch (err) { - api.logger.warn(`memory-powermem: store failed: ${String(err)}`); - return { - content: [ - { - type: "text", - text: `Failed to store memory: ${err instanceof Error ? err.message : String(err)}`, - }, - ], - details: { error: String(err) }, - }; - } - }, - }, - { name: "memory_store" }, - ); - - api.registerTool( - { - name: "memory_forget", - label: "Memory Forget", - description: "Delete specific memories. GDPR-compliant.", - parameters: Type.Object({ - query: Type.Optional(Type.String({ description: "Search to find memory" })), - memoryId: Type.Optional(Type.String({ description: "Specific memory ID" })), - }), - async execute(_toolCallId: string, params: Record) { - const { query, memoryId } = params as { query?: string; memoryId?: string }; - - try { - if (memoryId) { - await client.delete(memoryId); - return { - content: [{ type: "text", text: `Memory ${memoryId} forgotten.` }], - details: { action: "deleted", id: memoryId }, - }; - } - - if (query) { - const results = await client.search(query, 5); - if (results.length === 0) { - return { - content: [{ type: "text", text: "No matching memories found." }], - details: { found: 0 }, - }; - } - if (results.length === 1 && (results[0].score ?? 0) > 0.9) { - await client.delete(results[0].memory_id); - return { - content: [ - { - type: "text", - text: `Forgotten: "${results[0].content.slice(0, 60)}..."`, - }, - ], - details: { action: "deleted", id: String(results[0].memory_id) }, - }; - } - const list = results - .map( - (r) => - `- [${String(r.memory_id).slice(0, 8)}] ${r.content.slice(0, 60)}...`, - ) - .join("\n"); - return { - content: [ - { - type: "text", - text: `Found ${results.length} candidates. Specify memoryId:\n${list}`, - }, - ], - details: { - action: "candidates", - candidates: results.map((r) => ({ - id: String(r.memory_id), - text: r.content, - score: r.score, - })), - }, - }; - } - - return { - content: [{ type: "text", text: "Provide query or memoryId." }], - details: { error: "missing_param" }, - }; - } catch (err) { - api.logger.warn(`memory-powermem: forget failed: ${String(err)}`); - return { - content: [ - { - type: "text", - text: `Failed to forget: ${err instanceof Error ? err.message : String(err)}`, - }, - ], - details: { error: String(err) }, - }; - } - }, - }, - { name: "memory_forget" }, - ); - - // ======================================================================== - // CLI Commands - // ======================================================================== - - api.registerCli( - ({ program }: OpenClawPluginCliContext) => { - const ltm = program - .command("ltm") - .description("PowerMem long-term memory plugin commands"); - - ltm - .command("search") - .description("Search memories") - .argument("", "Search query") - .option("--limit ", "Max results", "5") - .action(async (...args: unknown[]) => { - const query = String(args[0] ?? ""); - const opts = (args[1] ?? {}) as { limit?: string }; - const limit = parseInt(opts.limit ?? "5", 10); - const results = await client.search(query, limit); - console.log(JSON.stringify(results, null, 2)); - }); - - ltm - .command("health") - .description("Check PowerMem server health") - .action(async () => { - try { - const h = await client.health(); - console.log("PowerMem:", h.status); - } catch (err) { - console.error("PowerMem health check failed:", err); - process.exitCode = 1; - } - }); - - ltm - .command("add") - .description("Manually add a memory (for testing or one-off storage)") - .argument("", "Content to store") - .action(async (...args: unknown[]) => { - const text = String(args[0] ?? ""); - try { - const created = await client.add(text.trim(), { infer: cfg.inferOnAdd }); - if (created.length === 0) { - console.log("Stored (no inferred items)."); - } else { - console.log(`Stored ${created.length} item(s):`, created.map((c) => c.memory_id)); - } - } catch (err) { - console.error("PowerMem add failed:", err); - process.exitCode = 1; - } - }); - }, - { commands: ["ltm"] }, - ); - - // ======================================================================== - // Lifecycle Hooks - // ======================================================================== - - const MEMORY_RECALL_GUIDANCE = - "## Long-term memory (PowerMem)\n" + - "When answering about past events, user preferences, people, or anything the user may have told you before: use the memory_recall tool to search long-term memory first, or use any already injected in this turn.\n"; - - function lastUserMessageText(messages: unknown[] | undefined): string { - if (!Array.isArray(messages) || messages.length === 0) return ""; - for (let i = messages.length - 1; i >= 0; i--) { - const msg = messages[i]; - if (!msg || typeof msg !== "object") continue; - const role = (msg as Record).role; - if (role !== "user") continue; - const content = (msg as Record).content; - if (typeof content === "string" && content.trim().length >= 5) return content.trim(); - if (Array.isArray(content)) { - for (const block of content) { - if ( - block && - typeof block === "object" && - (block as Record).type === "text" && - typeof (block as Record).text === "string" - ) { - const t = String((block as Record).text).trim(); - if (t.length >= 5) return t; - } - } - } - } - return ""; - } - - if (cfg.autoRecall) { - api.on("before_agent_start", async (event: unknown) => { - const e = event as { prompt: string; messages?: unknown[] }; - const query = - (typeof e.prompt === "string" && e.prompt.trim().length >= 5 - ? e.prompt.trim() - : lastUserMessageText(e.messages)) || ""; - if (query.length < 5) { - return { prependSystemContext: MEMORY_RECALL_GUIDANCE }; - } - - const recallLimit = Math.max(1, Math.min(100, cfg.recallLimit ?? 5)); - const scoreThreshold = Math.max(0, Math.min(1, cfg.recallScoreThreshold ?? 0)); - - try { - const requestLimit = Math.min(100, Math.max(recallLimit * 2, recallLimit + 10)); - const raw = await client.search(query, requestLimit); - const results = raw - .filter((r) => (r.score ?? 0) >= scoreThreshold) - .slice(0, recallLimit); - - const memoryContext = - results.length > 0 - ? results.map((r) => `- ${r.content}`).join("\n") - : ""; - if (results.length > 0) { - api.logger.info( - `memory-powermem: injecting ${results.length} memories into context`, - ); - } - return { - prependSystemContext: MEMORY_RECALL_GUIDANCE, - ...(memoryContext - ? { - prependContext: `\nThe following memories may be relevant to this conversation:\n${memoryContext}\n`, - } - : {}), - }; - } catch (err) { - api.logger.warn(`memory-powermem: recall failed: ${String(err)}`); - return { prependSystemContext: MEMORY_RECALL_GUIDANCE }; - } - }); - } - - if (cfg.autoCapture) { - api.on("agent_end", async (event: unknown) => { - const e = event as { messages: unknown[]; success: boolean; error?: string }; - if (!e.success || !e.messages || e.messages.length === 0) { - return; - } - - try { - const texts: string[] = []; - for (const msg of e.messages) { - if (!msg || typeof msg !== "object") continue; - const msgObj = msg as Record; - const role = msgObj.role; - if (role !== "user" && role !== "assistant") continue; - const content = msgObj.content; - if (typeof content === "string") { - texts.push(content); - continue; - } - if (Array.isArray(content)) { - for (const block of content) { - if ( - block && - typeof block === "object" && - "type" in block && - (block as Record).type === "text" && - "text" in block && - typeof (block as Record).text === "string" - ) { - texts.push((block as Record).text as string); - } - } - } - } - - const MIN_LEN = 10; - const MAX_CHUNK_LEN = 6000; - const MAX_CHUNKS_PER_SESSION = 3; - const sanitized = texts - .filter((t): t is string => typeof t === "string" && t.trim().length >= MIN_LEN) - .map((t) => t.trim()) - .filter( - (t) => - !t.includes("") && - !(t.startsWith("<") && t.includes("= MAX_CHUNKS_PER_SESSION) break; - chunks.push(combined.slice(i, i + MAX_CHUNK_LEN)); - } - - let stored = 0; - for (const chunk of chunks) { - const created = await client.add(chunk, { infer: cfg.inferOnAdd }); - stored += created.length; - } - if (stored > 0) { - api.logger.info(`memory-powermem: auto-captured ${stored} memories from conversation`); - } - } catch (err) { - api.logger.warn(`memory-powermem: capture failed: ${String(err)}`); - } - }); - } - - // ======================================================================== - // Service - // ======================================================================== - - api.registerService({ - id: "memory-powermem", - start: async (_ctx: OpenClawPluginServiceContext) => { - try { - const h = await client.health(); - const where = cfg.mode === "cli" ? `cli ${cfg.pmemPath ?? "pmem"}` : cfg.baseUrl; - api.logger.info( - `memory-powermem: initialized (${where}, health: ${h.status})`, - ); - } catch (err) { - const hint = - cfg.mode === "cli" - ? "is pmem on PATH? Check agents.defaults.model + provider keys in OpenClaw, or set envFile to a powermem .env" - : "is PowerMem server running?"; - api.logger.warn( - `memory-powermem: health check failed (${hint}): ${String(err)}`, - ); - } - }, - stop: (_ctx: OpenClawPluginServiceContext) => { - api.logger.info("memory-powermem: stopped"); - }, - }); - }, -}; - -export default memoryPlugin; diff --git a/install.sh b/install.sh index d4403d2..59a3c5b 100644 --- a/install.sh +++ b/install.sh @@ -27,7 +27,8 @@ SELECTED_MODE="cli" BASE_URL="http://localhost:8000" API_KEY="" ENV_FILE="" -PMEM_PATH="pmem" +# Default matches plugin: npm powermem-ts (package "powermem"); use "pmem" only for Python on PATH. +PMEM_PATH="bundled" POWMEM_DATA_DIR="" DEFAULT_POWMEM_ENV="" @@ -52,7 +53,7 @@ for arg in "$@"; do echo " or: bash install.sh [-y] [--workdir ]" echo "" echo "Options:" - echo " -y, --yes Non-interactive (defaults: cli, env ~/.openclaw/powermem/powermem.env)" + echo " -y, --yes Non-interactive (defaults: cli, bundled npm pmem, optional env template)" echo " --workdir OpenClaw config dir (default: ~/.openclaw)" echo " -h, --help Show this help" echo "" @@ -168,6 +169,7 @@ EOF select_mode_and_config() { if [[ "$INSTALL_YES" == "1" ]]; then SELECTED_MODE="cli" + PMEM_PATH="bundled" ENV_FILE="${DEFAULT_POWMEM_ENV}" seed_powermem_env_if_missing "${ENV_FILE}" return 0 @@ -180,8 +182,8 @@ select_mode_and_config() { read -r -p "Path to PowerMem .env [${DEFAULT_POWMEM_ENV}]: " _ef < /dev/tty || true ENV_FILE="${_ef:-${DEFAULT_POWMEM_ENV}}" seed_powermem_env_if_missing "${ENV_FILE}" - read -r -p "pmem binary path [pmem]: " _pmem < /dev/tty || true - PMEM_PATH="${_pmem:-pmem}" + read -r -p "pmem path [bundled] (bundled=npm powermem-ts; or absolute path to Python venv pmem): " _pmem < /dev/tty || true + PMEM_PATH="${_pmem:-bundled}" else SELECTED_MODE="http" ENV_FILE="" @@ -212,7 +214,7 @@ check_openclaw() { deploy_from_repo() { info "Deploying plugin from current directory..." mkdir -p "${PLUGIN_DEST}" - for f in index.ts config.ts client.ts client-cli.ts openclaw-powermem-env.ts openclaw.plugin.json package.json tsconfig.json .gitignore; do + for f in index.ts config.ts client.ts client-cli.ts resolve-powermem-cli.ts openclaw-powermem-env.ts openclaw.plugin.json package.json tsconfig.json .gitignore; do if [[ -f "$f" ]]; then cp "$f" "${PLUGIN_DEST}/" fi @@ -237,6 +239,7 @@ deploy_from_github() { "config.ts" "client.ts" "client-cli.ts" + "resolve-powermem-cli.ts" "openclaw-powermem-env.ts" "openclaw.plugin.json" "package.json" @@ -328,10 +331,12 @@ main() { echo " 2. openclaw gateway" echo " 3. openclaw ltm health" else - echo " 1. pip install powermem (venv recommended); put pmem on PATH when starting the gateway" - echo " 2. Edit LLM_* and EMBEDDING_* in: ${ENV_FILE:-$DEFAULT_POWMEM_ENV}" - echo " 3. openclaw gateway" - echo " 4. openclaw ltm health" + echo " 1. openclaw gateway (default CLI uses npm powermem-ts in the plugin dir; no pip required)" + echo " 2. openclaw ltm health" + echo " 3. Optional: with useOpenClawModel (default), you usually do NOT need to edit the seeded file:" + echo " ${ENV_FILE:-$DEFAULT_POWMEM_ENV}" + echo " Edit it only if you disable OpenClaw model injection or want extra PowerMem tuning." + echo " 4. Optional: use Python pmem instead → set plugins.entries.memory-powermem.config.pmemPath to your venv pmem." fi echo "" } diff --git a/openclaw.plugin.json b/openclaw.plugin.json index b961121..d1762d5 100644 --- a/openclaw.plugin.json +++ b/openclaw.plugin.json @@ -18,6 +18,24 @@ "placeholder": "", "help": "Optional; required if PowerMem server has authentication enabled (http mode only)" }, + "httpApiVersion": { + "label": "HTTP API version", + "placeholder": "v1", + "advanced": true, + "help": "HTTP mode: v1 (default) or v2. v2 enables per-request config and agent memory APIs." + }, + "requestTimeoutMs": { + "label": "Request timeout (ms)", + "placeholder": "30000", + "advanced": true, + "help": "Abort HTTP/CLI requests after this many milliseconds (0 = no timeout)" + }, + "requestConfig": { + "label": "Request config (v2)", + "placeholder": "", + "advanced": true, + "help": "HTTP v2 only: per-request PowerMem config object (same shape as auto_config())." + }, "envFile": { "label": "Env file path", "placeholder": "", @@ -26,9 +44,9 @@ }, "pmemPath": { "label": "pmem binary path", - "placeholder": "pmem", + "placeholder": "bundled", "advanced": true, - "help": "CLI mode: path to pmem (or powermem) executable. Default: pmem" + "help": "CLI mode: bundled (default) or auto = npm powermem next to this plugin if installed, else pmem on PATH; or absolute path / command name (e.g. Python venv pmem)" }, "userId": { "label": "User ID", @@ -54,6 +72,10 @@ "advanced": true, "help": "Min score (0–1); memories below are filtered out" }, + "walCapture": { + "label": "WAL Capture", + "help": "Incrementally capture key facts during conversations to prevent loss on crash/compaction" + }, "autoCapture": { "label": "Auto-Capture", "help": "Automatically store important information from conversations" @@ -62,10 +84,92 @@ "label": "Auto-Recall", "help": "Automatically inject relevant memories into context" }, + "autoExperience": { + "label": "Auto-Experience", + "help": "Automatically store session experiences at agent_end" + }, + "experienceRecall": { + "label": "Experience Recall", + "help": "Automatically inject relevant experiences into context" + }, "inferOnAdd": { "label": "Infer on Add", "help": "Use PowerMem intelligent extraction when adding (infer=true)" }, + "debugPerfLog": { + "label": "Debug performance logs", + "advanced": true, + "help": "Enable slow-path performance logs for key memory operations." + }, + "perfSlowMs": { + "label": "Perf slow threshold (ms)", + "advanced": true, + "placeholder": "800", + "help": "Only log performance entries slower than this threshold." + }, + "dualWrite": { + "label": "Dual write (HTTP + SQLite)", + "advanced": true, + "help": "When enabled, write to remote HTTP and local sqlite for failover and resync." + }, + "localDbPath": { + "label": "Local sqlite path", + "advanced": true, + "placeholder": "", + "help": "Local sqlite file path for dual-write. Default: /powermem/local-memories.sqlite" + }, + "localUserId": { + "label": "Local User ID", + "advanced": true, + "placeholder": "", + "help": "Override user_id for local sqlite storage (dual-write)" + }, + "localAgentId": { + "label": "Local Agent ID", + "advanced": true, + "placeholder": "", + "help": "Override agent_id for local sqlite storage (dual-write)" + }, + "syncOnResume": { + "label": "Sync pending writes", + "advanced": true, + "help": "When remote recovers, sync local pending writes (default true)" + }, + "syncBatchSize": { + "label": "Sync batch size", + "advanced": true, + "placeholder": "50", + "help": "Max pending writes per sync attempt" + }, + "syncMinIntervalMs": { + "label": "Sync min interval (ms)", + "advanced": true, + "placeholder": "5000", + "help": "Minimum interval between sync attempts" + }, + "syncBaseDelayMs": { + "label": "Sync base delay (ms)", + "advanced": true, + "placeholder": "5000", + "help": "Base backoff delay after a failed sync" + }, + "syncMaxDelayMs": { + "label": "Sync max delay (ms)", + "advanced": true, + "placeholder": "60000", + "help": "Maximum backoff delay after failures" + }, + "syncMaxRetries": { + "label": "Sync max retries", + "advanced": true, + "placeholder": "10", + "help": "Skip items after this many failed retries (0 = unlimited)" + }, + "localVector": { + "label": "Local vector search", + "advanced": true, + "help": "Optional local vector fallback for dual-write (OpenAI/Ollama compatible embeddings + sqlite-vec)." + }, "useOpenClawModel": { "label": "Use OpenClaw LLM for PowerMem", "advanced": true, @@ -79,15 +183,48 @@ "mode": { "type": "string", "enum": ["http", "cli"] }, "baseUrl": { "type": "string" }, "apiKey": { "type": "string" }, + "httpApiVersion": { "type": "string", "enum": ["v1", "v2"] }, + "requestTimeoutMs": { "type": "number" }, + "requestConfig": { "type": "object" }, "envFile": { "type": "string" }, "pmemPath": { "type": "string" }, "userId": { "type": "string" }, "agentId": { "type": "string" }, "recallLimit": { "type": "number" }, "recallScoreThreshold": { "type": "number" }, + "walCapture": { "type": "boolean" }, "autoCapture": { "type": "boolean" }, "autoRecall": { "type": "boolean" }, + "autoExperience": { "type": "boolean" }, + "experienceRecall": { "type": "boolean" }, "inferOnAdd": { "type": "boolean" }, + "debugPerfLog": { "type": "boolean" }, + "perfSlowMs": { "type": "number" }, + "dualWrite": { "type": "boolean" }, + "localDbPath": { "type": "string" }, + "localUserId": { "type": "string" }, + "localAgentId": { "type": "string" }, + "syncOnResume": { "type": "boolean" }, + "syncBatchSize": { "type": "number" }, + "syncMinIntervalMs": { "type": "number" }, + "syncBaseDelayMs": { "type": "number" }, + "syncMaxDelayMs": { "type": "number" }, + "syncMaxRetries": { "type": "number" }, + "localVector": { + "type": "object", + "additionalProperties": false, + "properties": { + "enabled": { "type": "boolean" }, + "provider": { "type": "string" }, + "model": { "type": "string" }, + "apiKey": { "type": "string" }, + "baseUrl": { "type": "string" }, + "headers": { + "type": "object", + "additionalProperties": { "type": "string" } + } + } + }, "useOpenClawModel": { "type": "boolean" } }, "required": [] diff --git a/package-lock.json b/package-lock.json index 7ac373c..63f0332 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,20 @@ { "name": "memory-powermem", - "version": "1.0.0", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "memory-powermem", - "version": "1.0.0", + "version": "0.4.0", "license": "Apache-2.0", "dependencies": { - "@sinclair/typebox": "^0.34.0" + "@langchain/openai": "^1.4.1", + "@mariozechner/pi-ai": "^0.67.2", + "@sinclair/typebox": "^0.34.0", + "better-sqlite3": "^12.9.0", + "powermem": "^0.1.1", + "sqlite-vec": "^0.1.9" }, "devDependencies": { "@types/node": "^22.0.0", @@ -25,231 +30,758 @@ } } }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, + "node_modules/@anthropic-ai/sdk": { + "version": "0.73.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.73.0.tgz", + "integrity": "sha512-URURVzhxXGJDGUGFunIOtBlSl7KWvZiAAKY/ttTkZAkXT9bTPqdk2eK0b8qqSxXpikh3QKPnPYpiyX98zf5ebw==", "license": "MIT", - "optional": true, - "os": [ - "aix" - ], + "dependencies": { + "json-schema-to-ts": "^3.1.1" + }, + "bin": { + "anthropic-ai-sdk": "bin/cli" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=16.0.0" } }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=14.0.0" } }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=14.0.0" } }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=14.0.0" } }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=16.0.0" } }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=14.0.0" } }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=14.0.0" } }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=14.0.0" } }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@aws-sdk/client-bedrock-runtime": { + "version": "3.1030.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.1030.0.tgz", + "integrity": "sha512-5Lnyx6mQPsIdld5Xr9FJqu8Hi9RVY6SgE8Rysmn4r3lRY2vNohNEu+gCtdXRDkkv/PgK9OnbA0sUPFU9rBRMYA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/credential-provider-node": "^3.972.30", + "@aws-sdk/eventstream-handler-node": "^3.972.13", + "@aws-sdk/middleware-eventstream": "^3.972.9", + "@aws-sdk/middleware-host-header": "^3.972.9", + "@aws-sdk/middleware-logger": "^3.972.9", + "@aws-sdk/middleware-recursion-detection": "^3.972.10", + "@aws-sdk/middleware-user-agent": "^3.972.29", + "@aws-sdk/middleware-websocket": "^3.972.15", + "@aws-sdk/region-config-resolver": "^3.972.11", + "@aws-sdk/token-providers": "3.1030.0", + "@aws-sdk/types": "^3.973.7", + "@aws-sdk/util-endpoints": "^3.996.6", + "@aws-sdk/util-user-agent-browser": "^3.972.9", + "@aws-sdk/util-user-agent-node": "^3.973.15", + "@smithy/config-resolver": "^4.4.14", + "@smithy/core": "^3.23.14", + "@smithy/eventstream-serde-browser": "^4.2.13", + "@smithy/eventstream-serde-config-resolver": "^4.3.13", + "@smithy/eventstream-serde-node": "^4.2.13", + "@smithy/fetch-http-handler": "^5.3.16", + "@smithy/hash-node": "^4.2.13", + "@smithy/invalid-dependency": "^4.2.13", + "@smithy/middleware-content-length": "^4.2.13", + "@smithy/middleware-endpoint": "^4.4.29", + "@smithy/middleware-retry": "^4.5.0", + "@smithy/middleware-serde": "^4.2.17", + "@smithy/middleware-stack": "^4.2.13", + "@smithy/node-config-provider": "^4.3.13", + "@smithy/node-http-handler": "^4.5.2", + "@smithy/protocol-http": "^5.3.13", + "@smithy/smithy-client": "^4.12.9", + "@smithy/types": "^4.14.0", + "@smithy/url-parser": "^4.2.13", + "@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.45", + "@smithy/util-defaults-mode-node": "^4.2.49", + "@smithy/util-endpoints": "^3.3.4", + "@smithy/util-middleware": "^4.2.13", + "@smithy/util-retry": "^4.3.0", + "@smithy/util-stream": "^4.5.22", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=20.0.0" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@aws-sdk/core": { + "version": "3.973.27", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.973.27.tgz", + "integrity": "sha512-CUZ5m8hwMCH6OYI4Li/WgMfIEx10Q2PLI9Y3XOUTPGZJ53aZ0007jCv+X/ywsaERyKPdw5MRZWk877roQksQ4A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@aws-sdk/xml-builder": "^3.972.17", + "@smithy/core": "^3.23.14", + "@smithy/node-config-provider": "^4.3.13", + "@smithy/property-provider": "^4.2.13", + "@smithy/protocol-http": "^5.3.13", + "@smithy/signature-v4": "^5.3.13", + "@smithy/smithy-client": "^4.12.9", + "@smithy/types": "^4.14.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-middleware": "^4.2.13", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=20.0.0" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.972.25", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.25.tgz", + "integrity": "sha512-6QfI0wv4jpG5CrdO/AO0JfZ2ux+tKwJPrUwmvxXF50vI5KIypKVGNF6b4vlkYEnKumDTI1NX2zUBi8JoU5QU3A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/types": "^3.973.7", + "@smithy/property-provider": "^4.2.13", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=20.0.0" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.972.27", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.27.tgz", + "integrity": "sha512-3V3Usj9Gs93h865DqN4M2NWJhC5kXU9BvZskfN3+69omuYlE3TZxOEcVQtBGLOloJB7BVfJKXVLqeNhOzHqSlQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/types": "^3.973.7", + "@smithy/fetch-http-handler": "^5.3.16", + "@smithy/node-http-handler": "^4.5.2", + "@smithy/property-provider": "^4.2.13", + "@smithy/protocol-http": "^5.3.13", + "@smithy/smithy-client": "^4.12.9", + "@smithy/types": "^4.14.0", + "@smithy/util-stream": "^4.5.22", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=20.0.0" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.972.29", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.972.29.tgz", + "integrity": "sha512-SiBuAnXecCbT/OpAf3vqyI/AVE3mTaYr9ShXLybxZiPLBiPCCOIWSGAtYYGQWMRvobBTiqOewaB+wcgMMZI2Aw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/credential-provider-env": "^3.972.25", + "@aws-sdk/credential-provider-http": "^3.972.27", + "@aws-sdk/credential-provider-login": "^3.972.29", + "@aws-sdk/credential-provider-process": "^3.972.25", + "@aws-sdk/credential-provider-sso": "^3.972.29", + "@aws-sdk/credential-provider-web-identity": "^3.972.29", + "@aws-sdk/nested-clients": "^3.996.19", + "@aws-sdk/types": "^3.973.7", + "@smithy/credential-provider-imds": "^4.2.13", + "@smithy/property-provider": "^4.2.13", + "@smithy/shared-ini-file-loader": "^4.4.8", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, "engines": { - "node": ">=12" + "node": ">=20.0.0" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.29", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.29.tgz", + "integrity": "sha512-OGOslTbOlxXexKMqhxCEbBQbUIfuhGxU5UXw3Fm56ypXHvrXH4aTt/xb5Y884LOoteP1QST1lVZzHfcTnWhiPQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/nested-clients": "^3.996.19", + "@aws-sdk/types": "^3.973.7", + "@smithy/property-provider": "^4.2.13", + "@smithy/protocol-http": "^5.3.13", + "@smithy/shared-ini-file-loader": "^4.4.8", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.972.30", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.30.tgz", + "integrity": "sha512-FMnAnWxc8PG+ZrZ2OBKzY4luCUJhe9CG0B9YwYr4pzrYGLXBS2rl+UoUvjGbAwiptxRL6hyA3lFn03Bv1TLqTw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "^3.972.25", + "@aws-sdk/credential-provider-http": "^3.972.27", + "@aws-sdk/credential-provider-ini": "^3.972.29", + "@aws-sdk/credential-provider-process": "^3.972.25", + "@aws-sdk/credential-provider-sso": "^3.972.29", + "@aws-sdk/credential-provider-web-identity": "^3.972.29", + "@aws-sdk/types": "^3.973.7", + "@smithy/credential-provider-imds": "^4.2.13", + "@smithy/property-provider": "^4.2.13", + "@smithy/shared-ini-file-loader": "^4.4.8", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.972.25", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.25.tgz", + "integrity": "sha512-HR7ynNRdNhNsdVCOCegy1HsfsRzozCOPtD3RzzT1JouuaHobWyRfJzCBue/3jP7gECHt+kQyZUvwg/cYLWurNQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/types": "^3.973.7", + "@smithy/property-provider": "^4.2.13", + "@smithy/shared-ini-file-loader": "^4.4.8", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.972.29", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.972.29.tgz", + "integrity": "sha512-HWv4SEq3jZDYPlwryZVef97+U8CxxRos5mK8sgGO1dQaFZpV5giZLzqGE5hkDmh2csYcBO2uf5XHjPTpZcJlig==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/nested-clients": "^3.996.19", + "@aws-sdk/token-providers": "3.1026.0", + "@aws-sdk/types": "^3.973.7", + "@smithy/property-provider": "^4.2.13", + "@smithy/shared-ini-file-loader": "^4.4.8", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso/node_modules/@aws-sdk/token-providers": { + "version": "3.1026.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1026.0.tgz", + "integrity": "sha512-Ieq/HiRrbEtrYP387Nes0XlR7H1pJiJOZKv+QyQzMYpvTiDs0VKy2ZB3E2Zf+aFovWmeE7lRE4lXyF7dYM6GgA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/nested-clients": "^3.996.19", + "@aws-sdk/types": "^3.973.7", + "@smithy/property-provider": "^4.2.13", + "@smithy/shared-ini-file-loader": "^4.4.8", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.972.29", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.29.tgz", + "integrity": "sha512-PdMBza1WEKEUPFEmMGCfnU2RYCz9MskU2e8JxjyUOsMKku7j9YaDKvbDi2dzC0ihFoM6ods2SbhfAAro+Gwlew==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/nested-clients": "^3.996.19", + "@aws-sdk/types": "^3.973.7", + "@smithy/property-provider": "^4.2.13", + "@smithy/shared-ini-file-loader": "^4.4.8", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-handler-node": { + "version": "3.972.13", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.972.13.tgz", + "integrity": "sha512-2Pi1kD0MDkMAxDHqvpi/hKMs9hXUYbj2GLEjCwy+0jzfLChAsF50SUYnOeTI+RztA+Ic4pnLAdB03f1e8nggxQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@smithy/eventstream-codec": "^4.2.13", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-eventstream": { + "version": "3.972.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.972.9.tgz", + "integrity": "sha512-ypgOvpWxQTCnQyDHGxnTviqqANE7FIIzII7VczJnTPCJcJlu17hMQXnvE47aKSKsawVJAaaRsyOEbHQuLJF9ng==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@smithy/protocol-http": "^5.3.13", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.972.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.972.9.tgz", + "integrity": "sha512-je5vRdNw4SkuTnmRbFZLdye4sQ0faLt8kwka5wnnSU30q1mHO4X+idGEJOOE+Tn1ME7Oryn05xxkDvIb3UaLaQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@smithy/protocol-http": "^5.3.13", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.972.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.972.9.tgz", + "integrity": "sha512-HsVgDrruhqI28RkaXALm8grJ7Agc1wF6Et0xh6pom8NdO2VdO/SD9U/tPwUjewwK/pVoka+EShBxyCvgsPCtog==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.972.10", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.972.10.tgz", + "integrity": "sha512-RVQQbq5orQ/GHUnXvqEOj2HHPBJm+mM+ySwZKS5UaLBwra5ugRtiH09PLUoOZRl7a1YzaOzXSuGbn9iD5j60WQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.13", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.972.29", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.972.29.tgz", + "integrity": "sha512-f/sIRzuTfEjg6NsbMYvye2VsmnQoNgntntleQyx5uGacUYzszbfIlO3GcI6G6daWUmTm0IDZc11qMHWwF0o0mQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/types": "^3.973.7", + "@aws-sdk/util-endpoints": "^3.996.6", + "@smithy/core": "^3.23.14", + "@smithy/protocol-http": "^5.3.13", + "@smithy/types": "^4.14.0", + "@smithy/util-retry": "^4.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-websocket": { + "version": "3.972.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.972.15.tgz", + "integrity": "sha512-hsZ35FORQsN5hwNdMD6zWmHCphbXkDxO6j+xwCUiuMb0O6gzS/PWgttQNl1OAn7h/uqZAMUG4yOS0wY/yhAieg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@aws-sdk/util-format-url": "^3.972.9", + "@smithy/eventstream-codec": "^4.2.13", + "@smithy/eventstream-serde-browser": "^4.2.13", + "@smithy/fetch-http-handler": "^5.3.16", + "@smithy/protocol-http": "^5.3.13", + "@smithy/signature-v4": "^5.3.13", + "@smithy/types": "^4.14.0", + "@smithy/util-base64": "^4.3.2", + "@smithy/util-hex-encoding": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.996.19", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.996.19.tgz", + "integrity": "sha512-uFkmCDXvmQYLanlYdOFS0+MQWkrj9wPMt/ZCc/0J0fjPim6F5jBVBmEomvGY/j77ILW6GTPwN22Jc174Mhkw6Q==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/middleware-host-header": "^3.972.9", + "@aws-sdk/middleware-logger": "^3.972.9", + "@aws-sdk/middleware-recursion-detection": "^3.972.10", + "@aws-sdk/middleware-user-agent": "^3.972.29", + "@aws-sdk/region-config-resolver": "^3.972.11", + "@aws-sdk/types": "^3.973.7", + "@aws-sdk/util-endpoints": "^3.996.6", + "@aws-sdk/util-user-agent-browser": "^3.972.9", + "@aws-sdk/util-user-agent-node": "^3.973.15", + "@smithy/config-resolver": "^4.4.14", + "@smithy/core": "^3.23.14", + "@smithy/fetch-http-handler": "^5.3.16", + "@smithy/hash-node": "^4.2.13", + "@smithy/invalid-dependency": "^4.2.13", + "@smithy/middleware-content-length": "^4.2.13", + "@smithy/middleware-endpoint": "^4.4.29", + "@smithy/middleware-retry": "^4.5.0", + "@smithy/middleware-serde": "^4.2.17", + "@smithy/middleware-stack": "^4.2.13", + "@smithy/node-config-provider": "^4.3.13", + "@smithy/node-http-handler": "^4.5.2", + "@smithy/protocol-http": "^5.3.13", + "@smithy/smithy-client": "^4.12.9", + "@smithy/types": "^4.14.0", + "@smithy/url-parser": "^4.2.13", + "@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.45", + "@smithy/util-defaults-mode-node": "^4.2.49", + "@smithy/util-endpoints": "^3.3.4", + "@smithy/util-middleware": "^4.2.13", + "@smithy/util-retry": "^4.3.0", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.972.11", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.972.11.tgz", + "integrity": "sha512-6Q8B1dcx6BBqUTY1Mc/eROKA0FImEEY5VPSd6AGPEUf0ErjExz4snVqa9kNJSoVDV1rKaNf3qrWojgcKW+SdDg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@smithy/config-resolver": "^4.4.14", + "@smithy/node-config-provider": "^4.3.13", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.1030.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1030.0.tgz", + "integrity": "sha512-gUuCLTnEiUgpxHEnJSidxZZlQ+rQwc/mrijz6DxeMijTwS3/e3UfJvL8C1YDvcbt8MkkXj92h0MpYtfhR+EGeg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.973.27", + "@aws-sdk/nested-clients": "^3.996.19", + "@aws-sdk/types": "^3.973.7", + "@smithy/property-provider": "^4.2.13", + "@smithy/shared-ini-file-loader": "^4.4.8", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.973.7", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.973.7.tgz", + "integrity": "sha512-reXRwoJ6CfChoqAsBszUYajAF8Z2LRE+CRcKocvFSMpIiLOtYU3aJ9trmn6VVPAzbbY5LXF+FfmUslbXk1SYFg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.996.6", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.996.6.tgz", + "integrity": "sha512-2nUQ+2ih7CShuKHpGSIYvvAIOHy52dOZguYG36zptBukhw6iFwcvGfG0tes0oZFWQqEWvgZe9HLWaNlvXGdOrg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@smithy/types": "^4.14.0", + "@smithy/url-parser": "^4.2.13", + "@smithy/util-endpoints": "^3.3.4", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-format-url": { + "version": "3.972.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.972.9.tgz", + "integrity": "sha512-fNJXHrs0ZT7Wx0KGIqKv7zLxlDXt2vqjx9z6oKUQFmpE5o4xxnSryvVHfHpIifYHWKz94hFccIldJ0YSZjlCBw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@smithy/querystring-builder": "^4.2.13", + "@smithy/types": "^4.14.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.965.5", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.965.5.tgz", + "integrity": "sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.972.9", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.972.9.tgz", + "integrity": "sha512-sn/LMzTbGjYqCCF24390WxPd6hkpoSptiUn5DzVp4cD71yqw+yGEGm1YCxyEoPXyc8qciM8UzLJcZBFslxo5Uw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.973.7", + "@smithy/types": "^4.14.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.973.15", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.973.15.tgz", + "integrity": "sha512-fYn3s9PtKdgQkczGZCFMgkNEe8aq1JCVbnRqjqN9RSVW43xn2RV9xdcZ3z01a48Jpkuh/xCmBKJxdLOo4Ozg7w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "^3.972.29", + "@aws-sdk/types": "^3.973.7", + "@smithy/node-config-provider": "^4.3.13", + "@smithy/types": "^4.14.0", + "@smithy/util-config-provider": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.972.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.17.tgz", + "integrity": "sha512-Ra7hjqAZf1OXRRMueB13qex7mFJRDK/pgCvdSFemXBT8KCGnQDPoKzHY1SjN+TjJVmnpSF14W5tJ1vDamFu+Gg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.0", + "fast-xml-parser": "5.5.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.4.tgz", + "integrity": "sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz", + "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@cfworker/json-schema": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@cfworker/json-schema/-/json-schema-4.1.1.tgz", + "integrity": "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==", + "license": "MIT" + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], @@ -257,50 +789,50 @@ "license": "MIT", "optional": true, "os": [ - "linux" + "aix" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/linux-riscv64": { + "node_modules/@esbuild/android-arm": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ - "riscv64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/linux-s390x": { + "node_modules/@esbuild/android-arm64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ - "s390x" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/linux-x64": { + "node_modules/@esbuild/android-x64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], @@ -308,33 +840,33 @@ "license": "MIT", "optional": true, "os": [ - "linux" + "android" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/netbsd-x64": { + "node_modules/@esbuild/darwin-arm64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "netbsd" + "darwin" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/openbsd-x64": { + "node_modules/@esbuild/darwin-x64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], @@ -342,357 +874,538 @@ "license": "MIT", "optional": true, "os": [ - "openbsd" + "darwin" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/sunos-x64": { + "node_modules/@esbuild/freebsd-arm64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "sunos" + "freebsd" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/win32-arm64": { + "node_modules/@esbuild/freebsd-x64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ - "arm64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "freebsd" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/win32-ia32": { + "node_modules/@esbuild/linux-arm": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ - "ia32" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { "node": ">=12" } }, - "node_modules/@esbuild/win32-x64": { + "node_modules/@esbuild/linux-arm64": { "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ], "engines": { "node": ">=12" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", - "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", - "cpu": [ - "arm" - ], + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", "optional": true, "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", - "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", - "cpu": [ - "arm64" + "linux" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", - "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ - "arm64" + "loong64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", - "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", - "cpu": [ - "x64" + "linux" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", - "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ - "arm64" + "mips64el" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "freebsd" - ] - }, - "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", - "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", - "cpu": [ - "x64" + "linux" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ] + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", - "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ - "arm" + "ppc64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", - "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", - "cpu": [ - "arm" ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", - "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ - "arm64" + "riscv64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", - "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ - "arm64" + "s390x" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-linux-loong64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", - "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ - "loong64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ "linux" - ] + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-linux-loong64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", - "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ - "loong64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "netbsd" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", - "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ - "ppc64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "openbsd" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-linux-ppc64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", - "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ - "ppc64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "sunos" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", - "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ - "riscv64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "win32" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", - "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ - "riscv64" + "ia32" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] + "win32" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", - "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ - "s390x" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@google/genai": { + "version": "1.50.1", + "resolved": "https://registry.npmjs.org/@google/genai/-/genai-1.50.1.tgz", + "integrity": "sha512-YbkX7H9+1Pt8wOt7DDREy8XSoiL6fRDzZQRyaVBarFf8MR3zHGqVdvM4cLbDXqPhxqvegZShgfxb8kw9C7YhAQ==", + "license": "Apache-2.0", + "dependencies": { + "google-auth-library": "^10.3.0", + "p-retry": "^4.6.2", + "protobufjs": "^7.5.4", + "ws": "^8.18.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@modelcontextprotocol/sdk": "^1.25.2" + }, + "peerDependenciesMeta": { + "@modelcontextprotocol/sdk": { + "optional": true + } + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@langchain/core": { + "version": "1.1.39", + "resolved": "https://registry.npmjs.org/@langchain/core/-/core-1.1.39.tgz", + "integrity": "sha512-DP9c7TREy6iA7HnywstmUAsNyJNYTFpRg2yBfQ+6H0l1HnvQzei9GsQ36GeOLxgRaD3vm9K8urCcawSC7yQpCw==", + "license": "MIT", + "dependencies": { + "@cfworker/json-schema": "^4.0.2", + "@standard-schema/spec": "^1.1.0", + "ansi-styles": "^5.0.0", + "camelcase": "6", + "decamelize": "1.2.0", + "js-tiktoken": "^1.0.12", + "langsmith": ">=0.5.0 <1.0.0", + "mustache": "^4.2.0", + "p-queue": "^6.6.2", + "uuid": "^11.1.0", + "zod": "^3.25.76 || ^4" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@langchain/openai": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@langchain/openai/-/openai-1.4.4.tgz", + "integrity": "sha512-mRr/X5rvlwPj6cSXPxbL+CtOqYANO1/+CQ3Z+5t48kWnrlgPYOazmA+UAWvqQOuwJ6LaYn3SFrt43rR4lte/Ow==", + "license": "MIT", + "dependencies": { + "js-tiktoken": "^1.0.12", + "openai": "^6.32.0", + "zod": "^3.25.76 || ^4" + }, + "engines": { + "node": ">=20" + }, + "peerDependencies": { + "@langchain/core": "^1.1.39" + } + }, + "node_modules/@mariozechner/pi-ai": { + "version": "0.67.3", + "resolved": "https://registry.npmjs.org/@mariozechner/pi-ai/-/pi-ai-0.67.3.tgz", + "integrity": "sha512-0GDT2osCfBPYKffaeEzGmrDKGCAF2QQ2eqTGGE5akhBvw1fSA3TYjOCQyLPgzWz3ZHUzZwb6EQ5Yb1Bn3H14CQ==", + "license": "MIT", + "dependencies": { + "@anthropic-ai/sdk": "^0.73.0", + "@aws-sdk/client-bedrock-runtime": "^3.983.0", + "@google/genai": "^1.40.0", + "@mistralai/mistralai": "1.14.1", + "@sinclair/typebox": "^0.34.41", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "chalk": "^5.6.2", + "openai": "6.26.0", + "partial-json": "^0.1.7", + "proxy-agent": "^6.5.0", + "undici": "^7.19.1", + "zod-to-json-schema": "^3.24.6" + }, + "bin": { + "pi-ai": "dist/cli.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@mariozechner/pi-ai/node_modules/openai": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-6.26.0.tgz", + "integrity": "sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==", + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/@mistralai/mistralai": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.14.1.tgz", + "integrity": "sha512-IiLmmZFCCTReQgPAT33r7KQ1nYo5JPdvGkrkZqA8qQ2qB1GHgs5LoP5K2ICyrjnpw2n8oSxMM/VP+liiKcGNlQ==", + "dependencies": { + "ws": "^8.18.0", + "zod": "^3.25.0 || ^4.0.0", + "zod-to-json-schema": "^3.24.1" + } + }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", - "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", + "integrity": "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==", "cpu": [ - "x64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "android" ] }, - "node_modules/@rollup/rollup-linux-x64-musl": { + "node_modules/@rollup/rollup-android-arm64": { "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", - "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.59.0.tgz", + "integrity": "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "linux" + "android" ] }, - "node_modules/@rollup/rollup-openbsd-x64": { + "node_modules/@rollup/rollup-darwin-arm64": { "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", - "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.59.0.tgz", + "integrity": "sha512-W2Psnbh1J8ZJw0xKAd8zdNgF9HRLkdWwwdWqubSVk0pUuQkoHnv7rx4GiF9rT4t5DIZGAsConRE3AxCdJ4m8rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.59.0.tgz", + "integrity": "sha512-ZW2KkwlS4lwTv7ZVsYDiARfFCnSGhzYPdiOU4IM2fDbL+QGlyAbjgSFuqNRbSthybLbIJ915UtZBtmuLrQAT/w==", "cpu": [ "x64" ], @@ -700,13 +1413,13 @@ "license": "MIT", "optional": true, "os": [ - "openbsd" + "darwin" ] }, - "node_modules/@rollup/rollup-openharmony-arm64": { + "node_modules/@rollup/rollup-freebsd-arm64": { "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", - "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.59.0.tgz", + "integrity": "sha512-EsKaJ5ytAu9jI3lonzn3BgG8iRBjV4LxZexygcQbpiU0wU0ATxhNVEpXKfUa0pS05gTcSDMKpn3Sx+QB9RlTTA==", "cpu": [ "arm64" ], @@ -714,504 +1427,3639 @@ "license": "MIT", "optional": true, "os": [ - "openharmony" + "freebsd" ] }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { + "node_modules/@rollup/rollup-freebsd-x64": { "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", - "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.59.0.tgz", + "integrity": "sha512-d3DuZi2KzTMjImrxoHIAODUZYoUUMsuUiY4SRRcJy6NJoZ6iIqWnJu9IScV9jXysyGMVuW+KNzZvBLOcpdl3Vg==", "cpu": [ - "arm64" + "x64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "freebsd" ] }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", - "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.59.0.tgz", + "integrity": "sha512-t4ONHboXi/3E0rT6OZl1pKbl2Vgxf9vJfWgmUoCEVQVxhW6Cw/c8I6hbbu7DAvgp82RKiH7TpLwxnJeKv2pbsw==", "cpu": [ - "ia32" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ] }, - "node_modules/@rollup/rollup-win32-x64-gnu": { + "node_modules/@rollup/rollup-linux-arm-musleabihf": { "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", - "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.59.0.tgz", + "integrity": "sha512-CikFT7aYPA2ufMD086cVORBYGHffBo4K8MQ4uPS/ZnY54GKj36i196u8U+aDVT2LX4eSMbyHtyOh7D7Zvk2VvA==", "cpu": [ - "x64" + "arm" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ] }, - "node_modules/@rollup/rollup-win32-x64-msvc": { + "node_modules/@rollup/rollup-linux-arm64-gnu": { "version": "4.59.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", - "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.59.0.tgz", + "integrity": "sha512-jYgUGk5aLd1nUb1CtQ8E+t5JhLc9x5WdBKew9ZgAXg7DBk0ZHErLHdXM24rfX+bKrFe+Xp5YuJo54I5HFjGDAA==", "cpu": [ - "x64" + "arm64" ], "dev": true, "license": "MIT", "optional": true, "os": [ - "win32" + "linux" ] }, - "node_modules/@sinclair/typebox": { - "version": "0.34.48", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", - "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", - "license": "MIT" + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.59.0.tgz", + "integrity": "sha512-peZRVEdnFWZ5Bh2KeumKG9ty7aCXzzEsHShOZEFiCQlDEepP1dpUl/SrUNXNg13UmZl+gzVDPsiCwnV1uI0RUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.59.0.tgz", + "integrity": "sha512-gbUSW/97f7+r4gHy3Jlup8zDG190AuodsWnNiXErp9mT90iCy9NKKU0Xwx5k8VlRAIV2uU9CsMnEFg/xXaOfXg==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@types/node": { - "version": "22.19.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz", - "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.59.0.tgz", + "integrity": "sha512-yTRONe79E+o0FWFijasoTjtzG9EBedFXJMl888NBEDCDV9I2wGbFFfJQQe63OijbFCUZqxpHz1GzpbtSFikJ4Q==", + "cpu": [ + "loong64" + ], "dev": true, "license": "MIT", - "dependencies": { - "undici-types": "~6.21.0" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@vitest/expect": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", - "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.59.0.tgz", + "integrity": "sha512-sw1o3tfyk12k3OEpRddF68a1unZ5VCN7zoTNtSn2KndUE+ea3m3ROOKRCZxEpmT9nsGnogpFP9x6mnLTCaoLkA==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@vitest/spy": "2.1.9", - "@vitest/utils": "2.1.9", - "chai": "^5.1.2", - "tinyrainbow": "^1.2.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@vitest/mocker": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", - "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.59.0.tgz", + "integrity": "sha512-+2kLtQ4xT3AiIxkzFVFXfsmlZiG5FXYW7ZyIIvGA7Bdeuh9Z0aN4hVyXS/G1E9bTP/vqszNIN/pUKCk/BTHsKA==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.59.0.tgz", + "integrity": "sha512-NDYMpsXYJJaj+I7UdwIuHHNxXZ/b/N2hR15NyH3m2qAtb/hHPA4g4SuuvrdxetTdndfj9b1WOmy73kcPRoERUg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.59.0.tgz", + "integrity": "sha512-nLckB8WOqHIf1bhymk+oHxvM9D3tyPndZH8i8+35p/1YiVoVswPid2yLzgX7ZJP0KQvnkhM4H6QZ5m0LzbyIAg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.59.0.tgz", + "integrity": "sha512-oF87Ie3uAIvORFBpwnCvUzdeYUqi2wY6jRFWJAy1qus/udHFYIkplYRW+wo+GRUP4sKzYdmE1Y3+rY5Gc4ZO+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.59.0.tgz", + "integrity": "sha512-3AHmtQq/ppNuUspKAlvA8HtLybkDflkMuLK4DPo77DfthRb71V84/c4MlWJXixZz4uruIH4uaa07IqoAkG64fg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.59.0.tgz", + "integrity": "sha512-2UdiwS/9cTAx7qIUZB/fWtToJwvt0Vbo0zmnYt7ED35KPg13Q0ym1g442THLC7VyI6JfYTP4PiSOWyoMdV2/xg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.59.0.tgz", + "integrity": "sha512-M3bLRAVk6GOwFlPTIxVBSYKUaqfLrn8l0psKinkCFxl4lQvOSz8ZrKDz2gxcBwHFpci0B6rttydI4IpS4IS/jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.59.0.tgz", + "integrity": "sha512-tt9KBJqaqp5i5HUZzoafHZX8b5Q2Fe7UjYERADll83O4fGqJ49O1FsL6LpdzVFQcpwvnyd0i+K/VSwu/o/nWlA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.59.0.tgz", + "integrity": "sha512-V5B6mG7OrGTwnxaNUzZTDTjDS7F75PO1ae6MJYdiMu60sq0CqN5CVeVsbhPxalupvTX8gXVSU9gq+Rx1/hvu6A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.59.0.tgz", + "integrity": "sha512-UKFMHPuM9R0iBegwzKF4y0C4J9u8C6MEJgFuXTBerMk7EJ92GFVFYBfOZaSGLu6COf7FxpQNqhNS4c4icUPqxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.59.0.tgz", + "integrity": "sha512-laBkYlSS1n2L8fSo1thDNGrCTQMmxjYY5G0WFWjFFYZkKPjsMBsgJfGf4TLxXrF6RyhI60L8TMOjBMvXiTcxeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.59.0.tgz", + "integrity": "sha512-2HRCml6OztYXyJXAvdDXPKcawukWY2GpR5/nxKp4iBgiO3wcoEGkAaqctIbZcNB6KlUQBIqt8VYkNSj2397EfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@seekdb/js-bindings": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@seekdb/js-bindings/-/js-bindings-1.2.0.tgz", + "integrity": "sha512-s8h9vhszRqRweenCP7WZcMtIGu7Cfb6H/SDp6HPv7+gqy1z+jiaeit4vF6Ji+x0TXPkkcMUX/oB299rS/MXvHA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "adm-zip": "^0.5.16" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.34.48", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.48.tgz", + "integrity": "sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==", + "license": "MIT" + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.16", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.16.tgz", + "integrity": "sha512-GFlGPNLZKrGfqWpqVb31z7hvYCA9ZscfX1buYnvvMGcRYsQQnhH+4uN6mWWflcD5jB4OXP/LBrdpukEdjl41tg==", + "license": "Apache-2.0", + "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.1", + "@smithy/util-middleware": "^4.2.14", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.23.15", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.23.15.tgz", + "integrity": "sha512-E7GVCgsQttzfujEZb6Qep005wWf4xiL4x06apFEtzQMWYBPggZh/0cnOxPficw5cuK/YjjkehKoIN4YUaSh0UQ==", + "license": "Apache-2.0", + "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.23", + "@smithy/util-utf8": "^4.2.2", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.14.tgz", + "integrity": "sha512-Au28zBN48ZAoXdooGUHemuVBrkE+Ie6RPmGNIAJsFqj33Vhb6xAgRifUydZ2aY+M+KaMAETAlKk5NC5h1G7wpg==", + "license": "Apache-2.0", + "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.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.14.tgz", + "integrity": "sha512-erZq0nOIpzfeZdCyzZjdJb4nVSKLUmSkaQUVkRGQTXs30gyUGeKnrYEg+Xe1W5gE3aReS7IgsvANwVPxSzY6Pw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.14.1", + "@smithy/util-hex-encoding": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.14.tgz", + "integrity": "sha512-8IelTCtTctWRbb+0Dcy+C0aICh1qa0qWXqgjcXDmMuCvPJRnv26hiDZoAau2ILOniki65mCPKqOQs/BaWvO4CQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.14.tgz", + "integrity": "sha512-sqHiHpYRYo3FJlaIxD1J8PhbcmJAm7IuM16mVnwSkCToD7g00IBZzKuiLNMGmftULmEUX6/UAz8/NN5uMP8bVA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.14.tgz", + "integrity": "sha512-Ht/8BuGlKfFTy0H3+8eEu0vdpwGztCnaLLXtpXNdQqiR7Hj4vFScU3T436vRAjATglOIPjJXronY+1WxxNLSiw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.14.tgz", + "integrity": "sha512-lWyt4T2XQZUZgK3tQ3Wn0w3XBvZsK/vjTuJl6bXbnGZBHH0ZUSONTYiK9TgjTTzU54xQr3DRFwpjmhp0oLm3gg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.17", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.17.tgz", + "integrity": "sha512-bXOvQzaSm6MnmLaWA1elgfQcAtN4UP3vXqV97bHuoOrHQOJiLT3ds6o9eo5bqd0TJfRFpzdGnDQdW3FACiAVdw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/querystring-builder": "^4.2.14", + "@smithy/types": "^4.14.1", + "@smithy/util-base64": "^4.3.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.14.tgz", + "integrity": "sha512-8ZBDY2DD4wr+GGjTpPtiglEsqr0lUP+KHqgZcWczFf6qeZ/YRjMIOoQWVQlmwu7EtxKTd8YXD8lblmYcpBIA1g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.14.tgz", + "integrity": "sha512-c21qJiTSb25xvvOp+H2TNZzPCngrvl5vIPqPB8zQ/DmJF4QWXO19x1dWfMJZ6wZuuWUPPm0gV8C0cU3+ifcWuw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.2.tgz", + "integrity": "sha512-n6rQ4N8Jj4YTQO3YFrlgZuwKodf4zUFs7EJIWH86pSCWBaAtAGBFfCM7Wx6D2bBJ2xqFNxGBSrUWswT3M0VJow==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.14.tgz", + "integrity": "sha512-xhHq7fX4/3lv5NHxLUk3OeEvl0xZ+Ek3qIbWaCL4f9JwgDZEclPBElljaZCAItdGPQl/kSM4LPMOpy1MYgprpw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.4.30", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.30.tgz", + "integrity": "sha512-qS2XqhKeXmdZ4nEQ4cOxIczSP/Y91wPAHYuRwmWDCh975B7/57uxsm5d6sisnUThn2u2FwzMdJNM7AbO1YPsPg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.15", + "@smithy/middleware-serde": "^4.2.18", + "@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", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.5.3.tgz", + "integrity": "sha512-TE8dJNi6JuxzGSxMCVd3i9IEWDndCl3bmluLsBNDWok8olgj65OfkndMhl9SZ7m14c+C5SQn/PcUmrDl57rSFw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.15", + "@smithy/node-config-provider": "^4.3.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/service-error-classification": "^4.2.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "@smithy/util-middleware": "^4.2.14", + "@smithy/util-retry": "^4.3.2", + "@smithy/uuid": "^1.1.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.2.18", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.18.tgz", + "integrity": "sha512-M6CSgnp3v4tYz9ynj2JHbA60woBZcGqEwNjTKjBsNHPV26R1ZX52+0wW8WsZU18q45jD0tw2wL22S17Ze9LpEw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.15", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.14.tgz", + "integrity": "sha512-2dvkUKLuFdKsCRmOE4Mn63co0Djtsm+JMh0bYZQupN1pJwMeE8FmQmRLLzzEMN0dnNi7CDCYYH8F0EVwWiPBeA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.14.tgz", + "integrity": "sha512-S+gFjyo/weSVL0P1b9Ts8C/CwIfNCgUPikk3sl6QVsfE/uUuO+QsF+NsE/JkpvWqqyz1wg7HFdiaZuj5CoBMRg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.14", + "@smithy/shared-ini-file-loader": "^4.4.9", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.5.3.tgz", + "integrity": "sha512-lc5jFL++x17sPhIwMWJ3YOnqmSjw/2Po6VLDlUIXvxVWRuJwRXnJ4jOBBLB0cfI5BB5ehIl02Fxr1PDvk/kxDw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.14", + "@smithy/querystring-builder": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.14.tgz", + "integrity": "sha512-WuM31CgfsnQ/10i7NYr0PyxqknD72Y5uMfUMVSniPjbEPceiTErb4eIqJQ+pdxNEAUEWrewrGjIRjVbVHsxZiQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.14.tgz", + "integrity": "sha512-dN5F8kHx8RNU0r+pCwNmFZyz6ChjMkzShy/zup6MtkRmmix4vZzJdW+di7x//b1LiynIev88FM18ie+wwPcQtQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.14.tgz", + "integrity": "sha512-XYA5Z0IqTeF+5XDdh4BBmSA0HvbgVZIyv4cmOoUheDNR57K1HgBp9ukUMx3Cr3XpDHHpLBnexPE3LAtDsZkj2A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "@smithy/util-uri-escape": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.14.tgz", + "integrity": "sha512-hr+YyqBD23GVvRxGGrcc/oOeNlK3PzT5Fu4dzrDXxzS1LpFiuL2PQQqKPs87M79aW7ziMs+nvB3qdw77SqE7Lw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.14.tgz", + "integrity": "sha512-vVimoUnGxlx4eLLQbZImdOZFOe+Zh+5ACntv8VxZuGP72LdWu5GV3oEmCahSEReBgRJoWjypFkrehSj7BWx1HQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.9.tgz", + "integrity": "sha512-495/V2I15SHgedSJoDPD23JuSfKAp726ZI1V0wtjB07Wh7q/0tri/0e0DLefZCHgxZonrGKt/OCTpAtP1wE1kQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.14.tgz", + "integrity": "sha512-1D9Y/nmlVjCeSivCbhZ7hgEpmHyY1h0GvpSZt3l0xcD9JjmjVC1CHOozS6+Gh+/ldMH8JuJ6cujObQqfayAVFA==", + "license": "Apache-2.0", + "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.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.12.11", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.12.11.tgz", + "integrity": "sha512-wzz/Wa1CH/Tlhxh0s4DQPEcXSxSVfJ59AZcUh9Gu0c6JTlKuwGf4o/3P2TExv0VbtPFt8odIBG+eQGK2+vTECg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.23.15", + "@smithy/middleware-endpoint": "^4.4.30", + "@smithy/middleware-stack": "^4.2.14", + "@smithy/protocol-http": "^5.3.14", + "@smithy/types": "^4.14.1", + "@smithy/util-stream": "^4.5.23", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.14.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.14.1.tgz", + "integrity": "sha512-59b5HtSVrVR/eYNei3BUj3DCPKD/G7EtDDe7OEJE7i7FtQFugYo6MxbotS8mVJkLNVf8gYaAlEBwwtJ9HzhWSg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.14.tgz", + "integrity": "sha512-p06BiBigJ8bTA3MgnOfCtDUWnAMY0YfedO/GRpmc7p+wg3KW8vbXy1xwSu5ASy0wV7rRYtlfZOIKH4XqfhjSQQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.2.tgz", + "integrity": "sha512-XRH6b0H/5A3SgblmMa5ErXQ2XKhfbQB+Fm/oyLZ2O2kCUrwgg55bU0RekmzAhuwOjA9qdN5VU2BprOvGGUkOOQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "@smithy/util-utf8": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.2.tgz", + "integrity": "sha512-JKCrLNOup3OOgmzeaKQwi4ZCTWlYR5H4Gm1r2uTMVBXoemo1UEghk5vtMi1xSu2ymgKVGW631e2fp9/R610ZjQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.3.tgz", + "integrity": "sha512-ZkJGvqBzMHVHE7r/hcuCxlTY8pQr1kMtdsVPs7ex4mMU+EAbcXppfo5NmyxMYi2XU49eqaz56j2gsk4dHHPG/g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.2.tgz", + "integrity": "sha512-FDXD7cvUoFWwN6vtQfEta540Y/YBe5JneK3SoZg9bThSoOAC/eGeYEua6RkBgKjGa/sz6Y+DuBZj3+YEY21y4Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.2.tgz", + "integrity": "sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.3.47", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.47.tgz", + "integrity": "sha512-zlIuXai3/SHjQUQ8y3g/woLvrH573SK2wNjcDaHu5e9VOcC0JwM1MI0Sq0GZJyN3BwSUneIhpjZ18nsiz5AtQw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.14", + "@smithy/smithy-client": "^4.12.11", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.2.52", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.52.tgz", + "integrity": "sha512-cQBz8g68Vnw1W2meXlkb3D/hXJU+Taiyj9P8qLJtjREEV9/Td65xi4A/H1sRQ8EIgX5qbZbvdYPKygKLholZ3w==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^4.4.16", + "@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.11", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.4.1.tgz", + "integrity": "sha512-wMxNDZJrgS5mQV9oxCs4TWl5767VMgOfqfZ3JHyCkMtGC2ykW9iPqMvFur695Otcc5yxLG8OKO/80tsQBxrhXg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.2.tgz", + "integrity": "sha512-Qcz3W5vuHK4sLQdyT93k/rfrUwdJ8/HZ+nMUOyGdpeGA1Wxt65zYwi3oEl9kOM+RswvYq90fzkNDahPS8K0OIg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.14.tgz", + "integrity": "sha512-1Su2vj9RYNDEv/V+2E+jXkkwGsgR7dc4sfHn9Z7ruzQHJIEni9zzw5CauvRXlFJfmgcqYP8fWa0dkh2Q2YaQyw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.3.2.tgz", + "integrity": "sha512-2+KTsJEwTi63NUv4uR9IQ+IFT1yu6Rf6JuoBK2WKaaJ/TRvOiOVGcXAsEqX/TQN2thR9yII21kPUJq1UV/WI2A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^4.2.14", + "@smithy/types": "^4.14.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.5.23", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.23.tgz", + "integrity": "sha512-N6on1+ngJ3RznZOnDWNveIwnTSlqxNnXuNAh7ez889ZZaRdXoNRTXKgmYOLe6dB0gCmAVtuRScE1hymQFl4hpg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^5.3.17", + "@smithy/node-http-handler": "^4.5.3", + "@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.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.2.tgz", + "integrity": "sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.2.tgz", + "integrity": "sha512-75MeYpjdWRe8M5E3AW0O4Cx3UadweS+cwdXjwYGBW5h/gxxnbeZ877sLPX/ZJA9GVTlL/qG0dXP29JWFCD1Ayw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.2", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.2.tgz", + "integrity": "sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz", + "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT" + }, + "node_modules/@vitest/expect": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", + "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", + "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", + "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", + "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/adm-zip": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.17.tgz", + "integrity": "sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=12.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/aws-ssl-profiles": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/aws-ssl-profiles/-/aws-ssl-profiles-1.1.2.tgz", + "integrity": "sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==", + "license": "MIT", + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/basic-ftp": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.0.tgz", + "integrity": "sha512-5K9eNNn7ywHPsYnFwjKgYH8Hf8B5emh7JKcPaVjjrMJFQQwGpwowEnZNEtHs7DfR7hCZsmaK3VA4HUK0YarT+w==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/better-sqlite3": { + "version": "12.9.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-12.9.0.tgz", + "integrity": "sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + }, + "engines": { + "node": "20.x || 22.x || 23.x || 24.x || 25.x" + } + }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "license": "MIT", + "dependencies": { + "file-uri-to-path": "1.0.0" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/bowser": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", + "license": "MIT" + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "license": "BSD-3-Clause" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/commander": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz", + "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/content-disposition": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", + "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", + "dependencies": { + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-xml-builder": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.1.4.tgz", + "integrity": "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "path-expression-matcher": "^1.1.3" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.5.8", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.5.8.tgz", + "integrity": "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "fast-xml-builder": "^1.1.4", + "path-expression-matcher": "^1.2.0", + "strnum": "^2.2.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "license": "MIT" + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gaxios": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz", + "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "node-fetch": "^3.3.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/gcp-metadata": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz", + "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^7.0.0", + "google-logging-utils": "^1.0.0", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "license": "MIT", + "dependencies": { + "is-property": "^1.0.2" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-uri": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.5.tgz", + "integrity": "sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, + "node_modules/google-auth-library": { + "version": "10.6.2", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz", + "integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==", + "license": "Apache-2.0", + "dependencies": { + "base64-js": "^1.3.0", + "ecdsa-sig-formatter": "^1.0.11", + "gaxios": "^7.1.4", + "gcp-metadata": "8.1.2", + "google-logging-utils": "1.1.3", + "jws": "^4.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/google-logging-utils": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz", + "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", "dependencies": { - "@vitest/spy": "2.1.9", - "estree-walker": "^3.0.3", - "magic-string": "^0.30.12" + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" }, "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==", + "license": "MIT" + }, + "node_modules/js-tiktoken": { + "version": "1.0.21", + "resolved": "https://registry.npmjs.org/js-tiktoken/-/js-tiktoken-1.0.21.tgz", + "integrity": "sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==", + "license": "MIT", + "dependencies": { + "base64-js": "^1.5.1" + } + }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, + "node_modules/json-schema-to-ts": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz", + "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.18.3", + "ts-algebra": "^2.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/jwa": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", + "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", + "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/langsmith": { + "version": "0.5.18", + "resolved": "https://registry.npmjs.org/langsmith/-/langsmith-0.5.18.tgz", + "integrity": "sha512-3zuZUWffTHQ+73EAwnodADtf534VNEZUpXr9jC12qyG8/IQuJET7PRsCpTb9wX2lmBspakwLUpqpj3tNm/0bVA==", + "license": "MIT", + "dependencies": { + "p-queue": "6.6.2", + "uuid": "10.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "*", + "@opentelemetry/exporter-trace-otlp-proto": "*", + "@opentelemetry/sdk-trace-base": "*", + "openai": "*", + "ws": ">=7" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@opentelemetry/exporter-trace-otlp-proto": { + "optional": true + }, + "@opentelemetry/sdk-trace-base": { + "optional": true + }, + "openai": { + "optional": true + }, + "ws": { + "optional": true + } + } + }, + "node_modules/langsmith/node_modules/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/lru.min": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lru.min/-/lru.min-1.1.4.tgz", + "integrity": "sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==", + "license": "MIT", + "engines": { + "bun": ">=1.0.0", + "deno": ">=1.30.0", + "node": ">=8.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wellwelwel" + } + }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/mysql2": { + "version": "3.22.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.22.0.tgz", + "integrity": "sha512-4jaJYBObj7FhD3lnZhqX1yDMuZN4mQNz+IolDySDXT7fbozMBpeGQNcuWXKUqo4ahkAEfkjUHPjnwuDI0/6VKw==", + "license": "MIT", + "dependencies": { + "aws-ssl-profiles": "^1.1.2", + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.7.2", + "long": "^5.3.2", + "lru.min": "^1.1.4", + "named-placeholders": "^1.1.6", + "sql-escaper": "^1.3.3" + }, + "engines": { + "node": ">= 8.0" + }, + "peerDependencies": { + "@types/node": ">= 8" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.6.tgz", + "integrity": "sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==", + "license": "MIT", + "dependencies": { + "lru.min": "^1.1.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/netmask": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.1.1.tgz", + "integrity": "sha512-eonl3sLUha+S1GzTPxychyhnUzKyeQkZ7jLjKrBagJgPla13F+uQ71HgpFefyHgqrjEbCPkDArxYsjY8/+gLKA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/node-abi": { + "version": "3.89.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.89.0.tgz", + "integrity": "sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/openai": { + "version": "6.34.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-6.34.0.tgz", + "integrity": "sha512-yEr2jdGf4tVFYG6ohmr3pF6VJuveP0EA/sS8TBx+4Eq5NT10alu5zg2dmxMXMgqpihRDQlFGpRt2XwsGj+Fyxw==", + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" }, "peerDependencies": { - "msw": "^2.4.9", - "vite": "^5.0.0" + "ws": "^8.18.0", + "zod": "^3.25 || ^4.0" }, "peerDependenciesMeta": { - "msw": { + "ws": { "optional": true }, - "vite": { + "zod": { "optional": true } } }, - "node_modules/@vitest/pretty-format": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", - "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", - "dev": true, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", "license": "MIT", "dependencies": { - "tinyrainbow": "^1.2.0" + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" }, "funding": { - "url": "https://opencollective.com/vitest" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@vitest/runner": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", - "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", - "dev": true, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", "license": "MIT", "dependencies": { - "@vitest/utils": "2.1.9", - "pathe": "^1.1.2" + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pac-proxy-agent": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", + "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", + "license": "MIT", + "dependencies": { + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.6", + "pac-resolver": "^7.0.1", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", + "dependencies": { + "degenerator": "^5.0.0", + "netmask": "^2.0.2" }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/partial-json": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/partial-json/-/partial-json-0.1.7.tgz", + "integrity": "sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==", + "license": "MIT" + }, + "node_modules/path-expression-matcher": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.5.0.tgz", + "integrity": "sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/path-to-regexp": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", + "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", + "license": "MIT", "funding": { - "url": "https://opencollective.com/vitest" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@vitest/snapshot": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", - "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/pg": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.20.0.tgz", + "integrity": "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==", + "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.9", - "magic-string": "^0.30.12", - "pathe": "^1.1.2" + "pg-connection-string": "^2.12.0", + "pg-pool": "^3.13.0", + "pg-protocol": "^1.13.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">= 16.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.3.0" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } } }, - "node_modules/@vitest/spy": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", - "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "node_modules/pg-cloudflare": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.3.0.tgz", + "integrity": "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==", + "license": "MIT", + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.12.0.tgz", + "integrity": "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==", + "license": "MIT" + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.13.0.tgz", + "integrity": "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", + "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.8", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", + "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/powermem": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/powermem/-/powermem-0.1.1.tgz", + "integrity": "sha512-Qvq+Dw2sxkSr4srafJiGdLMkYeQsf9cRm41dJk+B8NmqvTHnpCvhCkhvj+J0f8ZGHToB5Lme4RvMTDCkZFdrLg==", + "dependencies": { + "@langchain/core": "^1.1.38", + "better-sqlite3": "^12.8.0", + "commander": "^14.0.3", + "dotenv": "^16.0.0", + "express": "^5.2.1", + "pg": "^8.20.0", + "seekdb": "^1.2.0", + "zod": "^4.3.6" + }, + "bin": { + "pmem": "dist/cli.js", + "powermem-server": "dist/server.js" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@langchain/anthropic": ">=0.3.0", + "@langchain/ollama": ">=0.2.0", + "@langchain/openai": ">=0.3.0" + }, + "peerDependenciesMeta": { + "@langchain/anthropic": { + "optional": true + }, + "@langchain/ollama": { + "optional": true + }, + "@langchain/openai": { + "optional": true + } + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "deprecated": "No longer maintained. Please contact the author of the relevant native addon; alternatives are available.", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/protobufjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.5.tgz", + "integrity": "sha512-3wY1AxV+VBNW8Yypfd1yQY9pXnqTAN+KwQxL8iYm3/BjKYMNg4i0owhEe26PWDOMaIrzeeF98Lqd5NGz4omiIg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-agent": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", + "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.1", + "https-proxy-agent": "^7.0.6", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.1.0", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.5" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/qs": { + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { - "tinyspy": "^3.0.2" + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "bin": { + "rc": "cli.js" } }, - "node_modules/@vitest/utils": { - "version": "2.1.9", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", - "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", - "dev": true, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "2.1.9", - "loupe": "^3.1.2", - "tinyrainbow": "^1.2.0" + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" }, - "funding": { - "url": "https://opencollective.com/vitest" + "engines": { + "node": ">= 6" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", - "dev": true, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "license": "MIT", "engines": { - "node": ">=12" + "node": ">=0.10.0" } }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 4" } }, - "node_modules/chai": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", - "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "node_modules/rollup": { + "version": "4.59.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", + "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", "dev": true, "license": "MIT", "dependencies": { - "assertion-error": "^2.0.1", - "check-error": "^2.1.1", - "deep-eql": "^5.0.1", - "loupe": "^3.1.0", - "pathval": "^2.0.0" + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" }, "engines": { - "node": ">=18" + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.59.0", + "@rollup/rollup-android-arm64": "4.59.0", + "@rollup/rollup-darwin-arm64": "4.59.0", + "@rollup/rollup-darwin-x64": "4.59.0", + "@rollup/rollup-freebsd-arm64": "4.59.0", + "@rollup/rollup-freebsd-x64": "4.59.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", + "@rollup/rollup-linux-arm-musleabihf": "4.59.0", + "@rollup/rollup-linux-arm64-gnu": "4.59.0", + "@rollup/rollup-linux-arm64-musl": "4.59.0", + "@rollup/rollup-linux-loong64-gnu": "4.59.0", + "@rollup/rollup-linux-loong64-musl": "4.59.0", + "@rollup/rollup-linux-ppc64-gnu": "4.59.0", + "@rollup/rollup-linux-ppc64-musl": "4.59.0", + "@rollup/rollup-linux-riscv64-gnu": "4.59.0", + "@rollup/rollup-linux-riscv64-musl": "4.59.0", + "@rollup/rollup-linux-s390x-gnu": "4.59.0", + "@rollup/rollup-linux-x64-gnu": "4.59.0", + "@rollup/rollup-linux-x64-musl": "4.59.0", + "@rollup/rollup-openbsd-x64": "4.59.0", + "@rollup/rollup-openharmony-arm64": "4.59.0", + "@rollup/rollup-win32-arm64-msvc": "4.59.0", + "@rollup/rollup-win32-ia32-msvc": "4.59.0", + "@rollup/rollup-win32-x64-gnu": "4.59.0", + "@rollup/rollup-win32-x64-msvc": "4.59.0", + "fsevents": "~2.3.2" } }, - "node_modules/check-error": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", - "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", - "dev": true, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, "engines": { - "node": ">= 16" + "node": ">= 18" } }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, - "license": "MIT", + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/seekdb": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/seekdb/-/seekdb-1.2.0.tgz", + "integrity": "sha512-wcEWLgmvKGPbJwD4F79wmYqKEojt60fm/balJa+p/bpRKex4OBoThFp5PaQ6Ia6/Ky7tWZE2q6kJB2nEm2hpNA==", + "license": "Apache-2.0", "dependencies": { - "ms": "^2.1.3" + "mysql2": "^3.11.5" }, "engines": { - "node": ">=6.0" + "node": ">=20" + }, + "optionalDependencies": { + "@seekdb/js-bindings": "1.2.0" + }, + "peerDependencies": { + "@seekdb/default-embed": "^1.2.0" }, "peerDependenciesMeta": { - "supports-color": { + "@seekdb/default-embed": { "optional": true } } }, - "node_modules/deep-eql": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", - "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", - "dev": true, - "license": "MIT", + "node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=6" + "node": ">=10" } }, - "node_modules/es-module-lexer": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", - "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", - "dev": true, - "license": "MIT" - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" }, "engines": { - "node": ">=12" + "node": ">= 18" }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dev": true, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/expect-type": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", - "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", - "dev": true, - "license": "Apache-2.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, "engines": { - "node": ">=12.0.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/loupe": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", - "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/magic-string": { - "version": "0.30.21", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", - "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.5" + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/nanoid": { - "version": "3.3.11", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", - "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/pathval": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", - "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", - "dev": true, + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, "engines": { - "node": ">= 14.16" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", "dev": true, "license": "ISC" }, - "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", - "dev": true, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", "funding": [ { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" + "type": "github", + "url": "https://github.com/sponsors/feross" }, { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" + "type": "patreon", + "url": "https://www.patreon.com/feross" }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ { "type": "github", - "url": "https://github.com/sponsors/ai" + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.11", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", "engines": { - "node": "^10 || ^12 || >=14" + "node": ">= 6.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/rollup": { - "version": "4.59.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.59.0.tgz", - "integrity": "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg==", - "dev": true, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", "license": "MIT", "dependencies": { - "@types/estree": "1.0.8" - }, - "bin": { - "rollup": "dist/bin/rollup" + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" }, "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.59.0", - "@rollup/rollup-android-arm64": "4.59.0", - "@rollup/rollup-darwin-arm64": "4.59.0", - "@rollup/rollup-darwin-x64": "4.59.0", - "@rollup/rollup-freebsd-arm64": "4.59.0", - "@rollup/rollup-freebsd-x64": "4.59.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", - "@rollup/rollup-linux-arm-musleabihf": "4.59.0", - "@rollup/rollup-linux-arm64-gnu": "4.59.0", - "@rollup/rollup-linux-arm64-musl": "4.59.0", - "@rollup/rollup-linux-loong64-gnu": "4.59.0", - "@rollup/rollup-linux-loong64-musl": "4.59.0", - "@rollup/rollup-linux-ppc64-gnu": "4.59.0", - "@rollup/rollup-linux-ppc64-musl": "4.59.0", - "@rollup/rollup-linux-riscv64-gnu": "4.59.0", - "@rollup/rollup-linux-riscv64-musl": "4.59.0", - "@rollup/rollup-linux-s390x-gnu": "4.59.0", - "@rollup/rollup-linux-x64-gnu": "4.59.0", - "@rollup/rollup-linux-x64-musl": "4.59.0", - "@rollup/rollup-openbsd-x64": "4.59.0", - "@rollup/rollup-openharmony-arm64": "4.59.0", - "@rollup/rollup-win32-arm64-msvc": "4.59.0", - "@rollup/rollup-win32-ia32-msvc": "4.59.0", - "@rollup/rollup-win32-x64-gnu": "4.59.0", - "@rollup/rollup-win32-x64-msvc": "4.59.0", - "fsevents": "~2.3.2" + "engines": { + "node": ">= 14" } }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true, - "license": "ISC" + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } }, "node_modules/source-map-js": { "version": "1.2.1", @@ -1223,6 +5071,108 @@ "node": ">=0.10.0" } }, + "node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "license": "ISC", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/sql-escaper": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/sql-escaper/-/sql-escaper-1.3.3.tgz", + "integrity": "sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw==", + "license": "MIT", + "engines": { + "bun": ">=1.0.0", + "deno": ">=2.0.0", + "node": ">=12.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/mysqljs/sql-escaper?sponsor=1" + } + }, + "node_modules/sqlite-vec": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/sqlite-vec/-/sqlite-vec-0.1.9.tgz", + "integrity": "sha512-L7XJWRIBNvR9O5+vh1FQ+IGkh/3D2AzVksW5gdtk28m78Hy8skFD0pqReKH1Yp0/BUKRGcffgKvyO/EON5JXpA==", + "license": "MIT OR Apache", + "optionalDependencies": { + "sqlite-vec-darwin-arm64": "0.1.9", + "sqlite-vec-darwin-x64": "0.1.9", + "sqlite-vec-linux-arm64": "0.1.9", + "sqlite-vec-linux-x64": "0.1.9", + "sqlite-vec-windows-x64": "0.1.9" + } + }, + "node_modules/sqlite-vec-darwin-arm64": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/sqlite-vec-darwin-arm64/-/sqlite-vec-darwin-arm64-0.1.9.tgz", + "integrity": "sha512-jSsZpE42OfBkGL/ItyJTVCUwl6o6Ka3U5rc4j+UBDIQzC1ulSSKMEhQLthsOnF/MdAf1MuAkYhkdKmmcjaIZQg==", + "cpu": [ + "arm64" + ], + "license": "MIT OR Apache", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/sqlite-vec-darwin-x64": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/sqlite-vec-darwin-x64/-/sqlite-vec-darwin-x64-0.1.9.tgz", + "integrity": "sha512-KDlVyqQT7pnOhU1ymB9gs7dMbSoVmKHitT+k1/xkjarcX8bBqPxWrGlK/R+C5WmWkfvWwyq5FfXfiBYCBs6PlA==", + "cpu": [ + "x64" + ], + "license": "MIT OR Apache", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/sqlite-vec-linux-arm64": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/sqlite-vec-linux-arm64/-/sqlite-vec-linux-arm64-0.1.9.tgz", + "integrity": "sha512-5wXVJ9c9kR4CHm/wVqXb/R+XUHTdpZ4nWbPHlS+gc9qQFVHs92Km4bPnCKX4rtcPMzvNis+SIzMJR1SCEwpuUw==", + "cpu": [ + "arm64" + ], + "license": "MIT OR Apache", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/sqlite-vec-linux-x64": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/sqlite-vec-linux-x64/-/sqlite-vec-linux-x64-0.1.9.tgz", + "integrity": "sha512-w3tCH8xK2finW8fQJ/m8uqKodXUZ9KAuAar2UIhz4BHILfpE0WM/MTGCRfa7RjYbrYim5Luk3guvMOGI7T7JQA==", + "cpu": [ + "x64" + ], + "license": "MIT OR Apache", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/sqlite-vec-windows-x64": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/sqlite-vec-windows-x64/-/sqlite-vec-windows-x64-0.1.9.tgz", + "integrity": "sha512-y3gEIyy/17bq2QFPQOWLE68TYWcRZkBQVA2XLrTPHNTOp55xJi/BBBmOm40tVMDMjtP+Elpk6UBUXdaq+46b0Q==", + "cpu": [ + "x64" + ], + "license": "MIT OR Apache", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -1230,6 +5180,15 @@ "dev": true, "license": "MIT" }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/std-env": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", @@ -1237,6 +5196,64 @@ "dev": true, "license": "MIT" }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strnum": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.3.tgz", + "integrity": "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/tinybench": { "version": "2.9.0", "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", @@ -1281,6 +5298,53 @@ "node": ">=14.0.0" } }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-algebra": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz", + "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==", + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", @@ -1295,13 +5359,58 @@ "node": ">=14.17" } }, + "node_modules/undici": { + "version": "7.25.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz", + "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==", + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, "license": "MIT" }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/vite": { "version": "5.4.21", "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", @@ -1451,6 +5560,15 @@ } } }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, "node_modules/why-is-node-running": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", @@ -1467,6 +5585,60 @@ "engines": { "node": ">=8" } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.20.0.tgz", + "integrity": "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } } } } diff --git a/package.json b/package.json index b03200c..5e96318 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,15 @@ { "name": "memory-powermem", - "version": "1.0.0", - "description": "OpenClaw plugin: long-term memory via PowerMem (default local CLI; optional HTTP server; intelligent extraction, Ebbinghaus forgetting curve).", + "version": "0.4.0", + "description": "OpenClaw plugin: long-term memory via PowerMem (default local CLI: npm powermem or pmem on PATH; optional HTTP server; intelligent extraction, Ebbinghaus forgetting curve).", "type": "module", - "main": "index.ts", + "main": "src/index.ts", "exports": { - ".": "./index.ts" + ".": "./src/index.ts" }, "files": [ - "index.ts", - "config.ts", - "client.ts", - "client-cli.ts", - "openclaw-powermem-env.ts", + "src", + "lib", "openclaw.plugin.json" ], "scripts": { @@ -20,7 +17,12 @@ "lint": "tsc --noEmit" }, "dependencies": { - "@sinclair/typebox": "^0.34.0" + "@langchain/openai": "^1.4.1", + "@mariozechner/pi-ai": "^0.67.2", + "@sinclair/typebox": "^0.34.0", + "better-sqlite3": "^12.9.0", + "powermem": "^0.1.1", + "sqlite-vec": "^0.1.9" }, "devDependencies": { "@types/node": "^22.0.0", @@ -31,11 +33,20 @@ "openclaw": ">=2026.1.0" }, "peerDependenciesMeta": { - "openclaw": { "optional": true } + "openclaw": { + "optional": true + } }, "openclaw": { - "extensions": ["./index.ts"] + "extensions": [ + "./src/index.ts" + ] }, "repository": "", - "license": "Apache-2.0" + "license": "Apache-2.0", + "pnpm": { + "onlyBuiltDependencies": [ + "better-sqlite3" + ] + } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..5ab4cef --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,6143 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@langchain/openai': + specifier: ^1.4.1 + version: 1.4.4(@langchain/core@1.1.39(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0))(ws@8.20.0) + '@mariozechner/pi-ai': + specifier: ^0.67.2 + version: 0.67.2(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@sinclair/typebox': + specifier: ^0.34.0 + version: 0.34.48 + better-sqlite3: + specifier: ^12.9.0 + version: 12.9.0 + openclaw: + specifier: '>=2026.1.0' + version: 2026.3.23(@cfworker/json-schema@4.1.1)(@napi-rs/canvas@0.1.97) + powermem: + specifier: ^0.1.1 + version: 0.1.1(@langchain/openai@1.4.4(@langchain/core@1.1.39(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0))(ws@8.20.0))(@types/node@22.19.15)(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0) + sqlite-vec: + specifier: ^0.1.9 + version: 0.1.9 + devDependencies: + '@types/node': + specifier: ^22.0.0 + version: 22.19.15 + typescript: + specifier: ^5.0.0 + version: 5.9.3 + vitest: + specifier: ^2.0.0 + version: 2.1.9(@types/node@22.19.15) + +packages: + + '@agentclientprotocol/sdk@0.16.1': + resolution: {integrity: sha512-1ad+Sc/0sCtZGHthxxvgEUo5Wsbw16I+aF+YwdiLnPwkZG8KAGUEAPK6LM6Pf69lCyJPt1Aomk1d+8oE3C4ZEw==} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + '@anthropic-ai/sdk@0.73.0': + resolution: {integrity: sha512-URURVzhxXGJDGUGFunIOtBlSl7KWvZiAAKY/ttTkZAkXT9bTPqdk2eK0b8qqSxXpikh3QKPnPYpiyX98zf5ebw==} + hasBin: true + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + + '@anthropic-ai/sdk@0.80.0': + resolution: {integrity: sha512-WeXLn7zNVk3yjeshn+xZHvld6AoFUOR3Sep6pSoHho5YbSi6HwcirqgPA5ccFuW8QTVJAAU7N8uQQC6Wa9TG+g==} + hasBin: true + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + + '@anthropic-ai/vertex-sdk@0.14.4': + resolution: {integrity: sha512-BZUPRWghZxfSFtAxU563wH+jfWBPoedAwsVxG35FhmNsjeV8tyfN+lFriWhCpcZApxA4NdT6Soov+PzfnxxD5g==} + + '@aws-crypto/crc32@5.2.0': + resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/sha256-browser@5.2.0': + resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} + + '@aws-crypto/sha256-js@5.2.0': + resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/supports-web-crypto@5.2.0': + resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} + + '@aws-crypto/util@5.2.0': + resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} + + '@aws-sdk/client-bedrock-runtime@3.1015.0': + resolution: {integrity: sha512-At8Ex5NXj3xjDHCyu/savuu8RTTbLBohaZGvll6DIi0kOXmI/P6T0+oKkRnHFOeKmlNWkeHD2z4vEjNnSMgonw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/client-bedrock@3.1015.0': + resolution: {integrity: sha512-YTmbADMdEP4bWiGi1EZ5/5CNuzo2ZhLucJge4GZ5blOnd3qlAsQ6au1+1A/hmAlYOM4tg+z6m40WHncGd6Tatw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/core@3.973.24': + resolution: {integrity: sha512-vvf82RYQu2GidWAuQq+uIzaPz9V0gSCXVqdVzRosgl5rXcspXOpSD3wFreGGW6AYymPr97Z69kjVnLePBxloDw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-env@3.972.22': + resolution: {integrity: sha512-cXp0VTDWT76p3hyK5D51yIKEfpf6/zsUvMfaB8CkyqadJxMQ8SbEeVroregmDlZbtG31wkj9ei0WnftmieggLg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-http@3.972.24': + resolution: {integrity: sha512-h694K7+tRuepSRJr09wTvQfaEnjzsKZ5s7fbESrVds02GT/QzViJ94/HCNwM7bUfFxqpPXHxulZfL6Cou0dwPg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-ini@3.972.24': + resolution: {integrity: sha512-O46fFmv0RDFWiWEA9/e6oW92BnsyAXuEgTTasxHligjn2RCr9L/DK773m/NoFaL3ZdNAUz8WxgxunleMnHAkeQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-login@3.972.24': + resolution: {integrity: sha512-sIk8oa6AzDoUhxsR11svZESqvzGuXesw62Rl2oW6wguZx8i9cdGCvkFg+h5K7iucUZP8wyWibUbJMc+J66cu5g==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-node@3.972.25': + resolution: {integrity: sha512-m7dR0Dsva2P+VUpL+VkC0WwiDby5pgmWXkRVDB5rlwv0jXJrQJf7YMtCoM8Wjk0H9jPeCYOxOXXcIgp/qp5Alg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-process@3.972.22': + resolution: {integrity: sha512-Os32s8/4gTZjBk5BtoS/cuTILaj+K72d0dVG7TCJX/fC4598cxwLDmf1AEHEpER5oL3K//yETjvFaz0V8oO5Xw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-sso@3.972.24': + resolution: {integrity: sha512-PaFv7snEfypU2yXkpvfyWgddEbDLtgVe51wdZlinhc2doubBjUzJZZpgwuF2Jenl1FBydMhNpMjD6SBUM3qdSA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.972.24': + resolution: {integrity: sha512-J6H4R1nvr3uBTqD/EeIPAskrBtET4WFfNhpFySr2xW7bVZOXpQfPjrLSIx65jcNjBmLXzWq8QFLdVoGxiGG/SA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/eventstream-handler-node@3.972.11': + resolution: {integrity: sha512-2IrLrOruRr1NhTK0vguBL1gCWv1pu4bf4KaqpsA+/vCJpFEbvXFawn71GvCzk1wyjnDUsemtKypqoKGv4cSGbA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-eventstream@3.972.8': + resolution: {integrity: sha512-r+oP+tbCxgqXVC3pu3MUVePgSY0ILMjA+aEwOosS77m3/DRbtvHrHwqvMcw+cjANMeGzJ+i0ar+n77KXpRA8RQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-host-header@3.972.8': + resolution: {integrity: sha512-wAr2REfKsqoKQ+OkNqvOShnBoh+nkPurDKW7uAeVSu6kUECnWlSJiPvnoqxGlfousEY/v9LfS9sNc46hjSYDIQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-logger@3.972.8': + resolution: {integrity: sha512-CWl5UCM57WUFaFi5kB7IBY1UmOeLvNZAZ2/OZ5l20ldiJ3TiIz1pC65gYj8X0BCPWkeR1E32mpsCk1L1I4n+lA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-recursion-detection@3.972.8': + resolution: {integrity: sha512-BnnvYs2ZEpdlmZ2PNlV2ZyQ8j8AEkMTjN79y/YA475ER1ByFYrkVR85qmhni8oeTaJcDqbx364wDpitDAA/wCA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-user-agent@3.972.25': + resolution: {integrity: sha512-QxiMPofvOt8SwSynTOmuZfvvPM1S9QfkESBxB22NMHTRXCJhR5BygLl8IXfC4jELiisQgwsgUby21GtXfX3f/g==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-websocket@3.972.13': + resolution: {integrity: sha512-Gp6EWIqHX5wmsOR5ZxWyyzEU8P0xBdSxkm6VHEwXwBqScKZ7QWRoj6ZmHpr+S44EYb5tuzGya4ottsogSu2W3A==} + engines: {node: '>= 14.0.0'} + + '@aws-sdk/nested-clients@3.996.14': + resolution: {integrity: sha512-fSESKvh1VbfjtV3QMnRkCPZWkUbQof6T/DOpiLp33yP2wA+rbwwnZeG3XT3Ekljgw2I8X4XaQPnw+zSR8yxJ5Q==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/region-config-resolver@3.972.9': + resolution: {integrity: sha512-eQ+dFU05ZRC/lC2XpYlYSPlXtX3VT8sn5toxN2Fv7EXlMoA2p9V7vUBKqHunfD4TRLpxUq8Y8Ol/nCqiv327Ng==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1015.0': + resolution: {integrity: sha512-3OSD4y110nisRhHzFOjoEeHU4GQL4KpzkX9PxzWaiZe0Yg2+thZKM0Pn9DjYwezH5JYfh/K++xK/SE0IHGrmCQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/types@3.973.6': + resolution: {integrity: sha512-Atfcy4E++beKtwJHiDln2Nby8W/mam64opFPTiHEqgsthqeydFS1pY+OUlN1ouNOmf8ArPU/6cDS65anOP3KQw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-endpoints@3.996.5': + resolution: {integrity: sha512-Uh93L5sXFNbyR5sEPMzUU8tJ++Ku97EY4udmC01nB8Zu+xfBPwpIwJ6F7snqQeq8h2pf+8SGN5/NoytfKgYPIw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-format-url@3.972.8': + resolution: {integrity: sha512-J6DS9oocrgxM8xlUTTmQOuwRF6rnAGEujAN9SAzllcrQmwn5iJ58ogxy3SEhD0Q7JZvlA5jvIXBkpQRqEqlE9A==} + 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.8': + resolution: {integrity: sha512-B3KGXJviV2u6Cdw2SDY2aDhoJkVfY/Q/Trwk2CMSkikE1Oi6gRzxhvhIfiRpHfmIsAhV4EA54TVEX8K6CbHbkA==} + + '@aws-sdk/util-user-agent-node@3.973.11': + resolution: {integrity: sha512-1qdXbXo2s5MMLpUvw00284LsbhtlQ4ul7Zzdn5n+7p4WVgCMLqhxImpHIrjSoc72E/fyc4Wq8dLtUld2Gsh+lA==} + engines: {node: '>=20.0.0'} + peerDependencies: + aws-crt: '>=1.0.0' + peerDependenciesMeta: + aws-crt: + optional: true + + '@aws-sdk/xml-builder@3.972.15': + resolution: {integrity: sha512-PxMRlCFNiQnke9YR29vjFQwz4jq+6Q04rOVFeTDR2K7Qpv9h9FOWOxG+zJjageimYbWqE3bTuLjmryWHAWbvaA==} + engines: {node: '>=20.0.0'} + + '@aws/lambda-invoke-store@0.2.4': + resolution: {integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==} + engines: {node: '>=18.0.0'} + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@borewit/text-codec@0.2.2': + resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} + + '@cfworker/json-schema@4.1.1': + resolution: {integrity: sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==} + + '@clack/core@1.1.0': + resolution: {integrity: sha512-SVcm4Dqm2ukn64/8Gub2wnlA5nS2iWJyCkdNHcvNHPIeBTGojpdJ+9cZKwLfmqy7irD4N5qLteSilJlE0WLAtA==} + + '@clack/prompts@1.1.0': + resolution: {integrity: sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g==} + + '@emnapi/runtime@1.9.1': + resolution: {integrity: sha512-VYi5+ZVLhpgK4hQ0TAjiQiZ6ol0oe4mBx7mVv7IflsiEp0OWoVsp/+f9Vc1hOhE0TtkORVrI1GvzyreqpgWtkA==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@google/genai@1.46.0': + resolution: {integrity: sha512-ewPMN5JkKfgU5/kdco9ZhXBHDPhVqZpMQqIFQhwsHLf8kyZfx1cNpw1pHo1eV6PGEW7EhIBFi3aYZraFndAXqg==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.25.2 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + + '@homebridge/ciao@1.3.5': + resolution: {integrity: sha512-f7MAw7YuoEYgJEQ1VyRcLHGuVmCpmXi65GVR8CAtPWPqIZf/HFr4vHzVpOfQMpEQw9Pt5uh07guuLt5HE8ruog==} + hasBin: true + + '@hono/node-server@1.19.11': + resolution: {integrity: sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@langchain/core@1.1.39': + resolution: {integrity: sha512-DP9c7TREy6iA7HnywstmUAsNyJNYTFpRg2yBfQ+6H0l1HnvQzei9GsQ36GeOLxgRaD3vm9K8urCcawSC7yQpCw==} + engines: {node: '>=20'} + + '@langchain/openai@1.4.4': + resolution: {integrity: sha512-mRr/X5rvlwPj6cSXPxbL+CtOqYANO1/+CQ3Z+5t48kWnrlgPYOazmA+UAWvqQOuwJ6LaYn3SFrt43rR4lte/Ow==} + engines: {node: '>=20'} + peerDependencies: + '@langchain/core': ^1.1.39 + + '@line/bot-sdk@10.6.0': + resolution: {integrity: sha512-4hSpglL/G/cW2JCcohaYz/BS0uOSJNV9IEYdMm0EiPEvDLayoI2hGq2D86uYPQFD2gvgkyhmzdShpWLG3P5r3w==} + engines: {node: '>=20'} + + '@lydell/node-pty-darwin-arm64@1.2.0-beta.3': + resolution: {integrity: sha512-owcv+e1/OSu3bf9ZBdUQqJsQF888KyuSIiPYFNn0fLhgkhm9F3Pvha76Kj5mCPnodf7hh3suDe7upw7GPRXftQ==} + cpu: [arm64] + os: [darwin] + + '@lydell/node-pty-darwin-x64@1.2.0-beta.3': + resolution: {integrity: sha512-k38O+UviWrWdxtqZBBc/D8NJU11Rey8Y2YMwSWNxLv3eXZZdF5IVpbBkI/2RmLsV5nCcciqLPbukxeZnEfPlwA==} + cpu: [x64] + os: [darwin] + + '@lydell/node-pty-linux-arm64@1.2.0-beta.3': + resolution: {integrity: sha512-HUwRpGu3O+4sv9DAQFKnyW5LYhyYu2SDUa/bdFO/t4dIFCM4uDJEq47wfRM7+aYtJTi1b3lakN8SlWeuFQqJQQ==} + cpu: [arm64] + os: [linux] + + '@lydell/node-pty-linux-x64@1.2.0-beta.3': + resolution: {integrity: sha512-+RRY0PoCUeQaCvPR7/UnkGbxulwbFtoTWJfe+o4T1RcNtngrgaI55I9nl8CD8uqhGrB3smKuyvPM5UtwGhASUw==} + cpu: [x64] + os: [linux] + + '@lydell/node-pty-win32-arm64@1.2.0-beta.3': + resolution: {integrity: sha512-UEDd9ASp2M3iIYpIzfmfBlpyn4+K1G4CAjYcHWStptCkefoSVXWTiUBIa1KjBjZi3/xmsHIDpBEYTkGWuvLt2Q==} + cpu: [arm64] + os: [win32] + + '@lydell/node-pty-win32-x64@1.2.0-beta.3': + resolution: {integrity: sha512-TpdqSFYx7/Rj+68tuP6F/lkRYrHCYAIJgaS1bx3SctTkb5QAQCFwOKHd4xlsivmEOMT2LdhkJggPxwX9PAO5pQ==} + cpu: [x64] + os: [win32] + + '@lydell/node-pty@1.2.0-beta.3': + resolution: {integrity: sha512-ngGAItlRhmJXrhspxt8kX13n1dVFqzETOq0m/+gqSkO8NJBvNMwP7FZckMwps2UFySdr4yxCXNGu/bumg5at6A==} + + '@mariozechner/clipboard-darwin-arm64@0.3.2': + resolution: {integrity: sha512-uBf6K7Je1ihsgvmWxA8UCGCeI+nbRVRXoarZdLjl6slz94Zs1tNKFZqx7aCI5O1i3e0B6ja82zZ06BWrl0MCVw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@mariozechner/clipboard-darwin-universal@0.3.2': + resolution: {integrity: sha512-mxSheKTW2U9LsBdXy0SdmdCAE5HqNS9QUmpNHLnfJ+SsbFKALjEZc5oRrVMXxGQSirDvYf5bjmRyT0QYYonnlg==} + engines: {node: '>= 10'} + os: [darwin] + + '@mariozechner/clipboard-darwin-x64@0.3.2': + resolution: {integrity: sha512-U1BcVEoidvwIp95+HJswSW+xr28EQiHR7rZjH6pn8Sja5yO4Yoe3yCN0Zm8Lo72BbSOK/fTSq0je7CJpaPCspg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@mariozechner/clipboard-linux-arm64-gnu@0.3.2': + resolution: {integrity: sha512-BsinwG3yWTIjdgNCxsFlip7LkfwPk+ruw/aFCXHUg/fb5XC/Ksp+YMQ7u0LUtiKzIv/7LMXgZInJQH6gxbAaqQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@mariozechner/clipboard-linux-arm64-musl@0.3.2': + resolution: {integrity: sha512-0/Gi5Xq2V6goXBop19ePoHvXsmJD9SzFlO3S+d6+T2b+BlPcpOu3Oa0wTjl+cZrLAAEzA86aPNBI+VVAFDFPKw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@mariozechner/clipboard-linux-riscv64-gnu@0.3.2': + resolution: {integrity: sha512-2AFFiXB24qf0zOZsxI1GJGb9wQGlOJyN6UwoXqmKS3dpQi/l6ix30IzDDA4c4ZcCcx4D+9HLYXhC1w7Sov8pXA==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + + '@mariozechner/clipboard-linux-x64-gnu@0.3.2': + resolution: {integrity: sha512-v6fVnsn7WMGg73Dab8QMwyFce7tzGfgEixKgzLP8f1GJqkJZi5zO4k4FOHzSgUufgLil63gnxvMpjWkgfeQN7A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@mariozechner/clipboard-linux-x64-musl@0.3.2': + resolution: {integrity: sha512-xVUtnoMQ8v2JVyfJLKKXACA6avdnchdbBkTsZs8BgJQo29qwCp5NIHAUO8gbJ40iaEGToW5RlmVk2M9V0HsHEw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@mariozechner/clipboard-win32-arm64-msvc@0.3.2': + resolution: {integrity: sha512-AEgg95TNi8TGgak2wSXZkXKCvAUTjWoU1Pqb0ON7JHrX78p616XUFNTJohtIon3e0w6k0pYPZeCuqRCza/Tqeg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@mariozechner/clipboard-win32-x64-msvc@0.3.2': + resolution: {integrity: sha512-tGRuYpZwDOD7HBrCpyRuhGnHHSCknELvqwKKUG4JSfSB7JIU7LKRh6zx6fMUOQd8uISK35TjFg5UcNih+vJhFA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@mariozechner/clipboard@0.3.2': + resolution: {integrity: sha512-IHQpksNjo7EAtGuHFU+tbWDp5LarH3HU/8WiB9O70ZEoBPHOg0/6afwSLK0QyNMMmx4Bpi/zl6+DcBXe95nWYA==} + engines: {node: '>= 10'} + + '@mariozechner/jiti@2.6.5': + resolution: {integrity: sha512-faGUlTcXka5l7rv0lP3K3vGW/ejRuOS24RR2aSFWREUQqzjgdsuWNo/IiPqL3kWRGt6Ahl2+qcDAwtdeWeuGUw==} + hasBin: true + + '@mariozechner/pi-agent-core@0.61.1': + resolution: {integrity: sha512-ELZsyx6INGBYXPAbYTAiRWtkmnwAlcXOOVPY434BE605TBdpzMrXF5gNckKdEyCCWYJiLzSKpHaAzWwB7Vx2nA==} + engines: {node: '>=20.0.0'} + + '@mariozechner/pi-ai@0.61.1': + resolution: {integrity: sha512-BOk8xwluIgauX93qgC9qyrWteKKnk6pNDM8szE1m/EJKMhcJ/jIJpgAUQgj4yXiwSMtcZm30h2Po97gqqXTIIg==} + engines: {node: '>=20.0.0'} + hasBin: true + + '@mariozechner/pi-ai@0.67.2': + resolution: {integrity: sha512-2RZD5GYj1WjLww/m6jN4BIJiJ9qOZLsq4jBecdcnMKOpnxUXYzEAYN8wfRR1H5+5cGOY2AfNkXU3AnPOkiL9Eg==} + engines: {node: '>=20.0.0'} + hasBin: true + + '@mariozechner/pi-coding-agent@0.61.1': + resolution: {integrity: sha512-w0QTn+LFFdyFhpaaYDOacGwBjW4MKYrl40b6LPfKDuVJ+9fDfHl3kWkbx6xJb9brk6M5lEFMheC82UIQdkeK3Q==} + engines: {node: '>=20.6.0'} + hasBin: true + + '@mariozechner/pi-tui@0.61.1': + resolution: {integrity: sha512-J3EI1gU5knUf1dXiHJsimDP4IRXLG7QJ1NVykU/yWOJoBPAgG6/qjjPPRcaUA7MYMUfKi+Z/zzGOyQSCVAajPA==} + engines: {node: '>=20.0.0'} + + '@mistralai/mistralai@1.14.1': + resolution: {integrity: sha512-IiLmmZFCCTReQgPAT33r7KQ1nYo5JPdvGkrkZqA8qQ2qB1GHgs5LoP5K2ICyrjnpw2n8oSxMM/VP+liiKcGNlQ==} + + '@modelcontextprotocol/sdk@1.27.1': + resolution: {integrity: sha512-sr6GbP+4edBwFndLbM60gf07z0FQ79gaExpnsjMGePXqFcSSb7t6iscpjk9DhFhwd+mTEQrzNafGP8/iGGFYaA==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@mozilla/readability@0.6.0': + resolution: {integrity: sha512-juG5VWh4qAivzTAeMzvY9xs9HY5rAcr2E4I7tiSSCokRFi7XIZCAu92ZkSTsIj1OPceCifL3cpfteP3pDT9/QQ==} + engines: {node: '>=14.0.0'} + + '@napi-rs/canvas-android-arm64@0.1.97': + resolution: {integrity: sha512-V1c/WVw+NzH8vk7ZK/O8/nyBSCQimU8sfMsB/9qeSvdkGKNU7+mxy/bIF0gTgeBFmHpj30S4E9WHMSrxXGQuVQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [android] + + '@napi-rs/canvas-darwin-arm64@0.1.97': + resolution: {integrity: sha512-ok+SCEF4YejcxuJ9Rm+WWunHHpf2HmiPxfz6z1a/NFQECGXtsY7A4B8XocK1LmT1D7P174MzwPF9Wy3AUAwEPw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@napi-rs/canvas-darwin-x64@0.1.97': + resolution: {integrity: sha512-PUP6e6/UGlclUvAQNnuXCcnkpdUou6VYZfQOQxExLp86epOylmiwLkqXIvpFmjoTEDmPmXrI+coL/9EFU1gKPA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.97': + resolution: {integrity: sha512-XyXH2L/cic8eTNtbrXCcvqHtMX/nEOxN18+7rMrAM2XtLYC/EB5s0wnO1FsLMWmK+04ZSLN9FBGipo7kpIkcOw==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@napi-rs/canvas-linux-arm64-gnu@0.1.97': + resolution: {integrity: sha512-Kuq/M3djq0K8ktgz6nPlK7Ne5d4uWeDxPpyKWOjWDK2RIOhHVtLtyLiJw2fuldw7Vn4mhw05EZXCEr4Q76rs9w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@napi-rs/canvas-linux-arm64-musl@0.1.97': + resolution: {integrity: sha512-kKmSkQVnWeqg7qdsiXvYxKhAFuHz3tkBjW/zyQv5YKUPhotpaVhpBGv5LqCngzyuRV85SXoe+OFj+Tv0a0QXkQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@napi-rs/canvas-linux-riscv64-gnu@0.1.97': + resolution: {integrity: sha512-Jc7I3A51jnEOIAXeLsN/M/+Z28LUeakcsXs07FLq9prXc0eYOtVwsDEv913Gr+06IRo34gJJVgT0TXvmz+N2VA==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + + '@napi-rs/canvas-linux-x64-gnu@0.1.97': + resolution: {integrity: sha512-iDUBe7AilfuBSRbSa8/IGX38Mf+iCSBqoVKLSQ5XaY2JLOaqz1TVyPFEyIck7wT6mRQhQt5sN6ogfjIDfi74tg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@napi-rs/canvas-linux-x64-musl@0.1.97': + resolution: {integrity: sha512-AKLFd/v0Z5fvgqBDqhvqtAdx+fHMJ5t9JcUNKq4FIZ5WH+iegGm8HPdj00NFlCSnm83Fp3Ln8I2f7uq1aIiWaA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@napi-rs/canvas-win32-arm64-msvc@0.1.97': + resolution: {integrity: sha512-u883Yr6A6fO7Vpsy9YE4FVCIxzzo5sO+7pIUjjoDLjS3vQaNMkVzx5bdIpEL+ob+gU88WDK4VcxYMZ6nmnoX9A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@napi-rs/canvas-win32-x64-msvc@0.1.97': + resolution: {integrity: sha512-sWtD2EE3fV0IzN+iiQUqr/Q1SwqWhs2O1FKItFlxtdDkikpEj5g7DKQpY3x55H/MAOnL8iomnlk3mcEeGiUMoQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@napi-rs/canvas@0.1.97': + resolution: {integrity: sha512-8cFniXvrIEnVwuNSRCW9wirRZbHvrD3JVujdS2P5n5xiJZNZMOZcfOvJ1pb66c7jXMKHHglJEDVJGbm8XWFcXQ==} + engines: {node: '>= 10'} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@rollup/rollup-android-arm-eabi@4.60.0': + resolution: {integrity: sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.60.0': + resolution: {integrity: sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.60.0': + resolution: {integrity: sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.60.0': + resolution: {integrity: sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.60.0': + resolution: {integrity: sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.60.0': + resolution: {integrity: sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.60.0': + resolution: {integrity: sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.60.0': + resolution: {integrity: sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.60.0': + resolution: {integrity: sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.60.0': + resolution: {integrity: sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.60.0': + resolution: {integrity: sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.60.0': + resolution: {integrity: sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.60.0': + resolution: {integrity: sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.60.0': + resolution: {integrity: sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.60.0': + resolution: {integrity: sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.60.0': + resolution: {integrity: sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.60.0': + resolution: {integrity: sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.60.0': + resolution: {integrity: sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.60.0': + resolution: {integrity: sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.60.0': + resolution: {integrity: sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.60.0': + resolution: {integrity: sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.60.0': + resolution: {integrity: sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.60.0': + resolution: {integrity: sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.60.0': + resolution: {integrity: sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.60.0': + resolution: {integrity: sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==} + cpu: [x64] + os: [win32] + + '@seekdb/js-bindings@1.2.0': + resolution: {integrity: sha512-s8h9vhszRqRweenCP7WZcMtIGu7Cfb6H/SDp6HPv7+gqy1z+jiaeit4vF6Ji+x0TXPkkcMUX/oB299rS/MXvHA==} + engines: {node: '>=18'} + + '@silvia-odwyer/photon-node@0.3.4': + resolution: {integrity: sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA==} + + '@sinclair/typebox@0.34.48': + resolution: {integrity: sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==} + + '@smithy/abort-controller@4.2.12': + resolution: {integrity: sha512-xolrFw6b+2iYGl6EcOL7IJY71vvyZ0DJ3mcKtpykqPe2uscwtzDZJa1uVQXyP7w9Dd+kGwYnPbMsJrGISKiY/Q==} + engines: {node: '>=18.0.0'} + + '@smithy/config-resolver@4.4.13': + resolution: {integrity: sha512-iIzMC5NmOUP6WL6o8iPBjFhUhBZ9pPjpUpQYWMUFQqKyXXzOftbfK8zcQCz/jFV1Psmf05BK5ypx4K2r4Tnwdg==} + engines: {node: '>=18.0.0'} + + '@smithy/core@3.23.12': + resolution: {integrity: sha512-o9VycsYNtgC+Dy3I0yrwCqv9CWicDnke0L7EVOrZtJpjb2t0EjaEofmMrYc0T1Kn3yk32zm6cspxF9u9Bj7e5w==} + engines: {node: '>=18.0.0'} + + '@smithy/credential-provider-imds@4.2.12': + resolution: {integrity: sha512-cr2lR792vNZcYMriSIj+Um3x9KWrjcu98kn234xA6reOAFMmbRpQMOv8KPgEmLLtx3eldU6c5wALKFqNOhugmg==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-codec@4.2.12': + resolution: {integrity: sha512-FE3bZdEl62ojmy8x4FHqxq2+BuOHlcxiH5vaZ6aqHJr3AIZzwF5jfx8dEiU/X0a8RboyNDjmXjlbr8AdEyLgiA==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-browser@4.2.12': + resolution: {integrity: sha512-XUSuMxlTxV5pp4VpqZf6Sa3vT/Q75FVkLSpSSE3KkWBvAQWeuWt1msTv8fJfgA4/jcJhrbrbMzN1AC/hvPmm5A==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-config-resolver@4.3.12': + resolution: {integrity: sha512-7epsAZ3QvfHkngz6RXQYseyZYHlmWXSTPOfPmXkiS+zA6TBNo1awUaMFL9vxyXlGdoELmCZyZe1nQE+imbmV+Q==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-node@4.2.12': + resolution: {integrity: sha512-D1pFuExo31854eAvg89KMn9Oab/wEeJR6Buy32B49A9Ogdtx5fwZPqBHUlDzaCDpycTFk2+fSQgX689Qsk7UGA==} + engines: {node: '>=18.0.0'} + + '@smithy/eventstream-serde-universal@4.2.12': + resolution: {integrity: sha512-+yNuTiyBACxOJUTvbsNsSOfH9G9oKbaJE1lNL3YHpGcuucl6rPZMi3nrpehpVOVR2E07YqFFmtwpImtpzlouHQ==} + engines: {node: '>=18.0.0'} + + '@smithy/fetch-http-handler@5.3.15': + resolution: {integrity: sha512-T4jFU5N/yiIfrtrsb9uOQn7RdELdM/7HbyLNr6uO/mpkj1ctiVs7CihVr51w4LyQlXWDpXFn4BElf1WmQvZu/A==} + engines: {node: '>=18.0.0'} + + '@smithy/hash-node@4.2.12': + resolution: {integrity: sha512-QhBYbGrbxTkZ43QoTPrK72DoYviDeg6YKDrHTMJbbC+A0sml3kSjzFtXP7BtbyJnXojLfTQldGdUR0RGD8dA3w==} + engines: {node: '>=18.0.0'} + + '@smithy/invalid-dependency@4.2.12': + resolution: {integrity: sha512-/4F1zb7Z8LOu1PalTdESFHR0RbPwHd3FcaG1sI3UEIriQTWakysgJr65lc1jj6QY5ye7aFsisajotH6UhWfm/g==} + 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==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-content-length@4.2.12': + resolution: {integrity: sha512-YE58Yz+cvFInWI/wOTrB+DbvUVz/pLn5mC5MvOV4fdRUc6qGwygyngcucRQjAhiCEbmfLOXX0gntSIcgMvAjmA==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-endpoint@4.4.27': + resolution: {integrity: sha512-T3TFfUgXQlpcg+UdzcAISdZpj4Z+XECZ/cefgA6wLBd6V4lRi0svN2hBouN/be9dXQ31X4sLWz3fAQDf+nt6BA==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-retry@4.4.44': + resolution: {integrity: sha512-Y1Rav7m5CFRPQyM4CI0koD/bXjyjJu3EQxZZhtLGD88WIrBrQ7kqXM96ncd6rYnojwOo/u9MXu57JrEvu/nLrA==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-serde@4.2.15': + resolution: {integrity: sha512-ExYhcltZSli0pgAKOpQQe1DLFBLryeZ22605y/YS+mQpdNWekum9Ujb/jMKfJKgjtz1AZldtwA/wCYuKJgjjlg==} + engines: {node: '>=18.0.0'} + + '@smithy/middleware-stack@4.2.12': + resolution: {integrity: sha512-kruC5gRHwsCOuyCd4ouQxYjgRAym2uDlCvQ5acuMtRrcdfg7mFBg6blaxcJ09STpt3ziEkis6bhg1uwrWU7txw==} + engines: {node: '>=18.0.0'} + + '@smithy/node-config-provider@4.3.12': + resolution: {integrity: sha512-tr2oKX2xMcO+rBOjobSwVAkV05SIfUKz8iI53rzxEmgW3GOOPOv0UioSDk+J8OpRQnpnhsO3Af6IEBabQBVmiw==} + engines: {node: '>=18.0.0'} + + '@smithy/node-http-handler@4.5.0': + resolution: {integrity: sha512-Rnq9vQWiR1+/I6NZZMNzJHV6pZYyEHt2ZnuV3MG8z2NNenC4i/8Kzttz7CjZiHSmsN5frhXhg17z3Zqjjhmz1A==} + engines: {node: '>=18.0.0'} + + '@smithy/property-provider@4.2.12': + resolution: {integrity: sha512-jqve46eYU1v7pZ5BM+fmkbq3DerkSluPr5EhvOcHxygxzD05ByDRppRwRPPpFrsFo5yDtCYLKu+kreHKVrvc7A==} + engines: {node: '>=18.0.0'} + + '@smithy/protocol-http@5.3.12': + resolution: {integrity: sha512-fit0GZK9I1xoRlR4jXmbLhoN0OdEpa96ul8M65XdmXnxXkuMxM0Y8HDT0Fh0Xb4I85MBvBClOzgSrV1X2s1Hxw==} + engines: {node: '>=18.0.0'} + + '@smithy/querystring-builder@4.2.12': + resolution: {integrity: sha512-6wTZjGABQufekycfDGMEB84BgtdOE/rCVTov+EDXQ8NHKTUNIp/j27IliwP7tjIU9LR+sSzyGBOXjeEtVgzCHg==} + engines: {node: '>=18.0.0'} + + '@smithy/querystring-parser@4.2.12': + resolution: {integrity: sha512-P2OdvrgiAKpkPNKlKUtWbNZKB1XjPxM086NeVhK+W+wI46pIKdWBe5QyXvhUm3MEcyS/rkLvY8rZzyUdmyDZBw==} + engines: {node: '>=18.0.0'} + + '@smithy/service-error-classification@4.2.12': + resolution: {integrity: sha512-LlP29oSQN0Tw0b6D0Xo6BIikBswuIiGYbRACy5ujw/JgWSzTdYj46U83ssf6Ux0GyNJVivs2uReU8pt7Eu9okQ==} + engines: {node: '>=18.0.0'} + + '@smithy/shared-ini-file-loader@4.4.7': + resolution: {integrity: sha512-HrOKWsUb+otTeo1HxVWeEb99t5ER1XrBi/xka2Wv6NVmTbuCUC1dvlrksdvxFtODLBjsC+PHK+fuy2x/7Ynyiw==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.3.12': + resolution: {integrity: sha512-B/FBwO3MVOL00DaRSXfXfa/TRXRheagt/q5A2NM13u7q+sHS59EOVGQNfG7DkmVtdQm5m3vOosoKAXSqn/OEgw==} + engines: {node: '>=18.0.0'} + + '@smithy/smithy-client@4.12.7': + resolution: {integrity: sha512-q3gqnwml60G44FECaEEsdQMplYhDMZYCtYhMCzadCnRnnHIobZJjegmdoUo6ieLQlPUzvrMdIJUpx6DoPmzANQ==} + engines: {node: '>=18.0.0'} + + '@smithy/types@4.13.1': + resolution: {integrity: sha512-787F3yzE2UiJIQ+wYW1CVg2odHjmaWLGksnKQHUrK/lYZSEcy1msuLVvxaR/sI2/aDe9U+TBuLsXnr3vod1g0g==} + engines: {node: '>=18.0.0'} + + '@smithy/url-parser@4.2.12': + resolution: {integrity: sha512-wOPKPEpso+doCZGIlr+e1lVI6+9VAKfL4kZWFgzVgGWY2hZxshNKod4l2LXS3PRC9otH/JRSjtEHqQ/7eLciRA==} + 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==} + 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==} + engines: {node: '>=18.0.0'} + + '@smithy/util-config-provider@4.2.2': + resolution: {integrity: sha512-dWU03V3XUprJwaUIFVv4iOnS1FC9HnMHDfUrlNDSh4315v0cWyaIErP8KiqGVbf5z+JupoVpNM7ZB3jFiTejvQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-defaults-mode-browser@4.3.43': + resolution: {integrity: sha512-Qd/0wCKMaXxev/z00TvNzGCH2jlKKKxXP1aDxB6oKwSQthe3Og2dMhSayGCnsma1bK/kQX1+X7SMP99t6FgiiQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-defaults-mode-node@4.2.47': + resolution: {integrity: sha512-qSRbYp1EQ7th+sPFuVcVO05AE0QH635hycdEXlpzIahqHHf2Fyd/Zl+8v0XYMJ3cgDVPa0lkMefU7oNUjAP+DQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-endpoints@3.3.3': + resolution: {integrity: sha512-VACQVe50j0HZPjpwWcjyT51KUQ4AnsvEaQ2lKHOSL4mNLD0G9BjEniQ+yCt1qqfKfiAHRAts26ud7hBjamrwig==} + 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.12': + resolution: {integrity: sha512-Er805uFUOvgc0l8nv0e0su0VFISoxhJ/AwOn3gL2NWNY2LUEldP5WtVcRYSQBcjg0y9NfG8JYrCJaYDpupBHJQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-retry@4.2.12': + resolution: {integrity: sha512-1zopLDUEOwumjcHdJ1mwBHddubYF8GMQvstVCLC54Y46rqoHwlIU+8ZzUeaBcD+WCJHyDGSeZ2ml9YSe9aqcoQ==} + engines: {node: '>=18.0.0'} + + '@smithy/util-stream@4.5.20': + resolution: {integrity: sha512-4yXLm5n/B5SRBR2p8cZ90Sbv4zL4NKsgxdzCzp/83cXw2KxLEumt5p+GAVyRNZgQOSrzXn9ARpO0lUe8XSlSDw==} + engines: {node: '>=18.0.0'} + + '@smithy/util-uri-escape@4.2.2': + resolution: {integrity: sha512-2kAStBlvq+lTXHyAZYfJRb/DfS3rsinLiwb+69SstC9Vb0s9vNWkRwpnj918Pfi85mzi42sOqdV72OLxWAISnw==} + 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==} + engines: {node: '>=18.0.0'} + + '@smithy/uuid@1.1.2': + resolution: {integrity: sha512-O/IEdcCUKkubz60tFbGA7ceITTAJsty+lBjNoorP4Z6XRqaFb/OjQjZODophEcuq68nKm6/0r+6/lLQ+XVpk8g==} + engines: {node: '>=18.0.0'} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@telegraf/types@7.1.0': + resolution: {integrity: sha512-kGevOIbpMcIlCDeorKGpwZmdH7kHbqlk/Yj6dEpJMKEQw5lk0KVQY0OLXaCswy8GqlIVLd5625OB+rAntP9xVw==} + + '@tokenizer/inflate@0.4.1': + resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} + engines: {node: '>=18'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + + '@tootallnate/quickjs-emscripten@0.23.0': + resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/mime-types@2.1.4': + resolution: {integrity: sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==} + + '@types/node@22.19.15': + resolution: {integrity: sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==} + + '@types/node@24.12.0': + resolution: {integrity: sha512-GYDxsZi3ChgmckRT9HPU0WEhKLP08ev/Yfcq2AstjrDASOYCSXeyjDsHg4v5t4jOj7cyDX3vmprafKlWIG9MXQ==} + + '@types/retry@0.12.0': + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + + '@types/yauzl@2.10.3': + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + + '@vitest/expect@2.1.9': + resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} + + '@vitest/mocker@2.1.9': + resolution: {integrity: sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/runner@2.1.9': + resolution: {integrity: sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==} + + '@vitest/snapshot@2.1.9': + resolution: {integrity: sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==} + + '@vitest/spy@2.1.9': + resolution: {integrity: sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==} + + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + adm-zip@0.5.17: + resolution: {integrity: sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==} + engines: {node: '>=12.0'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.18.0: + resolution: {integrity: sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + aws-ssl-profiles@1.1.2: + resolution: {integrity: sha512-NZKeq9AfyQvEeNlN0zSYAaWrmBffJh3IELMZfRpJVWgrpEbtEpnjvzqBPf+mxoI287JohRDoa+/nsfqqiZmF6g==} + engines: {node: '>= 6.0.0'} + + axios@1.13.6: + resolution: {integrity: sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + basic-ftp@5.2.0: + resolution: {integrity: sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==} + engines: {node: '>=10.0.0'} + deprecated: Security vulnerability fixed in 5.2.1, please upgrade + + better-sqlite3@12.9.0: + resolution: {integrity: sha512-wqUv4Gm3toFpHDQmaKD4QhZm3g1DjUBI0yzS4UBl6lElUmXFYdTQmmEDpAFa5o8FiFiymURypEnfVHzILKaxqQ==} + engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + bowser@2.14.1: + resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + + brace-expansion@5.0.4: + resolution: {integrity: sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg==} + engines: {node: 18 || 20 || >=22} + + buffer-alloc-unsafe@1.1.0: + resolution: {integrity: sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==} + + buffer-alloc@1.2.0: + resolution: {integrity: sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==} + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + buffer-fill@1.0.0: + resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} + engines: {node: '>= 16'} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + cli-highlight@2.1.11: + resolution: {integrity: sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==} + engines: {node: '>=8.0.0', npm: '>=5.0.0'} + hasBin: true + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + croner@10.0.1: + resolution: {integrity: sha512-ixNtAJndqh173VQ4KodSdJEI6nuioBWI0V1ITNKhZZsO0pEMoDxz539T4FTTbSZ/xIOSuDnzxLVRqBVSvPNE2g==} + engines: {node: '>=18.0'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + cssom@0.5.0: + resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + data-uri-to-buffer@6.0.2: + resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} + engines: {node: '>= 14'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + degenerator@5.0.1: + resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} + engines: {node: '>= 14'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + denque@2.1.0: + resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} + engines: {node: '>=0.10'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + diff@8.0.4: + resolution: {integrity: sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==} + engines: {node: '>=0.3.1'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + + dotenv@17.3.1: + resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@7.0.1: + resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} + engines: {node: '>=0.12'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + eventsource-parser@3.0.6: + resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + express-rate-limit@8.3.1: + resolution: {integrity: sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extract-zip@2.0.1: + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fast-xml-builder@1.1.4: + resolution: {integrity: sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg==} + + fast-xml-parser@5.5.8: + resolution: {integrity: sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ==} + hasBin: true + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + file-type@21.3.4: + resolution: {integrity: sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==} + engines: {node: '>=20'} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + follow-redirects@1.15.11: + resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gaxios@6.7.1: + resolution: {integrity: sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==} + engines: {node: '>=14'} + + gaxios@7.1.4: + resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} + engines: {node: '>=18'} + + gcp-metadata@6.1.1: + resolution: {integrity: sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==} + engines: {node: '>=14'} + + gcp-metadata@8.1.2: + resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} + engines: {node: '>=18'} + + generate-function@2.3.1: + resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} + + get-caller-file@2.0.5: + 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==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-uri@6.0.5: + resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} + engines: {node: '>= 14'} + + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + + glob@13.0.6: + resolution: {integrity: sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==} + engines: {node: 18 || 20 || >=22} + + google-auth-library@10.6.2: + resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} + engines: {node: '>=18'} + + google-auth-library@9.15.1: + resolution: {integrity: sha512-Jb6Z0+nvECVz+2lzSMt9u98UsoakXxA2HGHMCxh+so3n90XgYWkq5dur19JAJV7ONiJY22yBTyJB1TSkvPq9Ng==} + engines: {node: '>=14'} + + google-logging-utils@0.0.2: + resolution: {integrity: sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==} + engines: {node: '>=14'} + + google-logging-utils@1.1.3: + resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} + engines: {node: '>=14'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + gtoken@7.1.0: + resolution: {integrity: sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==} + engines: {node: '>=14.0.0'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + hono@4.12.8: + resolution: {integrity: sha512-VJCEvtrezO1IAR+kqEYnxUOoStaQPGrCmX3j4wDTNOcD1uRPFpGlwQUIW8niPuvHXaTUxeOUl5MMDGrl+tmO9A==} + engines: {node: '>=16.9.0'} + + hosted-git-info@9.0.2: + resolution: {integrity: sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==} + engines: {node: ^20.17.0 || >=22.9.0} + + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + + htmlparser2@10.1.0: + resolution: {integrity: sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ip-address@10.1.0: + resolution: {integrity: sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipaddr.js@2.3.0: + resolution: {integrity: sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==} + engines: {node: '>= 10'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-property@1.0.2: + resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jiti@2.6.1: + resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} + hasBin: true + + jose@6.2.2: + resolution: {integrity: sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==} + + js-tiktoken@1.0.21: + resolution: {integrity: sha512-biOj/6M5qdgx5TKjDnFT1ymSpM5tbd3ylwDtrQvFQSu0Z7bBYko2dF+W/aUkXUPuk6IVpRxk/3Q2sHOzGlS36g==} + + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + + json-schema-to-ts@3.1.1: + resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} + engines: {node: '>=16'} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jszip@3.10.1: + resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} + + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + + koffi@2.15.2: + resolution: {integrity: sha512-r9tjJLVRSOhCRWdVyQlF3/Ugzeg13jlzS4czS82MAgLff4W+BcYOW7g8Y62t9O5JYjYOLAjAovAZDNlDfZNu+g==} + + langsmith@0.5.18: + resolution: {integrity: sha512-3zuZUWffTHQ+73EAwnodADtf534VNEZUpXr9jC12qyG8/IQuJET7PRsCpTb9wX2lmBspakwLUpqpj3tNm/0bVA==} + peerDependencies: + '@opentelemetry/api': '*' + '@opentelemetry/exporter-trace-otlp-proto': '*' + '@opentelemetry/sdk-trace-base': '*' + openai: '*' + ws: '>=7' + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@opentelemetry/exporter-trace-otlp-proto': + optional: true + '@opentelemetry/sdk-trace-base': + optional: true + openai: + optional: true + ws: + optional: true + + lie@3.3.0: + resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} + + linkedom@0.18.12: + resolution: {integrity: sha512-jalJsOwIKuQJSeTvsgzPe9iJzyfVaEJiEXl+25EkKevsULHvMJzpNqwvj1jOESWdmgKDiXObyjOYwlUqG7wo1Q==} + engines: {node: '>=16'} + peerDependencies: + canvas: '>= 2' + peerDependenciesMeta: + canvas: + optional: true + + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + lru-cache@11.2.7: + resolution: {integrity: sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA==} + engines: {node: 20 || >=22} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + 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'} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + markdown-it@14.1.1: + resolution: {integrity: sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==} + hasBin: true + + marked@15.0.12: + resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==} + engines: {node: '>= 18'} + hasBin: true + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + minimatch@10.2.4: + resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} + engines: {node: 18 || 20 || >=22} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + + mysql2@3.22.0: + resolution: {integrity: sha512-4jaJYBObj7FhD3lnZhqX1yDMuZN4mQNz+IolDySDXT7fbozMBpeGQNcuWXKUqo4ahkAEfkjUHPjnwuDI0/6VKw==} + engines: {node: '>= 8.0'} + peerDependencies: + '@types/node': '>= 8' + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + named-placeholders@1.1.6: + resolution: {integrity: sha512-Tz09sEL2EEuv5fFowm419c1+a/jSMiBjI9gHxVLrVdbUkkNUUfjsVYs9pVZu5oCon/kmRh9TfLEObFtkVxmY0w==} + engines: {node: '>=8.0.0'} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + + node-abi@3.89.0: + resolution: {integrity: sha512-6u9UwL0HlAl21+agMN3YAMXcKByMqwGx+pq+P76vii5f7hTPtKDp08/H9py6DY+cfDw7kQNTGEj/rly3IgbNQA==} + engines: {node: '>=10'} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-edge-tts@1.2.10: + resolution: {integrity: sha512-bV2i4XU54D45+US0Zm1HcJRkifuB3W438dWyuJEHLQdKxnuqlI1kim2MOvR6Q3XUQZvfF9PoDyR1Rt7aeXhPdQ==} + hasBin: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + node-readable-to-web-readable-stream@0.4.2: + resolution: {integrity: sha512-/cMZNI34v//jUTrI+UIo4ieHAB5EZRY/+7OmXZgBxaWBMcW2tGdceIw06RFxWxrKZ5Jp3sI2i5TsRo+CBhtVLQ==} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + openai@6.26.0: + resolution: {integrity: sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + + openai@6.34.0: + resolution: {integrity: sha512-yEr2jdGf4tVFYG6ohmr3pF6VJuveP0EA/sS8TBx+4Eq5NT10alu5zg2dmxMXMgqpihRDQlFGpRt2XwsGj+Fyxw==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + + openclaw@2026.3.23: + resolution: {integrity: sha512-CSenO9Q+WePEzhzr3vIgx70GLanQVLcwgtItxT7gy1XtE7uiAVLBTqOxn2nc6BGGX3R3u9RqOpUh/vyAPvameA==} + engines: {node: '>=22.16.0'} + hasBin: true + peerDependencies: + '@napi-rs/canvas': ^0.1.89 + node-llama-cpp: 3.16.2 + peerDependenciesMeta: + node-llama-cpp: + optional: true + + openshell@0.1.0: + resolution: {integrity: sha512-B7jLewH+d73hraWcrSFgNOjvd+frW5JPejkTpqgj2EJBjX/Yk1Y4blgP5pDl4FwrBxfmwsTKR08Uwgrdo+xpSg==} + engines: {node: '>=18'} + hasBin: true + + osc-progress@0.3.0: + resolution: {integrity: sha512-4/8JfsetakdeEa4vAYV45FW20aY+B/+K8NEXp5Eiar3wR8726whgHrbSg5Ar/ZY1FLJ/AGtUqV7W2IVF+Gvp9A==} + engines: {node: '>=20'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-queue@6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + + p-retry@4.6.2: + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} + engines: {node: '>=8'} + + p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + + p-timeout@4.1.0: + resolution: {integrity: sha512-+/wmHtzJuWii1sXn3HCuH/FTwGhrp4tmJTxSKJbfS+vkipci6osxXM5mY0jUiRzWKMTgUT8l7HFbeSwZAynqHw==} + engines: {node: '>=10'} + + pac-proxy-agent@7.2.0: + resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} + engines: {node: '>= 14'} + + pac-resolver@7.0.1: + resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} + engines: {node: '>= 14'} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + parse5-htmlparser2-tree-adapter@6.0.1: + resolution: {integrity: sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==} + + parse5@5.1.1: + resolution: {integrity: sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + partial-json@0.1.7: + resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==} + + path-expression-matcher@1.2.0: + resolution: {integrity: sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ==} + engines: {node: '>=14.0.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@2.0.2: + resolution: {integrity: sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==} + engines: {node: 18 || 20 || >=22} + + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + + pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + + pdfjs-dist@5.5.207: + resolution: {integrity: sha512-WMqqw06w1vUt9ZfT0gOFhMf3wHsWhaCrxGrckGs5Cci6ybDW87IvPaOd2pnBwT6BJuP/CzXDZxjFgmSULLdsdw==} + engines: {node: '>=20.19.0 || >=22.13.0 || >=24'} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + pg-cloudflare@1.3.0: + resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} + + pg-connection-string@2.12.0: + resolution: {integrity: sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==} + + 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==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.13.0: + resolution: {integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==} + + 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==} + engines: {node: '>= 16.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + + playwright-core@1.58.2: + resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} + engines: {node: '>=18'} + hasBin: true + + postcss@8.5.8: + resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} + engines: {node: ^10 || ^12 || >=14} + + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.1: + resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + + powermem@0.1.1: + resolution: {integrity: sha512-Qvq+Dw2sxkSr4srafJiGdLMkYeQsf9cRm41dJk+B8NmqvTHnpCvhCkhvj+J0f8ZGHToB5Lme4RvMTDCkZFdrLg==} + engines: {node: '>=18.0.0'} + hasBin: true + peerDependencies: + '@langchain/anthropic': '>=0.3.0' + '@langchain/ollama': '>=0.2.0' + '@langchain/openai': '>=0.3.0' + peerDependenciesMeta: + '@langchain/anthropic': + optional: true + '@langchain/ollama': + optional: true + '@langchain/openai': + optional: true + + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + deprecated: No longer maintained. Please contact the author of the relevant native addon; alternatives are available. + hasBin: true + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + + protobufjs@7.5.4: + resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==} + engines: {node: '>=12.0.0'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-agent@6.5.0: + resolution: {integrity: sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==} + engines: {node: '>= 14'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + qrcode-terminal@0.12.0: + resolution: {integrity: sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ==} + hasBin: true + + qs@6.15.0: + resolution: {integrity: sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==} + engines: {node: '>=0.6'} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + rollup@4.60.0: + resolution: {integrity: sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-compare@1.1.4: + resolution: {integrity: sha512-b9wZ986HHCo/HbKrRpBJb2kqXMK9CEWIE1egeEvZsYn69ay3kdfl9nG3RyOcR+jInTDf7a86WQ1d4VJX7goSSQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sandwich-stream@2.0.2: + resolution: {integrity: sha512-jLYV0DORrzY3xaz/S9ydJL6Iz7essZeAfnAavsJ+zsJGZ1MOnsS52yRjU3uF3pJa/lla7+wisp//fxOwOH8SKQ==} + engines: {node: '>= 0.10'} + + seekdb@1.2.0: + resolution: {integrity: sha512-wcEWLgmvKGPbJwD4F79wmYqKEojt60fm/balJa+p/bpRKex4OBoThFp5PaQ6Ia6/Ky7tWZE2q6kJB2nEm2hpNA==} + engines: {node: '>=20'} + peerDependencies: + '@seekdb/default-embed': ^1.2.0 + peerDependenciesMeta: + '@seekdb/default-embed': + optional: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + + socks@2.8.7: + resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sql-escaper@1.3.3: + resolution: {integrity: sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw==} + engines: {bun: '>=1.0.0', deno: '>=2.0.0', node: '>=12.0.0'} + + sqlite-vec-darwin-arm64@0.1.7: + resolution: {integrity: sha512-dQ7u4GKPdOPi3IfZ44K7HHdYup2JssM6fuKR9zgqRzW137uFOQmRhbYChNu+ZfW+yhJutsPgfNRFsuWKmy627w==} + cpu: [arm64] + os: [darwin] + + sqlite-vec-darwin-arm64@0.1.9: + resolution: {integrity: sha512-jSsZpE42OfBkGL/ItyJTVCUwl6o6Ka3U5rc4j+UBDIQzC1ulSSKMEhQLthsOnF/MdAf1MuAkYhkdKmmcjaIZQg==} + cpu: [arm64] + os: [darwin] + + sqlite-vec-darwin-x64@0.1.7: + resolution: {integrity: sha512-MDoczft1BriQcGMEz+CqeSCkB0OsAf12ytZOapS6MaB7zgNzLLSLH6Sxe3yzcPWUyDuCWgK7WzyRIo8u1vAIVA==} + cpu: [x64] + os: [darwin] + + sqlite-vec-darwin-x64@0.1.9: + resolution: {integrity: sha512-KDlVyqQT7pnOhU1ymB9gs7dMbSoVmKHitT+k1/xkjarcX8bBqPxWrGlK/R+C5WmWkfvWwyq5FfXfiBYCBs6PlA==} + cpu: [x64] + os: [darwin] + + sqlite-vec-linux-arm64@0.1.7: + resolution: {integrity: sha512-V429sYT/gwr9PgtT8rbjQd6ls7CFchFpiS45TKSf7rU7wxt9MBmCVorUcheD4kEZb4VeZ6PnFXXCqPMeaHkaUw==} + cpu: [arm64] + os: [linux] + + sqlite-vec-linux-arm64@0.1.9: + resolution: {integrity: sha512-5wXVJ9c9kR4CHm/wVqXb/R+XUHTdpZ4nWbPHlS+gc9qQFVHs92Km4bPnCKX4rtcPMzvNis+SIzMJR1SCEwpuUw==} + cpu: [arm64] + os: [linux] + + sqlite-vec-linux-x64@0.1.7: + resolution: {integrity: sha512-wZL+lXeW7y63DLv6FYU6Q4nv2lP5F94cWt7bJCWNiHmZ6NdKIgz/p0QlyuJA/51b8TyoDvsTdusLVlZz9cIh5A==} + cpu: [x64] + os: [linux] + + sqlite-vec-linux-x64@0.1.9: + resolution: {integrity: sha512-w3tCH8xK2finW8fQJ/m8uqKodXUZ9KAuAar2UIhz4BHILfpE0WM/MTGCRfa7RjYbrYim5Luk3guvMOGI7T7JQA==} + cpu: [x64] + os: [linux] + + sqlite-vec-windows-x64@0.1.7: + resolution: {integrity: sha512-FEZMjMT03irJxwqMQg+A+4hHCiFslxISOAkQ0eYn2lP7GdpppkgYveaT5Xnw/2V+GLq2MXOJb0nDGFNethHSkg==} + cpu: [x64] + os: [win32] + + sqlite-vec-windows-x64@0.1.9: + resolution: {integrity: sha512-y3gEIyy/17bq2QFPQOWLE68TYWcRZkBQVA2XLrTPHNTOp55xJi/BBBmOm40tVMDMjtP+Elpk6UBUXdaq+46b0Q==} + cpu: [x64] + os: [win32] + + sqlite-vec@0.1.7: + resolution: {integrity: sha512-1Sge9uRc3B6wDKR4J6sGFi/E2ai9SAU5FenDki3OmhdP/a49PO2Juy1U5yQnx2bZP5t+C3BYJTkG+KkDi3q9Xg==} + + sqlite-vec@0.1.9: + resolution: {integrity: sha512-L7XJWRIBNvR9O5+vh1FQ+IGkh/3D2AzVksW5gdtk28m78Hy8skFD0pqReKH1Yp0/BUKRGcffgKvyO/EON5JXpA==} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strnum@2.2.2: + resolution: {integrity: sha512-DnR90I+jtXNSTXWdwrEy9FakW7UX+qUZg28gj5fk2vxxl7uS/3bpI4fjFYVmdK9etptYBPNkpahuQnEwhwECqA==} + + strtok3@10.3.5: + resolution: {integrity: sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==} + engines: {node: '>=18'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar@7.5.12: + resolution: {integrity: sha512-9TsuLcdhOn4XztcQqhNyq1KOwOOED/3k58JAvtULiYqbO8B/0IBAAIE1hj0Svmm58k27TmcigyDI0deMlgG3uw==} + engines: {node: '>=18'} + + telegraf@4.16.3: + resolution: {integrity: sha512-yjEu2NwkHlXu0OARWoNhJlIjX09dRktiMQFsM678BAH/PEPVwctzL67+tvXqLCRQQvm3SDtki2saGO9hLlz68w==} + engines: {node: ^12.20.0 || >=14.13.1} + hasBin: true + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + token-types@6.1.2: + resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} + engines: {node: '>=14.16'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-algebra@2.0.0: + resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tslog@4.10.2: + resolution: {integrity: sha512-XuELoRpMR+sq8fuWwX7P0bcj+PRNiicOKDEb3fGNURhxWVyykCi9BNq7c4uVz7h7P0sj8qgBsr5SWS6yBClq3g==} + engines: {node: '>=16'} + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + type-is@2.0.1: + resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} + engines: {node: '>= 0.6'} + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + uhyphen@0.2.0: + resolution: {integrity: sha512-qz3o9CHXmJJPGBdqzab7qAYuW8kQGKNEuoHFYrBwV6hWIMcpAmxDLXojcHfFr9US1Pe6zUswEIJIbLI610fuqA==} + + uint8array-extras@1.5.0: + resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} + engines: {node: '>=18'} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + + undici@7.24.5: + resolution: {integrity: sha512-3IWdCpjgxp15CbJnsi/Y9TCDE7HWVN19j1hmzVhoAkY/+CJx449tVxT5wZc1Gwg8J+P0LWvzlBzxYRnHJ+1i7Q==} + engines: {node: '>=20.18.1'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + + uuid@11.1.0: + resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} + hasBin: true + + uuid@13.0.0: + resolution: {integrity: sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vite-node@2.1.9: + resolution: {integrity: sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + vitest@2.1.9: + resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.1.9 + '@vitest/ui': 2.1.9 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@2.8.3: + resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} + engines: {node: '>=18'} + + zod-to-json-schema@3.25.1: + resolution: {integrity: sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==} + peerDependencies: + zod: ^3.25 || ^4 + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + +snapshots: + + '@agentclientprotocol/sdk@0.16.1(zod@4.3.6)': + dependencies: + zod: 4.3.6 + + '@anthropic-ai/sdk@0.73.0(zod@4.3.6)': + dependencies: + json-schema-to-ts: 3.1.1 + optionalDependencies: + zod: 4.3.6 + + '@anthropic-ai/sdk@0.80.0(zod@4.3.6)': + dependencies: + json-schema-to-ts: 3.1.1 + optionalDependencies: + zod: 4.3.6 + + '@anthropic-ai/vertex-sdk@0.14.4(zod@4.3.6)': + dependencies: + '@anthropic-ai/sdk': 0.80.0(zod@4.3.6) + google-auth-library: 9.15.1 + transitivePeerDependencies: + - encoding + - supports-color + - zod + + '@aws-crypto/crc32@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.6 + tslib: 2.8.1 + + '@aws-crypto/sha256-browser@5.2.0': + dependencies: + '@aws-crypto/sha256-js': 5.2.0 + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-locate-window': 3.965.5 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-crypto/sha256-js@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.6 + tslib: 2.8.1 + + '@aws-crypto/supports-web-crypto@5.2.0': + dependencies: + tslib: 2.8.1 + + '@aws-crypto/util@5.2.0': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-sdk/client-bedrock-runtime@3.1015.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.24 + '@aws-sdk/credential-provider-node': 3.972.25 + '@aws-sdk/eventstream-handler-node': 3.972.11 + '@aws-sdk/middleware-eventstream': 3.972.8 + '@aws-sdk/middleware-host-header': 3.972.8 + '@aws-sdk/middleware-logger': 3.972.8 + '@aws-sdk/middleware-recursion-detection': 3.972.8 + '@aws-sdk/middleware-user-agent': 3.972.25 + '@aws-sdk/middleware-websocket': 3.972.13 + '@aws-sdk/region-config-resolver': 3.972.9 + '@aws-sdk/token-providers': 3.1015.0 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-endpoints': 3.996.5 + '@aws-sdk/util-user-agent-browser': 3.972.8 + '@aws-sdk/util-user-agent-node': 3.973.11 + '@smithy/config-resolver': 4.4.13 + '@smithy/core': 3.23.12 + '@smithy/eventstream-serde-browser': 4.2.12 + '@smithy/eventstream-serde-config-resolver': 4.3.12 + '@smithy/eventstream-serde-node': 4.2.12 + '@smithy/fetch-http-handler': 5.3.15 + '@smithy/hash-node': 4.2.12 + '@smithy/invalid-dependency': 4.2.12 + '@smithy/middleware-content-length': 4.2.12 + '@smithy/middleware-endpoint': 4.4.27 + '@smithy/middleware-retry': 4.4.44 + '@smithy/middleware-serde': 4.2.15 + '@smithy/middleware-stack': 4.2.12 + '@smithy/node-config-provider': 4.3.12 + '@smithy/node-http-handler': 4.5.0 + '@smithy/protocol-http': 5.3.12 + '@smithy/smithy-client': 4.12.7 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@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.43 + '@smithy/util-defaults-mode-node': 4.2.47 + '@smithy/util-endpoints': 3.3.3 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-retry': 4.2.12 + '@smithy/util-stream': 4.5.20 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/client-bedrock@3.1015.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.24 + '@aws-sdk/credential-provider-node': 3.972.25 + '@aws-sdk/middleware-host-header': 3.972.8 + '@aws-sdk/middleware-logger': 3.972.8 + '@aws-sdk/middleware-recursion-detection': 3.972.8 + '@aws-sdk/middleware-user-agent': 3.972.25 + '@aws-sdk/region-config-resolver': 3.972.9 + '@aws-sdk/token-providers': 3.1015.0 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-endpoints': 3.996.5 + '@aws-sdk/util-user-agent-browser': 3.972.8 + '@aws-sdk/util-user-agent-node': 3.973.11 + '@smithy/config-resolver': 4.4.13 + '@smithy/core': 3.23.12 + '@smithy/fetch-http-handler': 5.3.15 + '@smithy/hash-node': 4.2.12 + '@smithy/invalid-dependency': 4.2.12 + '@smithy/middleware-content-length': 4.2.12 + '@smithy/middleware-endpoint': 4.4.27 + '@smithy/middleware-retry': 4.4.44 + '@smithy/middleware-serde': 4.2.15 + '@smithy/middleware-stack': 4.2.12 + '@smithy/node-config-provider': 4.3.12 + '@smithy/node-http-handler': 4.5.0 + '@smithy/protocol-http': 5.3.12 + '@smithy/smithy-client': 4.12.7 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@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.43 + '@smithy/util-defaults-mode-node': 4.2.47 + '@smithy/util-endpoints': 3.3.3 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-retry': 4.2.12 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/core@3.973.24': + dependencies: + '@aws-sdk/types': 3.973.6 + '@aws-sdk/xml-builder': 3.972.15 + '@smithy/core': 3.23.12 + '@smithy/node-config-provider': 4.3.12 + '@smithy/property-provider': 4.2.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/signature-v4': 5.3.12 + '@smithy/smithy-client': 4.12.7 + '@smithy/types': 4.13.1 + '@smithy/util-base64': 4.3.2 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-env@3.972.22': + dependencies: + '@aws-sdk/core': 3.973.24 + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.972.24': + dependencies: + '@aws-sdk/core': 3.973.24 + '@aws-sdk/types': 3.973.6 + '@smithy/fetch-http-handler': 5.3.15 + '@smithy/node-http-handler': 4.5.0 + '@smithy/property-provider': 4.2.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/smithy-client': 4.12.7 + '@smithy/types': 4.13.1 + '@smithy/util-stream': 4.5.20 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-ini@3.972.24': + dependencies: + '@aws-sdk/core': 3.973.24 + '@aws-sdk/credential-provider-env': 3.972.22 + '@aws-sdk/credential-provider-http': 3.972.24 + '@aws-sdk/credential-provider-login': 3.972.24 + '@aws-sdk/credential-provider-process': 3.972.22 + '@aws-sdk/credential-provider-sso': 3.972.24 + '@aws-sdk/credential-provider-web-identity': 3.972.24 + '@aws-sdk/nested-clients': 3.996.14 + '@aws-sdk/types': 3.973.6 + '@smithy/credential-provider-imds': 4.2.12 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-login@3.972.24': + dependencies: + '@aws-sdk/core': 3.973.24 + '@aws-sdk/nested-clients': 3.996.14 + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-node@3.972.25': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.22 + '@aws-sdk/credential-provider-http': 3.972.24 + '@aws-sdk/credential-provider-ini': 3.972.24 + '@aws-sdk/credential-provider-process': 3.972.22 + '@aws-sdk/credential-provider-sso': 3.972.24 + '@aws-sdk/credential-provider-web-identity': 3.972.24 + '@aws-sdk/types': 3.973.6 + '@smithy/credential-provider-imds': 4.2.12 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-process@3.972.22': + dependencies: + '@aws-sdk/core': 3.973.24 + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.972.24': + dependencies: + '@aws-sdk/core': 3.973.24 + '@aws-sdk/nested-clients': 3.996.14 + '@aws-sdk/token-providers': 3.1015.0 + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/credential-provider-web-identity@3.972.24': + dependencies: + '@aws-sdk/core': 3.973.24 + '@aws-sdk/nested-clients': 3.996.14 + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/eventstream-handler-node@3.972.11': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/eventstream-codec': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-eventstream@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-host-header@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-logger@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-recursion-detection@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@aws/lambda-invoke-store': 0.2.4 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/middleware-user-agent@3.972.25': + dependencies: + '@aws-sdk/core': 3.973.24 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-endpoints': 3.996.5 + '@smithy/core': 3.23.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-retry': 4.2.12 + tslib: 2.8.1 + + '@aws-sdk/middleware-websocket@3.972.13': + dependencies: + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-format-url': 3.972.8 + '@smithy/eventstream-codec': 4.2.12 + '@smithy/eventstream-serde-browser': 4.2.12 + '@smithy/fetch-http-handler': 5.3.15 + '@smithy/protocol-http': 5.3.12 + '@smithy/signature-v4': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-base64': 4.3.2 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.996.14': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.973.24 + '@aws-sdk/middleware-host-header': 3.972.8 + '@aws-sdk/middleware-logger': 3.972.8 + '@aws-sdk/middleware-recursion-detection': 3.972.8 + '@aws-sdk/middleware-user-agent': 3.972.25 + '@aws-sdk/region-config-resolver': 3.972.9 + '@aws-sdk/types': 3.973.6 + '@aws-sdk/util-endpoints': 3.996.5 + '@aws-sdk/util-user-agent-browser': 3.972.8 + '@aws-sdk/util-user-agent-node': 3.973.11 + '@smithy/config-resolver': 4.4.13 + '@smithy/core': 3.23.12 + '@smithy/fetch-http-handler': 5.3.15 + '@smithy/hash-node': 4.2.12 + '@smithy/invalid-dependency': 4.2.12 + '@smithy/middleware-content-length': 4.2.12 + '@smithy/middleware-endpoint': 4.4.27 + '@smithy/middleware-retry': 4.4.44 + '@smithy/middleware-serde': 4.2.15 + '@smithy/middleware-stack': 4.2.12 + '@smithy/node-config-provider': 4.3.12 + '@smithy/node-http-handler': 4.5.0 + '@smithy/protocol-http': 5.3.12 + '@smithy/smithy-client': 4.12.7 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@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.43 + '@smithy/util-defaults-mode-node': 4.2.47 + '@smithy/util-endpoints': 3.3.3 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-retry': 4.2.12 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/region-config-resolver@3.972.9': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/config-resolver': 4.4.13 + '@smithy/node-config-provider': 4.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1015.0': + dependencies: + '@aws-sdk/core': 3.973.24 + '@aws-sdk/nested-clients': 3.996.14 + '@aws-sdk/types': 3.973.6 + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + transitivePeerDependencies: + - aws-crt + + '@aws-sdk/types@3.973.6': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@aws-sdk/util-endpoints@3.996.5': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@smithy/util-endpoints': 3.3.3 + tslib: 2.8.1 + + '@aws-sdk/util-format-url@3.972.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/querystring-builder': 4.2.12 + '@smithy/types': 4.13.1 + 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.8': + dependencies: + '@aws-sdk/types': 3.973.6 + '@smithy/types': 4.13.1 + bowser: 2.14.1 + tslib: 2.8.1 + + '@aws-sdk/util-user-agent-node@3.973.11': + dependencies: + '@aws-sdk/middleware-user-agent': 3.972.25 + '@aws-sdk/types': 3.973.6 + '@smithy/node-config-provider': 4.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-config-provider': 4.2.2 + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.972.15': + dependencies: + '@smithy/types': 4.13.1 + fast-xml-parser: 5.5.8 + tslib: 2.8.1 + + '@aws/lambda-invoke-store@0.2.4': {} + + '@babel/runtime@7.29.2': {} + + '@borewit/text-codec@0.2.2': {} + + '@cfworker/json-schema@4.1.1': {} + + '@clack/core@1.1.0': + dependencies: + sisteransi: 1.0.5 + + '@clack/prompts@1.1.0': + dependencies: + '@clack/core': 1.1.0 + sisteransi: 1.0.5 + + '@emnapi/runtime@1.9.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@google/genai@1.46.0(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))': + dependencies: + google-auth-library: 10.6.2 + p-retry: 4.6.2 + protobufjs: 7.5.4 + ws: 8.20.0 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@homebridge/ciao@1.3.5': + dependencies: + debug: 4.4.3 + fast-deep-equal: 3.1.3 + source-map-support: 0.5.21 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@hono/node-server@1.19.11(hono@4.12.8)': + dependencies: + hono: 4.12.8 + + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.9.1 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.3 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@langchain/core@1.1.39(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0)': + dependencies: + '@cfworker/json-schema': 4.1.1 + '@standard-schema/spec': 1.1.0 + ansi-styles: 5.2.0 + camelcase: 6.3.0 + decamelize: 1.2.0 + js-tiktoken: 1.0.21 + langsmith: 0.5.18(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0) + mustache: 4.2.0 + p-queue: 6.6.2 + uuid: 11.1.0 + zod: 4.3.6 + transitivePeerDependencies: + - '@opentelemetry/api' + - '@opentelemetry/exporter-trace-otlp-proto' + - '@opentelemetry/sdk-trace-base' + - openai + - ws + + '@langchain/openai@1.4.4(@langchain/core@1.1.39(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0))(ws@8.20.0)': + dependencies: + '@langchain/core': 1.1.39(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0) + js-tiktoken: 1.0.21 + openai: 6.34.0(ws@8.20.0)(zod@4.3.6) + zod: 4.3.6 + transitivePeerDependencies: + - ws + + '@line/bot-sdk@10.6.0': + dependencies: + '@types/node': 24.12.0 + optionalDependencies: + axios: 1.13.6 + transitivePeerDependencies: + - debug + + '@lydell/node-pty-darwin-arm64@1.2.0-beta.3': + optional: true + + '@lydell/node-pty-darwin-x64@1.2.0-beta.3': + optional: true + + '@lydell/node-pty-linux-arm64@1.2.0-beta.3': + optional: true + + '@lydell/node-pty-linux-x64@1.2.0-beta.3': + optional: true + + '@lydell/node-pty-win32-arm64@1.2.0-beta.3': + optional: true + + '@lydell/node-pty-win32-x64@1.2.0-beta.3': + optional: true + + '@lydell/node-pty@1.2.0-beta.3': + optionalDependencies: + '@lydell/node-pty-darwin-arm64': 1.2.0-beta.3 + '@lydell/node-pty-darwin-x64': 1.2.0-beta.3 + '@lydell/node-pty-linux-arm64': 1.2.0-beta.3 + '@lydell/node-pty-linux-x64': 1.2.0-beta.3 + '@lydell/node-pty-win32-arm64': 1.2.0-beta.3 + '@lydell/node-pty-win32-x64': 1.2.0-beta.3 + + '@mariozechner/clipboard-darwin-arm64@0.3.2': + optional: true + + '@mariozechner/clipboard-darwin-universal@0.3.2': + optional: true + + '@mariozechner/clipboard-darwin-x64@0.3.2': + optional: true + + '@mariozechner/clipboard-linux-arm64-gnu@0.3.2': + optional: true + + '@mariozechner/clipboard-linux-arm64-musl@0.3.2': + optional: true + + '@mariozechner/clipboard-linux-riscv64-gnu@0.3.2': + optional: true + + '@mariozechner/clipboard-linux-x64-gnu@0.3.2': + optional: true + + '@mariozechner/clipboard-linux-x64-musl@0.3.2': + optional: true + + '@mariozechner/clipboard-win32-arm64-msvc@0.3.2': + optional: true + + '@mariozechner/clipboard-win32-x64-msvc@0.3.2': + optional: true + + '@mariozechner/clipboard@0.3.2': + optionalDependencies: + '@mariozechner/clipboard-darwin-arm64': 0.3.2 + '@mariozechner/clipboard-darwin-universal': 0.3.2 + '@mariozechner/clipboard-darwin-x64': 0.3.2 + '@mariozechner/clipboard-linux-arm64-gnu': 0.3.2 + '@mariozechner/clipboard-linux-arm64-musl': 0.3.2 + '@mariozechner/clipboard-linux-riscv64-gnu': 0.3.2 + '@mariozechner/clipboard-linux-x64-gnu': 0.3.2 + '@mariozechner/clipboard-linux-x64-musl': 0.3.2 + '@mariozechner/clipboard-win32-arm64-msvc': 0.3.2 + '@mariozechner/clipboard-win32-x64-msvc': 0.3.2 + optional: true + + '@mariozechner/jiti@2.6.5': + dependencies: + std-env: 3.10.0 + yoctocolors: 2.1.2 + + '@mariozechner/pi-agent-core@0.61.1(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': + dependencies: + '@mariozechner/pi-ai': 0.61.1(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - aws-crt + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + + '@mariozechner/pi-ai@0.61.1(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': + dependencies: + '@anthropic-ai/sdk': 0.73.0(zod@4.3.6) + '@aws-sdk/client-bedrock-runtime': 3.1015.0 + '@google/genai': 1.46.0(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6)) + '@mistralai/mistralai': 1.14.1 + '@sinclair/typebox': 0.34.48 + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + chalk: 5.6.2 + openai: 6.26.0(ws@8.20.0)(zod@4.3.6) + partial-json: 0.1.7 + proxy-agent: 6.5.0 + undici: 7.24.5 + zod-to-json-schema: 3.25.1(zod@4.3.6) + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - aws-crt + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + + '@mariozechner/pi-ai@0.67.2(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': + dependencies: + '@anthropic-ai/sdk': 0.73.0(zod@4.3.6) + '@aws-sdk/client-bedrock-runtime': 3.1015.0 + '@google/genai': 1.46.0(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6)) + '@mistralai/mistralai': 1.14.1 + '@sinclair/typebox': 0.34.48 + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + chalk: 5.6.2 + openai: 6.26.0(ws@8.20.0)(zod@4.3.6) + partial-json: 0.1.7 + proxy-agent: 6.5.0 + undici: 7.24.5 + zod-to-json-schema: 3.25.1(zod@4.3.6) + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - aws-crt + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + + '@mariozechner/pi-coding-agent@0.61.1(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6)': + dependencies: + '@mariozechner/jiti': 2.6.5 + '@mariozechner/pi-agent-core': 0.61.1(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@mariozechner/pi-ai': 0.61.1(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@mariozechner/pi-tui': 0.61.1 + '@silvia-odwyer/photon-node': 0.3.4 + chalk: 5.6.2 + cli-highlight: 2.1.11 + diff: 8.0.4 + extract-zip: 2.0.1 + file-type: 21.3.4 + glob: 13.0.6 + hosted-git-info: 9.0.2 + ignore: 7.0.5 + marked: 15.0.12 + minimatch: 10.2.4 + proper-lockfile: 4.1.2 + strip-ansi: 7.2.0 + undici: 7.24.5 + yaml: 2.8.3 + optionalDependencies: + '@mariozechner/clipboard': 0.3.2 + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - aws-crt + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + + '@mariozechner/pi-tui@0.61.1': + dependencies: + '@types/mime-types': 2.1.4 + chalk: 5.6.2 + get-east-asian-width: 1.5.0 + marked: 15.0.12 + mime-types: 3.0.2 + optionalDependencies: + koffi: 2.15.2 + + '@mistralai/mistralai@1.14.1': + dependencies: + ws: 8.20.0 + zod: 4.3.6 + zod-to-json-schema: 3.25.1(zod@4.3.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6)': + dependencies: + '@hono/node-server': 1.19.11(hono@4.12.8) + ajv: 8.18.0 + ajv-formats: 3.0.1(ajv@8.18.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.2.1 + express-rate-limit: 8.3.1(express@5.2.1) + hono: 4.12.8 + jose: 6.2.2 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.3.6 + zod-to-json-schema: 3.25.1(zod@4.3.6) + optionalDependencies: + '@cfworker/json-schema': 4.1.1 + transitivePeerDependencies: + - supports-color + + '@mozilla/readability@0.6.0': {} + + '@napi-rs/canvas-android-arm64@0.1.97': + optional: true + + '@napi-rs/canvas-darwin-arm64@0.1.97': + optional: true + + '@napi-rs/canvas-darwin-x64@0.1.97': + optional: true + + '@napi-rs/canvas-linux-arm-gnueabihf@0.1.97': + optional: true + + '@napi-rs/canvas-linux-arm64-gnu@0.1.97': + optional: true + + '@napi-rs/canvas-linux-arm64-musl@0.1.97': + optional: true + + '@napi-rs/canvas-linux-riscv64-gnu@0.1.97': + optional: true + + '@napi-rs/canvas-linux-x64-gnu@0.1.97': + optional: true + + '@napi-rs/canvas-linux-x64-musl@0.1.97': + optional: true + + '@napi-rs/canvas-win32-arm64-msvc@0.1.97': + optional: true + + '@napi-rs/canvas-win32-x64-msvc@0.1.97': + optional: true + + '@napi-rs/canvas@0.1.97': + optionalDependencies: + '@napi-rs/canvas-android-arm64': 0.1.97 + '@napi-rs/canvas-darwin-arm64': 0.1.97 + '@napi-rs/canvas-darwin-x64': 0.1.97 + '@napi-rs/canvas-linux-arm-gnueabihf': 0.1.97 + '@napi-rs/canvas-linux-arm64-gnu': 0.1.97 + '@napi-rs/canvas-linux-arm64-musl': 0.1.97 + '@napi-rs/canvas-linux-riscv64-gnu': 0.1.97 + '@napi-rs/canvas-linux-x64-gnu': 0.1.97 + '@napi-rs/canvas-linux-x64-musl': 0.1.97 + '@napi-rs/canvas-win32-arm64-msvc': 0.1.97 + '@napi-rs/canvas-win32-x64-msvc': 0.1.97 + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.4': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.0': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.0': {} + + '@rollup/rollup-android-arm-eabi@4.60.0': + optional: true + + '@rollup/rollup-android-arm64@4.60.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.60.0': + optional: true + + '@rollup/rollup-darwin-x64@4.60.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.60.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.60.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.60.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.60.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.60.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.60.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.60.0': + optional: true + + '@rollup/rollup-openbsd-x64@4.60.0': + optional: true + + '@rollup/rollup-openharmony-arm64@4.60.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.60.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.60.0': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.60.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.60.0': + optional: true + + '@seekdb/js-bindings@1.2.0': + dependencies: + adm-zip: 0.5.17 + optional: true + + '@silvia-odwyer/photon-node@0.3.4': {} + + '@sinclair/typebox@0.34.48': {} + + '@smithy/abort-controller@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/config-resolver@4.4.13': + dependencies: + '@smithy/node-config-provider': 4.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-config-provider': 4.2.2 + '@smithy/util-endpoints': 3.3.3 + '@smithy/util-middleware': 4.2.12 + tslib: 2.8.1 + + '@smithy/core@3.23.12': + dependencies: + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@smithy/util-base64': 4.3.2 + '@smithy/util-body-length-browser': 4.2.2 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-stream': 4.5.20 + '@smithy/util-utf8': 4.2.2 + '@smithy/uuid': 1.1.2 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.2.12': + dependencies: + '@smithy/node-config-provider': 4.3.12 + '@smithy/property-provider': 4.2.12 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + tslib: 2.8.1 + + '@smithy/eventstream-codec@4.2.12': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@smithy/types': 4.13.1 + '@smithy/util-hex-encoding': 4.2.2 + tslib: 2.8.1 + + '@smithy/eventstream-serde-browser@4.2.12': + dependencies: + '@smithy/eventstream-serde-universal': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-config-resolver@4.3.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-node@4.2.12': + dependencies: + '@smithy/eventstream-serde-universal': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/eventstream-serde-universal@4.2.12': + dependencies: + '@smithy/eventstream-codec': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/fetch-http-handler@5.3.15': + dependencies: + '@smithy/protocol-http': 5.3.12 + '@smithy/querystring-builder': 4.2.12 + '@smithy/types': 4.13.1 + '@smithy/util-base64': 4.3.2 + tslib: 2.8.1 + + '@smithy/hash-node@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + '@smithy/util-buffer-from': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@smithy/invalid-dependency@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/is-array-buffer@2.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/is-array-buffer@4.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/middleware-content-length@4.2.12': + dependencies: + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/middleware-endpoint@4.4.27': + dependencies: + '@smithy/core': 3.23.12 + '@smithy/middleware-serde': 4.2.15 + '@smithy/node-config-provider': 4.3.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + '@smithy/url-parser': 4.2.12 + '@smithy/util-middleware': 4.2.12 + tslib: 2.8.1 + + '@smithy/middleware-retry@4.4.44': + dependencies: + '@smithy/node-config-provider': 4.3.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/service-error-classification': 4.2.12 + '@smithy/smithy-client': 4.12.7 + '@smithy/types': 4.13.1 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-retry': 4.2.12 + '@smithy/uuid': 1.1.2 + tslib: 2.8.1 + + '@smithy/middleware-serde@4.2.15': + dependencies: + '@smithy/core': 3.23.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/middleware-stack@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/node-config-provider@4.3.12': + dependencies: + '@smithy/property-provider': 4.2.12 + '@smithy/shared-ini-file-loader': 4.4.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/node-http-handler@4.5.0': + dependencies: + '@smithy/abort-controller': 4.2.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/querystring-builder': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/property-provider@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/protocol-http@5.3.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/querystring-builder@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + '@smithy/util-uri-escape': 4.2.2 + tslib: 2.8.1 + + '@smithy/querystring-parser@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/service-error-classification@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + + '@smithy/shared-ini-file-loader@4.4.7': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/signature-v4@5.3.12': + dependencies: + '@smithy/is-array-buffer': 4.2.2 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-hex-encoding': 4.2.2 + '@smithy/util-middleware': 4.2.12 + '@smithy/util-uri-escape': 4.2.2 + '@smithy/util-utf8': 4.2.2 + tslib: 2.8.1 + + '@smithy/smithy-client@4.12.7': + dependencies: + '@smithy/core': 3.23.12 + '@smithy/middleware-endpoint': 4.4.27 + '@smithy/middleware-stack': 4.2.12 + '@smithy/protocol-http': 5.3.12 + '@smithy/types': 4.13.1 + '@smithy/util-stream': 4.5.20 + tslib: 2.8.1 + + '@smithy/types@4.13.1': + dependencies: + tslib: 2.8.1 + + '@smithy/url-parser@4.2.12': + dependencies: + '@smithy/querystring-parser': 4.2.12 + '@smithy/types': 4.13.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': + dependencies: + tslib: 2.8.1 + + '@smithy/util-buffer-from@2.2.0': + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.8.1 + + '@smithy/util-buffer-from@4.2.2': + dependencies: + '@smithy/is-array-buffer': 4.2.2 + tslib: 2.8.1 + + '@smithy/util-config-provider@4.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-defaults-mode-browser@4.3.43': + dependencies: + '@smithy/property-provider': 4.2.12 + '@smithy/smithy-client': 4.12.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-defaults-mode-node@4.2.47': + dependencies: + '@smithy/config-resolver': 4.4.13 + '@smithy/credential-provider-imds': 4.2.12 + '@smithy/node-config-provider': 4.3.12 + '@smithy/property-provider': 4.2.12 + '@smithy/smithy-client': 4.12.7 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-endpoints@3.3.3': + dependencies: + '@smithy/node-config-provider': 4.3.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-hex-encoding@4.2.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-middleware@4.2.12': + dependencies: + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-retry@4.2.12': + dependencies: + '@smithy/service-error-classification': 4.2.12 + '@smithy/types': 4.13.1 + tslib: 2.8.1 + + '@smithy/util-stream@4.5.20': + dependencies: + '@smithy/fetch-http-handler': 5.3.15 + '@smithy/node-http-handler': 4.5.0 + '@smithy/types': 4.13.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': + dependencies: + tslib: 2.8.1 + + '@smithy/util-utf8@2.3.0': + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.8.1 + + '@smithy/util-utf8@4.2.2': + dependencies: + '@smithy/util-buffer-from': 4.2.2 + tslib: 2.8.1 + + '@smithy/uuid@1.1.2': + dependencies: + tslib: 2.8.1 + + '@standard-schema/spec@1.1.0': {} + + '@telegraf/types@7.1.0': + optional: true + + '@tokenizer/inflate@0.4.1': + dependencies: + debug: 4.4.3 + token-types: 6.1.2 + transitivePeerDependencies: + - supports-color + + '@tokenizer/token@0.3.0': {} + + '@tootallnate/quickjs-emscripten@0.23.0': {} + + '@types/estree@1.0.8': {} + + '@types/mime-types@2.1.4': {} + + '@types/node@22.19.15': + dependencies: + undici-types: 6.21.0 + + '@types/node@24.12.0': + dependencies: + undici-types: 7.16.0 + + '@types/retry@0.12.0': {} + + '@types/yauzl@2.10.3': + dependencies: + '@types/node': 22.19.15 + optional: true + + '@vitest/expect@2.1.9': + dependencies: + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + tinyrainbow: 1.2.0 + + '@vitest/mocker@2.1.9(vite@5.4.21(@types/node@22.19.15))': + dependencies: + '@vitest/spy': 2.1.9 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 5.4.21(@types/node@22.19.15) + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.1.9': + dependencies: + '@vitest/utils': 2.1.9 + pathe: 1.1.2 + + '@vitest/snapshot@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + magic-string: 0.30.21 + pathe: 1.1.2 + + '@vitest/spy@2.1.9': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.2.1 + tinyrainbow: 1.2.0 + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + optional: true + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.0.0 + + adm-zip@0.5.17: + optional: true + + agent-base@7.1.4: {} + + ajv-formats@3.0.1(ajv@8.18.0): + optionalDependencies: + ajv: 8.18.0 + + ajv@8.18.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + any-promise@1.3.0: {} + + argparse@2.0.1: {} + + assertion-error@2.0.1: {} + + ast-types@0.13.4: + dependencies: + tslib: 2.8.1 + + asynckit@0.4.0: + optional: true + + aws-ssl-profiles@1.1.2: {} + + axios@1.13.6: + dependencies: + follow-redirects: 1.15.11 + form-data: 4.0.5 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + optional: true + + balanced-match@4.0.4: {} + + base64-js@1.5.1: {} + + basic-ftp@5.2.0: {} + + better-sqlite3@12.9.0: + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.3 + + bignumber.js@9.3.1: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + body-parser@2.2.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + on-finished: 2.4.1 + qs: 6.15.0 + raw-body: 3.0.2 + type-is: 2.0.1 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + bowser@2.14.1: {} + + brace-expansion@5.0.4: + dependencies: + balanced-match: 4.0.4 + + buffer-alloc-unsafe@1.1.0: + optional: true + + buffer-alloc@1.2.0: + dependencies: + buffer-alloc-unsafe: 1.1.0 + buffer-fill: 1.0.0 + optional: true + + buffer-crc32@0.2.13: {} + + buffer-equal-constant-time@1.0.1: {} + + buffer-fill@1.0.0: + optional: true + + buffer-from@1.1.2: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bytes@3.1.2: {} + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + camelcase@6.3.0: {} + + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.3 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + check-error@2.1.3: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + + chownr@1.1.4: {} + + chownr@3.0.0: {} + + cli-highlight@2.1.11: + dependencies: + chalk: 4.1.2 + highlight.js: 10.7.3 + mz: 2.7.0 + parse5: 5.1.1 + parse5-htmlparser2-tree-adapter: 6.0.1 + yargs: 16.2.0 + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + optional: true + + commander@14.0.3: {} + + content-disposition@1.0.1: {} + + content-type@1.0.5: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + core-util-is@1.0.3: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + croner@10.0.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-what@6.2.2: {} + + cssom@0.5.0: {} + + data-uri-to-buffer@4.0.1: {} + + data-uri-to-buffer@6.0.2: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decamelize@1.2.0: {} + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-eql@5.0.2: {} + + deep-extend@0.6.0: {} + + degenerator@5.0.1: + dependencies: + ast-types: 0.13.4 + escodegen: 2.1.0 + esprima: 4.0.1 + + delayed-stream@1.0.0: + optional: true + + denque@2.1.0: {} + + depd@2.0.0: {} + + detect-libc@2.1.2: {} + + diff@8.0.4: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dotenv@16.6.1: {} + + dotenv@17.3.1: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + ee-first@1.1.1: {} + + emoji-regex@8.0.0: {} + + encodeurl@2.0.0: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + entities@4.5.0: {} + + entities@7.0.1: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + optional: true + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + + esprima@4.0.1: {} + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + esutils@2.0.3: {} + + etag@1.8.1: {} + + event-target-shim@5.0.1: + optional: true + + eventemitter3@4.0.7: {} + + eventsource-parser@3.0.6: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.6 + + expand-template@2.0.3: {} + + expect-type@1.3.0: {} + + express-rate-limit@8.3.1(express@5.2.1): + dependencies: + express: 5.2.1 + ip-address: 10.1.0 + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.2 + content-disposition: 1.0.1 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.15.0 + 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 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend@3.0.2: {} + + extract-zip@2.0.1: + dependencies: + debug: 4.4.3 + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-uri@3.1.0: {} + + fast-xml-builder@1.1.4: + dependencies: + path-expression-matcher: 1.2.0 + + fast-xml-parser@5.5.8: + dependencies: + fast-xml-builder: 1.1.4 + path-expression-matcher: 1.2.0 + strnum: 2.2.2 + + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + file-type@21.3.4: + dependencies: + '@tokenizer/inflate': 0.4.1 + strtok3: 10.3.5 + token-types: 6.1.2 + uint8array-extras: 1.5.0 + transitivePeerDependencies: + - supports-color + + file-uri-to-path@1.0.0: {} + + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + follow-redirects@1.15.11: + optional: true + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + optional: true + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fs-constants@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gaxios@6.7.1: + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + is-stream: 2.0.1 + node-fetch: 2.7.0 + uuid: 9.0.1 + transitivePeerDependencies: + - encoding + - supports-color + + gaxios@7.1.4: + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + node-fetch: 3.3.2 + transitivePeerDependencies: + - supports-color + + gcp-metadata@6.1.1: + dependencies: + gaxios: 6.7.1 + google-logging-utils: 0.0.2 + json-bigint: 1.0.0 + transitivePeerDependencies: + - encoding + - supports-color + + gcp-metadata@8.1.2: + dependencies: + gaxios: 7.1.4 + google-logging-utils: 1.1.3 + json-bigint: 1.0.0 + transitivePeerDependencies: + - supports-color + + generate-function@2.3.1: + dependencies: + is-property: 1.0.2 + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.5.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.2 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stream@5.2.0: + dependencies: + pump: 3.0.4 + + get-uri@6.0.5: + dependencies: + basic-ftp: 5.2.0 + data-uri-to-buffer: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + github-from-package@0.0.0: {} + + glob@13.0.6: + dependencies: + minimatch: 10.2.4 + minipass: 7.1.3 + path-scurry: 2.0.2 + + google-auth-library@10.6.2: + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 7.1.4 + gcp-metadata: 8.1.2 + google-logging-utils: 1.1.3 + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + + google-auth-library@9.15.1: + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 6.7.1 + gcp-metadata: 6.1.1 + gtoken: 7.1.0 + jws: 4.0.1 + transitivePeerDependencies: + - encoding + - supports-color + + google-logging-utils@0.0.2: {} + + google-logging-utils@1.1.3: {} + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + gtoken@7.1.0: + dependencies: + gaxios: 6.7.1 + jws: 4.0.1 + transitivePeerDependencies: + - encoding + - supports-color + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + optional: true + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + highlight.js@10.7.3: {} + + hono@4.12.8: {} + + hosted-git-info@9.0.2: + dependencies: + lru-cache: 11.2.7 + + html-escaper@3.0.3: {} + + htmlparser2@10.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 7.0.1 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@7.0.5: {} + + immediate@3.0.6: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ip-address@10.1.0: {} + + ipaddr.js@1.9.1: {} + + ipaddr.js@2.3.0: {} + + is-fullwidth-code-point@3.0.0: {} + + is-promise@4.0.0: {} + + is-property@1.0.2: {} + + is-stream@2.0.1: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + jiti@2.6.1: {} + + jose@6.2.2: {} + + js-tiktoken@1.0.21: + dependencies: + base64-js: 1.5.1 + + json-bigint@1.0.0: + dependencies: + bignumber.js: 9.3.1 + + json-schema-to-ts@3.1.1: + dependencies: + '@babel/runtime': 7.29.2 + ts-algebra: 2.0.0 + + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + + json5@2.2.3: {} + + jszip@3.10.1: + dependencies: + lie: 3.3.0 + pako: 1.0.11 + readable-stream: 2.3.8 + setimmediate: 1.0.5 + + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + + koffi@2.15.2: + optional: true + + langsmith@0.5.18(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0): + dependencies: + p-queue: 6.6.2 + uuid: 10.0.0 + optionalDependencies: + openai: 6.34.0(ws@8.20.0)(zod@4.3.6) + ws: 8.20.0 + + lie@3.3.0: + dependencies: + immediate: 3.0.6 + + linkedom@0.18.12: + dependencies: + css-select: 5.2.2 + cssom: 0.5.0 + html-escaper: 3.0.3 + htmlparser2: 10.1.0 + uhyphen: 0.2.0 + + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + long@5.3.2: {} + + loupe@3.2.1: {} + + lru-cache@11.2.7: {} + + lru-cache@7.18.3: {} + + lru.min@1.1.4: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + markdown-it@14.1.1: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + marked@15.0.12: {} + + math-intrinsics@1.1.0: {} + + mdurl@2.0.0: {} + + media-typer@1.1.0: {} + + merge-descriptors@2.0.0: {} + + mime-db@1.52.0: + optional: true + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + optional: true + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mimic-response@3.1.0: {} + + minimatch@10.2.4: + dependencies: + brace-expansion: 5.0.4 + + minimist@1.2.8: {} + + minipass@7.1.3: {} + + minizlib@3.1.0: + dependencies: + minipass: 7.1.3 + + mkdirp-classic@0.5.3: {} + + mri@1.2.0: + optional: true + + ms@2.1.3: {} + + mustache@4.2.0: {} + + mysql2@3.22.0(@types/node@22.19.15): + dependencies: + '@types/node': 22.19.15 + aws-ssl-profiles: 1.1.2 + denque: 2.1.0 + generate-function: 2.3.1 + iconv-lite: 0.7.2 + long: 5.3.2 + lru.min: 1.1.4 + named-placeholders: 1.1.6 + sql-escaper: 1.3.3 + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + named-placeholders@1.1.6: + dependencies: + lru.min: 1.1.4 + + nanoid@3.3.11: {} + + napi-build-utils@2.0.0: {} + + negotiator@1.0.0: {} + + netmask@2.0.2: {} + + node-abi@3.89.0: + dependencies: + semver: 7.7.4 + + node-domexception@1.0.0: {} + + node-edge-tts@1.2.10: + dependencies: + https-proxy-agent: 7.0.6 + ws: 8.20.0 + yargs: 17.7.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + node-readable-to-web-readable-stream@0.4.2: + optional: true + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + openai@6.26.0(ws@8.20.0)(zod@4.3.6): + optionalDependencies: + ws: 8.20.0 + zod: 4.3.6 + + openai@6.34.0(ws@8.20.0)(zod@4.3.6): + optionalDependencies: + ws: 8.20.0 + zod: 4.3.6 + + openclaw@2026.3.23(@cfworker/json-schema@4.1.1)(@napi-rs/canvas@0.1.97): + dependencies: + '@agentclientprotocol/sdk': 0.16.1(zod@4.3.6) + '@anthropic-ai/vertex-sdk': 0.14.4(zod@4.3.6) + '@aws-sdk/client-bedrock': 3.1015.0 + '@clack/prompts': 1.1.0 + '@homebridge/ciao': 1.3.5 + '@line/bot-sdk': 10.6.0 + '@lydell/node-pty': 1.2.0-beta.3 + '@mariozechner/pi-agent-core': 0.61.1(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@mariozechner/pi-ai': 0.61.1(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@mariozechner/pi-coding-agent': 0.61.1(@modelcontextprotocol/sdk@1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6))(ws@8.20.0)(zod@4.3.6) + '@mariozechner/pi-tui': 0.61.1 + '@modelcontextprotocol/sdk': 1.27.1(@cfworker/json-schema@4.1.1)(zod@4.3.6) + '@mozilla/readability': 0.6.0 + '@napi-rs/canvas': 0.1.97 + '@sinclair/typebox': 0.34.48 + ajv: 8.18.0 + chalk: 5.6.2 + chokidar: 5.0.0 + cli-highlight: 2.1.11 + commander: 14.0.3 + croner: 10.0.1 + dotenv: 17.3.1 + express: 5.2.1 + file-type: 21.3.4 + gaxios: 7.1.4 + hono: 4.12.8 + ipaddr.js: 2.3.0 + jiti: 2.6.1 + json5: 2.2.3 + jszip: 3.10.1 + linkedom: 0.18.12 + long: 5.3.2 + markdown-it: 14.1.1 + node-edge-tts: 1.2.10 + osc-progress: 0.3.0 + pdfjs-dist: 5.5.207 + playwright-core: 1.58.2 + qrcode-terminal: 0.12.0 + sharp: 0.34.5 + sqlite-vec: 0.1.7 + tar: 7.5.12 + tslog: 4.10.2 + undici: 7.24.5 + uuid: 13.0.0 + ws: 8.20.0 + yaml: 2.8.3 + zod: 4.3.6 + optionalDependencies: + openshell: 0.1.0 + transitivePeerDependencies: + - '@cfworker/json-schema' + - aws-crt + - bufferutil + - canvas + - debug + - encoding + - supports-color + - utf-8-validate + + openshell@0.1.0: + dependencies: + dotenv: 16.6.1 + telegraf: 4.16.3 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + osc-progress@0.3.0: {} + + p-finally@1.0.0: {} + + p-queue@6.6.2: + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + + p-retry@4.6.2: + dependencies: + '@types/retry': 0.12.0 + retry: 0.13.1 + + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 + + p-timeout@4.1.0: + optional: true + + pac-proxy-agent@7.2.0: + dependencies: + '@tootallnate/quickjs-emscripten': 0.23.0 + agent-base: 7.1.4 + debug: 4.4.3 + get-uri: 6.0.5 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + pac-resolver: 7.0.1 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + pac-resolver@7.0.1: + dependencies: + degenerator: 5.0.1 + netmask: 2.0.2 + + pako@1.0.11: {} + + parse5-htmlparser2-tree-adapter@6.0.1: + dependencies: + parse5: 6.0.1 + + parse5@5.1.1: {} + + parse5@6.0.1: {} + + parseurl@1.3.3: {} + + partial-json@0.1.7: {} + + path-expression-matcher@1.2.0: {} + + path-key@3.1.1: {} + + path-scurry@2.0.2: + dependencies: + lru-cache: 11.2.7 + minipass: 7.1.3 + + path-to-regexp@8.3.0: {} + + pathe@1.1.2: {} + + pathval@2.0.1: {} + + pdfjs-dist@5.5.207: + optionalDependencies: + '@napi-rs/canvas': 0.1.97 + node-readable-to-web-readable-stream: 0.4.2 + + pend@1.2.0: {} + + pg-cloudflare@1.3.0: + optional: true + + pg-connection-string@2.12.0: {} + + pg-int8@1.0.1: {} + + pg-pool@3.13.0(pg@8.20.0): + dependencies: + pg: 8.20.0 + + pg-protocol@1.13.0: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.1 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.20.0: + dependencies: + pg-connection-string: 2.12.0 + pg-pool: 3.13.0(pg@8.20.0) + pg-protocol: 1.13.0 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.3.0 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + + picocolors@1.1.1: {} + + pkce-challenge@5.0.1: {} + + playwright-core@1.58.2: {} + + postcss@8.5.8: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postgres-array@2.0.0: {} + + postgres-bytea@1.0.1: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + + powermem@0.1.1(@langchain/openai@1.4.4(@langchain/core@1.1.39(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0))(ws@8.20.0))(@types/node@22.19.15)(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0): + dependencies: + '@langchain/core': 1.1.39(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0) + better-sqlite3: 12.9.0 + commander: 14.0.3 + dotenv: 16.6.1 + express: 5.2.1 + pg: 8.20.0 + seekdb: 1.2.0(@types/node@22.19.15) + zod: 4.3.6 + optionalDependencies: + '@langchain/openai': 1.4.4(@langchain/core@1.1.39(openai@6.34.0(ws@8.20.0)(zod@4.3.6))(ws@8.20.0))(ws@8.20.0) + transitivePeerDependencies: + - '@opentelemetry/api' + - '@opentelemetry/exporter-trace-otlp-proto' + - '@opentelemetry/sdk-trace-base' + - '@seekdb/default-embed' + - '@types/node' + - openai + - pg-native + - supports-color + - ws + + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.1.2 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.89.0 + pump: 3.0.4 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.4 + tunnel-agent: 0.6.0 + + process-nextick-args@2.0.1: {} + + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + + protobufjs@7.5.4: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 22.19.15 + long: 5.3.2 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-agent@6.5.0: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + lru-cache: 7.18.3 + pac-proxy-agent: 7.2.0 + proxy-from-env: 1.1.0 + socks-proxy-agent: 8.0.5 + transitivePeerDependencies: + - supports-color + + proxy-from-env@1.1.0: {} + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + punycode.js@2.3.1: {} + + qrcode-terminal@0.12.0: {} + + qs@6.15.0: + dependencies: + side-channel: 1.1.0 + + range-parser@1.2.1: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + unpipe: 1.0.0 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readdirp@5.0.0: {} + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + retry@0.12.0: {} + + retry@0.13.1: {} + + rollup@4.60.0: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.60.0 + '@rollup/rollup-android-arm64': 4.60.0 + '@rollup/rollup-darwin-arm64': 4.60.0 + '@rollup/rollup-darwin-x64': 4.60.0 + '@rollup/rollup-freebsd-arm64': 4.60.0 + '@rollup/rollup-freebsd-x64': 4.60.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.0 + '@rollup/rollup-linux-arm-musleabihf': 4.60.0 + '@rollup/rollup-linux-arm64-gnu': 4.60.0 + '@rollup/rollup-linux-arm64-musl': 4.60.0 + '@rollup/rollup-linux-loong64-gnu': 4.60.0 + '@rollup/rollup-linux-loong64-musl': 4.60.0 + '@rollup/rollup-linux-ppc64-gnu': 4.60.0 + '@rollup/rollup-linux-ppc64-musl': 4.60.0 + '@rollup/rollup-linux-riscv64-gnu': 4.60.0 + '@rollup/rollup-linux-riscv64-musl': 4.60.0 + '@rollup/rollup-linux-s390x-gnu': 4.60.0 + '@rollup/rollup-linux-x64-gnu': 4.60.0 + '@rollup/rollup-linux-x64-musl': 4.60.0 + '@rollup/rollup-openbsd-x64': 4.60.0 + '@rollup/rollup-openharmony-arm64': 4.60.0 + '@rollup/rollup-win32-arm64-msvc': 4.60.0 + '@rollup/rollup-win32-ia32-msvc': 4.60.0 + '@rollup/rollup-win32-x64-gnu': 4.60.0 + '@rollup/rollup-win32-x64-msvc': 4.60.0 + fsevents: 2.3.3 + + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.3.0 + transitivePeerDependencies: + - supports-color + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-compare@1.1.4: + dependencies: + buffer-alloc: 1.2.0 + optional: true + + safer-buffer@2.1.2: {} + + sandwich-stream@2.0.2: + optional: true + + seekdb@1.2.0(@types/node@22.19.15): + dependencies: + mysql2: 3.22.0(@types/node@22.19.15) + optionalDependencies: + '@seekdb/js-bindings': 1.2.0 + transitivePeerDependencies: + - '@types/node' + + semver@7.7.4: {} + + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + setimmediate@1.0.5: {} + + setprototypeof@1.2.0: {} + + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + siginfo@2.0.0: {} + + signal-exit@3.0.7: {} + + simple-concat@1.0.1: {} + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + + sisteransi@1.0.5: {} + + smart-buffer@4.2.0: {} + + socks-proxy-agent@8.0.5: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + socks: 2.8.7 + transitivePeerDependencies: + - supports-color + + socks@2.8.7: + dependencies: + ip-address: 10.1.0 + smart-buffer: 4.2.0 + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + split2@4.2.0: {} + + sql-escaper@1.3.3: {} + + sqlite-vec-darwin-arm64@0.1.7: + optional: true + + sqlite-vec-darwin-arm64@0.1.9: + optional: true + + sqlite-vec-darwin-x64@0.1.7: + optional: true + + sqlite-vec-darwin-x64@0.1.9: + optional: true + + sqlite-vec-linux-arm64@0.1.7: + optional: true + + sqlite-vec-linux-arm64@0.1.9: + optional: true + + sqlite-vec-linux-x64@0.1.7: + optional: true + + sqlite-vec-linux-x64@0.1.9: + optional: true + + sqlite-vec-windows-x64@0.1.7: + optional: true + + sqlite-vec-windows-x64@0.1.9: + optional: true + + sqlite-vec@0.1.7: + optionalDependencies: + sqlite-vec-darwin-arm64: 0.1.7 + sqlite-vec-darwin-x64: 0.1.7 + sqlite-vec-linux-arm64: 0.1.7 + sqlite-vec-linux-x64: 0.1.7 + sqlite-vec-windows-x64: 0.1.7 + + sqlite-vec@0.1.9: + optionalDependencies: + sqlite-vec-darwin-arm64: 0.1.9 + sqlite-vec-darwin-x64: 0.1.9 + sqlite-vec-linux-arm64: 0.1.9 + sqlite-vec-linux-x64: 0.1.9 + sqlite-vec-windows-x64: 0.1.9 + + stackback@0.0.2: {} + + statuses@2.0.2: {} + + std-env@3.10.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-json-comments@2.0.1: {} + + strnum@2.2.2: {} + + strtok3@10.3.5: + dependencies: + '@tokenizer/token': 0.3.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + tar-fs@2.1.4: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.4 + tar-stream: 2.2.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar@7.5.12: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.3 + minizlib: 3.1.0 + yallist: 5.0.0 + + telegraf@4.16.3: + dependencies: + '@telegraf/types': 7.1.0 + abort-controller: 3.0.0 + debug: 4.4.3 + mri: 1.2.0 + node-fetch: 2.7.0 + p-timeout: 4.1.0 + safe-compare: 1.1.4 + sandwich-stream: 2.0.2 + transitivePeerDependencies: + - encoding + - supports-color + optional: true + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinypool@1.1.1: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.2: {} + + toidentifier@1.0.1: {} + + token-types@6.1.2: + dependencies: + '@borewit/text-codec': 0.2.2 + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + + tr46@0.0.3: {} + + ts-algebra@2.0.0: {} + + tslib@2.8.1: {} + + tslog@4.10.2: {} + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + + type-is@2.0.1: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.2 + + typescript@5.9.3: {} + + uc.micro@2.1.0: {} + + uhyphen@0.2.0: {} + + uint8array-extras@1.5.0: {} + + undici-types@6.21.0: {} + + undici-types@7.16.0: {} + + undici@7.24.5: {} + + unpipe@1.0.0: {} + + util-deprecate@1.0.2: {} + + uuid@10.0.0: {} + + uuid@11.1.0: {} + + uuid@13.0.0: {} + + uuid@9.0.1: {} + + vary@1.1.2: {} + + vite-node@2.1.9(@types/node@22.19.15): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 1.1.2 + vite: 5.4.21(@types/node@22.19.15) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + vite@5.4.21(@types/node@22.19.15): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.8 + rollup: 4.60.0 + optionalDependencies: + '@types/node': 22.19.15 + fsevents: 2.3.3 + + vitest@2.1.9(@types/node@22.19.15): + dependencies: + '@vitest/expect': 2.1.9 + '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@22.19.15)) + '@vitest/pretty-format': 2.1.9 + '@vitest/runner': 2.1.9 + '@vitest/snapshot': 2.1.9 + '@vitest/spy': 2.1.9 + '@vitest/utils': 2.1.9 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.3.0 + magic-string: 0.30.21 + pathe: 1.1.2 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.1.1 + tinyrainbow: 1.2.0 + vite: 5.4.21(@types/node@22.19.15) + vite-node: 2.1.9(@types/node@22.19.15) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.19.15 + transitivePeerDependencies: + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + + web-streams-polyfill@3.3.3: {} + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@8.20.0: {} + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + yallist@5.0.0: {} + + yaml@2.8.3: {} + + yargs-parser@20.2.9: {} + + yargs-parser@21.1.1: {} + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + + yoctocolors@2.1.2: {} + + zod-to-json-schema@3.25.1(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@4.3.6: {} diff --git a/skills/install-memory-powermem-full/SKILL.md b/skills/install-memory-powermem-full/SKILL.md index 31c3c11..0509d51 100644 --- a/skills/install-memory-powermem-full/SKILL.md +++ b/skills/install-memory-powermem-full/SKILL.md @@ -1,6 +1,6 @@ --- name: install-memory-powermem-full -description: OpenClaw full guide skill (id and folder name install-memory-powermem-full). Step-by-step install and configuration for the PowerMem long-term memory plugin—options, tools, troubleshooting—and bundled reference docs. Complements the quickstart skill install-memory-powermem; either can be used alone. +description: OpenClaw full guide skill (id and folder name install-memory-powermem-full). Step-by-step install and configuration for the PowerMem long-term memory plugin—default powermem-ts (npm) CLI, optional Python pmem, HTTP, tools, troubleshooting—and bundled reference docs. Complements install-memory-powermem; either can be used alone. triggers: - "安装 PowerMem 记忆" - "安装 PowerMem 记忆插件" @@ -26,38 +26,35 @@ This skill folder includes supplementary docs: - **Auto-Capture**: After a conversation, the plugin sends valuable user/assistant text to PowerMem (optional infer / intelligent extraction). - **Auto-Recall**: Before each turn, it searches memories and can inject a `` block into context. +- **Auto-Experience**: Optionally distills procedural experiences and stores them as memories for later recall. ## When User Asks to Install -**Recommended order (TO C):** (1) OpenClaw installed and **default model + provider auth** configured. (2) **Python 3.10+ verified** (`python3 --version`) *before* venv / `pip install`. (3) `pip install powermem` and `pmem` available to the gateway (PATH or `pmemPath`). (4) Install the **memory-powermem** plugin. **No `powermem.env` is required** for the default path. +**Recommended order (TO C):** (1) OpenClaw installed and **default model + provider auth** configured. (2) Install the **memory-powermem** plugin. (3) Default **CLI** uses **powermem-ts** (npm package **`powermem`**) via **`pmemPath: bundled`**—no Python required; the plugin’s `npm install` / `pnpm install` pulls `powermem`, **`@langchain/openai`**, and native deps (**`better-sqlite3`**). (4) *Optional:* use **Python** `pmem` from [oceanbase/powermem](https://github.com/oceanbase/powermem) instead by setting **`pmemPath`** to the venv binary. **No `powermem.env` is required** for the default path when **`useOpenClawModel`** is true. -The curl **`install.sh`** deploys the plugin and OpenClaw entries; with **`-y`** it may still create **`~/.openclaw/powermem/powermem.env`** as an *optional* template—it does **not** run `pip install powermem`. That file is **not** required if the user relies on **OpenClaw-injected** LLM + default SQLite. +The curl **`install.sh`** deploys the plugin and OpenClaw entries; with **`-y`** it may still create **`~/.openclaw/powermem/powermem.env`** as an *optional* template—it does **not** require `pip install powermem`. That file is **not** required if the user relies on **OpenClaw-injected** LLM + default SQLite + **bundled** npm CLI. 1. **Check OpenClaw** `openclaw --version`. If missing: `npm install -g openclaw`, `openclaw onboard`. Ensure **`agents.defaults.model`** is set (e.g. `openai/gpt-4o-mini`) and the corresponding **provider / API key** works for normal chat—the plugin reuses that for PowerMem when **`useOpenClawModel`** is true (default). -2. **Check Python (required before venv / pip)** - PowerMem needs **Python 3.10 or newer**. Run **`python3 --version`** first; the minor version must be **≥ 10** (e.g. 3.10.x, 3.12.x). Optional strict check: - ```bash - python3 -c "import sys; assert sys.version_info >= (3, 10), 'Need Python 3.10+'; print(sys.version.split()[0], 'OK')" - ``` - If it fails: upgrade Python or use a specific binary (e.g. `python3.12`) for all commands below instead of `python3`. +2. **Install the plugin** + `openclaw plugins install /path/to/memory-powermem` (or `openclaw plugins install memory-powermem` from npm), or run **`install.sh`** from the [memory-powermem](https://github.com/ob-labs/memory-powermem) repo — see **One-click plugin deploy (`install.sh`)** below for curl / flags / `--workdir`. -3. **Install PowerMem (CLI — default)** - - Venv recommended: e.g. `python3 -m venv ~/.openclaw/powermem/.venv && source ~/.openclaw/powermem/.venv/bin/activate`. - - `pip install powermem`. +3. **PowerMem CLI — default: powermem-ts (npm), no Python** + - Plugin default **`pmemPath: bundled`**: runs the **`powermem`** npm package (TypeScript / **powermem-ts**) shipped with the plugin (`node_modules/.../powermem/dist/cli.js`). + - After `openclaw plugins install` or **`install.sh`**, dependencies are installed under the plugin directory; for a **local path** / symlink install, run **`pnpm install` / `npm install`** in that directory. + - **pnpm 10+:** allow **`better-sqlite3`** install scripts (see plugin **`package.json`** → **`pnpm.onlyBuiltDependencies`**) or run **`pnpm rebuild better-sqlite3`** if the native module failed to build. - **Defaults:** Plugin injects **SQLite** at `/powermem/data/powermem.db` and **LLM + embedding** env vars derived from OpenClaw. Typical `stateDir` is `~/.openclaw` unless the user uses another instance (`OPENCLAW_STATE_DIR`, `--workdir`). - **Optional `envFile`:** Path to a PowerMem `.env` for extra tuning. If the file **exists**, `pmem` loads it; **OpenClaw-derived vars still override** the same keys when `useOpenClawModel` is true. - - **`useOpenClawModel: false`:** Disables injection; user must supply a **complete** PowerMem config via `.env` and/or environment variables. - - **Verify:** `pmem --version`. If the gateway does not inherit the venv, set **`pmemPath`** to the absolute path of `pmem`. + - **`useOpenClawModel: false`:** Disables injection; user must supply a **complete** PowerMem config via `.env` and/or environment variables. -4. **HTTP path (enterprise / shared server)** - - Same **Python 3.10+** requirement as CLI; then `pip install powermem`, `.env` in server working directory, `powermem-server --host 0.0.0.0 --port 8000`. - - Check: `curl -s http://localhost:8000/api/v1/system/health`. +4. **Optional: Python CLI instead of bundled npm** + For [oceanbase/powermem](https://github.com/oceanbase/powermem) **Python** `pmem`: **Python 3.10+**, venv + `pip install powermem`, then set **`pmemPath`** to the absolute path of the `pmem` binary (gateway may not inherit venv `PATH`). Verify with **`pmem --version`**. -5. **Install the plugin** - `openclaw plugins install /path/to/memory-powermem` (or `openclaw plugins install memory-powermem` from npm), or run **`install.sh`** from the [memory-powermem](https://github.com/ob-labs/memory-powermem) repo — see **One-click plugin deploy (`install.sh`)** below for curl / flags / `--workdir`. +5. **HTTP path (enterprise / shared server)** + - Run **`powermem-server`** from the same **powermem-ts** stack (npm) or from a Python/Docker deployment; `.env` in server working directory with DB + LLM + embedding; e.g. `powermem-server --host 0.0.0.0 --port 8000`. + - Check: `curl -s http://localhost:8000/api/v1/system/health` (or `/api/v2/system/health` for v2). 6. **Configure OpenClaw** @@ -68,10 +65,12 @@ The curl **`install.sh`** deploys the plugin and OpenClaw entries; with **`-y`** openclaw config set plugins.enabled true openclaw config set plugins.slots.memory memory-powermem openclaw config set plugins.entries.memory-powermem.config.mode cli - openclaw config set plugins.entries.memory-powermem.config.pmemPath pmem + openclaw config set plugins.entries.memory-powermem.config.pmemPath bundled openclaw config set plugins.entries.memory-powermem.config.useOpenClawModel true --json openclaw config set plugins.entries.memory-powermem.config.autoCapture true --json openclaw config set plugins.entries.memory-powermem.config.autoRecall true --json + openclaw config set plugins.entries.memory-powermem.config.autoExperience true --json + openclaw config set plugins.entries.memory-powermem.config.experienceRecall true --json openclaw config set plugins.entries.memory-powermem.config.inferOnAdd true --json ``` @@ -90,7 +89,11 @@ The curl **`install.sh`** deploys the plugin and OpenClaw entries; with **`-y`** openclaw config set plugins.entries.memory-powermem.config.baseUrl http://localhost:8000 ``` - Optional: `apiKey` if the server uses auth. + Optional: `apiKey` if the server uses auth. For v2, set: + ```bash + openclaw config set plugins.entries.memory-powermem.config.httpApiVersion v2 + openclaw config set plugins.entries.memory-powermem.config.requestConfig '{"memory_db":{"host":"db-host","port":2881}}' --json + ``` 7. **Verify** Restart **gateway**, then in another terminal: @@ -109,9 +112,9 @@ The curl **`install.sh`** deploys the plugin and OpenClaw entries; with **`-y`** ## One-click plugin deploy (`install.sh`) -**Requires:** OpenClaw installed (`openclaw --version`). The script does **not** run `pip install powermem`; ensure **`pmem`** is on PATH when the gateway runs or set **`pmemPath`**. +**Requires:** OpenClaw installed (`openclaw --version`). The script runs **`npm install`** (or equivalent) **inside the deployed plugin directory** so **powermem-ts** is available; it does **not** run `pip install powermem`. Default **`pmemPath`** is **`bundled`** (npm CLI). -**Default:** configures plugin **CLI** mode. With **`-y`**, it may still create **`~/.openclaw/powermem/powermem.env`** as an optional template — not required if you use OpenClaw-injected LLM + default SQLite. +**Default:** configures plugin **CLI** mode. With **`-y`**, it may still create **`~/.openclaw/powermem/powermem.env`** as an optional template — not required if you use OpenClaw-injected LLM + default SQLite + bundled CLI. ```bash curl -fsSL https://raw.githubusercontent.com/ob-labs/memory-powermem/main/install.sh | bash @@ -192,6 +195,12 @@ Plugin data and default SQLite follow **that** instance’s `stateDir`. | **memory_recall** | Search long-term memories. Params: `query`, optional `limit`, `scoreThreshold`. | | **memory_store** | Save text; optional infer. Params: `text`, optional `importance`. | | **memory_forget** | Delete by `memoryId` or by `query` search. | +| **experience_store** | Store a procedural experience. | +| **experience_recall** | Recall experiences. | +| **agent_memory_add** | Add memory to another agent (HTTP v2 only). | +| **agent_memory_list** | List an agent’s memories (HTTP v2 only). | +| **agent_memory_share** | Share memories across agents (HTTP v2 only). | +| **agent_memory_shared** | List memories shared with an agent (HTTP v2 only). | ## Configuration (summary) @@ -200,17 +209,25 @@ Plugin data and default SQLite follow **that** instance’s `stateDir`. | `mode` | `cli` | `cli` or `http`. | | `baseUrl` | — | Required for HTTP; if `mode` omitted and `baseUrl` set → HTTP. | | `apiKey` | — | HTTP server auth. | +| `httpApiVersion` | `v1` | HTTP API version: `v1` or `v2`. | +| `requestConfig` | — | HTTP v2: per-request config (e.g. `memory_db`). | | `envFile` | — | Optional CLI `.env` (used only if file exists). | -| `pmemPath` | `pmem` | CLI binary path. | +| `pmemPath` | `bundled` | CLI: **`bundled`** = npm **powermem-ts** next to the plugin; **`auto`** / empty resolves bundled then falls back to **`pmem` on PATH** (e.g. Python); or an absolute path to a `pmem` executable. | | `useOpenClawModel` | `true` | Inject LLM/embedding from OpenClaw + default SQLite under state dir. | | `recallLimit` | `5` | Max memories per recall. | | `recallScoreThreshold` | `0` | Min score 0–1. | -| `autoCapture` / `autoRecall` / `inferOnAdd` | `true` | Auto memory pipeline and infer on add. | +| `autoCapture` / `autoRecall` / `autoExperience` / `experienceRecall` / `inferOnAdd` | `true` | Auto memory + experience pipeline and infer on add. | +| `userId` / `agentId` | auto | Omit or set to `auto` to generate stable IDs saved under `/powermem/identity.json`. | +| `dualWrite` | `false` | HTTP only: remote + local SQLite dual-write. | +| `localDbPath` | — | Local SQLite path for dual-write. | +| `localUserId` / `localAgentId` | — | Local namespace for dual-write (defaults to `userId`/`agentId`). | +| `localVector` | — | Optional local vector search for dual-write fallback (OpenAI/Ollama + sqlite-vec). | +| `syncOnResume` / `syncBatchSize` / `syncMinIntervalMs` / `syncBaseDelayMs` / `syncMaxDelayMs` / `syncMaxRetries` | see defaults | Retry controls for pending sync. | ## Daily Operations ```bash -openclaw gateway +openclaw gateway restart openclaw ltm health openclaw ltm add "Some fact to remember" @@ -226,9 +243,11 @@ Restart the gateway after slot or plugin config changes. | Symptom | Fix | |---------|-----| -| **Python < 3.10** | Run step 2 first; upgrade Python or use `python3.11` / `python3.12` for venv and `pip install`. Do not skip the version check. | -| **`pip install powermem` fails** | Confirm Python 3.10+, clean venv. See [PowerMem issues](https://github.com/oceanbase/powermem/issues). | -| **`pmem` not found** | Activate venv or set **`pmemPath`** to the full binary. | +| **`spawnSync pmem ENOENT` / bundled CLI not resolved** | Run **`pnpm install` / `npm install`** in the plugin directory; ensure **`pmemPath`** is **`bundled`** or points to a real **`powermem/dist/cli.js`**. | +| **`ERR_MODULE_NOT_FOUND` (e.g. `@langchain/openai`)** | Ensure plugin **`package.json`** dependencies are installed (**memory-powermem** lists **`@langchain/openai`** for optional peers of **powermem**). | +| **`better-sqlite3` failed to load** | **`pnpm rebuild better-sqlite3`** or allow build scripts per **`pnpm.onlyBuiltDependencies`** in the plugin **`package.json`**. | +| **Python path only:** **Python < 3.10** or **`pip install powermem` fails** | Upgrade Python / clean venv. See [oceanbase/powermem](https://github.com/oceanbase/powermem/issues). | +| **`pmem` not found** (PATH / Python) | Set **`pmemPath`** to the venv **`pmem`** absolute path, or use **`bundled`**. | | **`openclaw ltm health` unhealthy (CLI)** | Confirm **`agents.defaults.model`** and provider keys in OpenClaw; gateway version should expose plugin **`config`** + **`runtime.modelAuth`**. Or set **`useOpenClawModel: false`** and a full **`envFile`**. | | **Health OK but add/search errors** | Embedding/LLM mismatch for your provider—see gateway logs; try optional **PowerMem `.env`** from [.env.example](https://github.com/oceanbase/powermem/blob/master/.env.example). | | **Wrong SQLite file / instance** | Data is under **that OpenClaw instance’s `stateDir`** (`OPENCLAW_STATE_DIR` / `--workdir`). | diff --git a/skills/install-memory-powermem-full/config-reference.md b/skills/install-memory-powermem-full/config-reference.md index 86f9ab5..6d9e0d8 100644 --- a/skills/install-memory-powermem-full/config-reference.md +++ b/skills/install-memory-powermem-full/config-reference.md @@ -4,14 +4,13 @@ Quick reference for skill **`install-memory-powermem-full`**. See **SKILL.md** i --- -## Before the plugin: PowerMem (Python) +## Before the plugin: PowerMem CLI (default = powermem-ts) -- **Python 3.10+** — `python3 --version`. -- **Install** — `pip install powermem` (virtualenv recommended). +- **Default (recommended)** — Plugin **`pmemPath: bundled`**: **powermem-ts** via npm package **`powermem`** inside the plugin directory. Run **`pnpm install` / `npm install`** in the plugin folder when installing from a **local path** or **`-l`** symlink. Dependencies include **`@langchain/openai`** (for optional peers) and **`better-sqlite3`** (native; **pnpm 10+** may require **`pnpm.onlyBuiltDependencies`** / **`pnpm rebuild better-sqlite3`**). - **CLI (default)** — No `powermem.env` required for the default setup: the plugin injects **SQLite** (under the OpenClaw **state directory**) and **LLM + embedding** from OpenClaw (`agents.defaults.model` + provider keys), as long as `useOpenClawModel` is `true` (default). -- **`pmem` on PATH** — When you start `openclaw gateway`, the same environment should expose `pmem`, or set plugin `pmemPath` to the binary’s absolute path (e.g. inside a venv). +- **Optional: Python `pmem`** — **Python 3.10+**, `pip install powermem` ([oceanbase/powermem](https://github.com/oceanbase/powermem)), then set **`pmemPath`** to the venv **`pmem`** absolute path (gateway often does not inherit venv `PATH`). - **Optional `.env`** — Set `envFile` to a PowerMem `.env` if you want file-based overrides; if the file exists, it is loaded first, then OpenClaw-derived variables **override** the same keys (when `useOpenClawModel` is true). -- **HTTP (shared server)** — Run `powermem-server` with its own `.env`; plugin `mode: http` + `baseUrl`. Verify with `curl` on `/api/v1/system/health`. +- **HTTP (shared server)** — Run **`powermem-server`** (npm or Python/Docker); plugin `mode: http` + `baseUrl`. Use `httpApiVersion: v2` + `requestConfig` for per-request config. Verify with `curl` on `/api/v1/system/health` or v2 `/api/v2/system/health`. --- @@ -28,12 +27,12 @@ Quick reference for skill **`install-memory-powermem-full`**. See **SKILL.md** i --- -## Installing PowerMem (do this before the plugin) +## Installing PowerMem vs installing the plugin -- **Python 3.10+** required. Check with `python3 --version`. -- **Install**: `pip install powermem` (prefer inside a virtualenv). -- **HTTP mode**: Create a `.env` (copy from [PowerMem .env.example](https://github.com/oceanbase/powermem/blob/master/.env.example)), set at least database + LLM + Embedding. Start server in that directory: `powermem-server --port 8000`. Verify: `curl -s http://localhost:8000/api/v1/system/health`. -- **CLI mode**: Ensure `pmem` is on PATH (e.g. activate the venv where powermem is installed). Optional: `pmem config init` for `.env`. +- **Default:** Install **memory-powermem** first; **powermem-ts** comes as a **dependency** of the plugin—**no** separate `pip install` for CLI mode. +- **Python-only CLI path:** `pip install powermem` (prefer a virtualenv), then configure **`pmemPath`** to that `pmem` binary. +- **HTTP mode**: Create a `.env` (see PowerMem / powermem-ts docs), set at least database + LLM + Embedding. Start server in that directory: `powermem-server --port 8000`. Verify: `curl -s http://localhost:8000/api/v1/system/health`. +- **CLI mode (Python):** Ensure `pmem` is on PATH or set **`pmemPath`** to an absolute path. Optional: `pmem config init` for `.env`. --- @@ -44,14 +43,49 @@ Quick reference for skill **`install-memory-powermem-full`**. See **SKILL.md** i | `mode` | `cli` | `cli` (local `pmem`) or `http` (`powermem-server`). | | `baseUrl` | — | Required when `mode` is `http` (or omit `mode` and set non-empty `baseUrl` → HTTP). | | `apiKey` | — | HTTP: optional PowerMem server API key. | +| `httpApiVersion` | `v1` | HTTP API version: `v1` or `v2`. | +| `requestConfig` | — | HTTP v2 only: forwarded as `config` (e.g. `memory_db`). | | `envFile` | — | CLI: optional path to PowerMem `.env` (only used if the file exists). | -| `pmemPath` | `pmem` | CLI: `pmem` executable path. | +| `pmemPath` | `bundled` | CLI: **`bundled`** = npm **powermem-ts** next to the plugin; **`auto`** / empty = resolve bundled then **`pmem` on PATH**; or absolute path to a `pmem` executable (e.g. Python venv). | | `useOpenClawModel` | `true` | Inject LLM/embedding from OpenClaw; default SQLite under state dir. Set `false` to disable injection (you must then provide a full `.env` or env vars). | | `recallLimit` | `5` | Max memories per recall / auto-recall. | | `recallScoreThreshold` | `0` | Min score (0–1) to keep a hit. | | `autoCapture` | `true` | Auto-store from conversations. | | `autoRecall` | `true` | Auto-inject relevant memories before reply. | +| `autoExperience` | `true` | Auto-extract experiences via LLM. | +| `experienceRecall` | `true` | Include experiences in recall. | | `inferOnAdd` | `true` | PowerMem intelligent extraction on add. | +| `userId` | auto | Omit or set to `auto` to generate a stable ID saved under `/powermem/identity.json`. | +| `agentId` | auto | Omit or set to `auto` to generate a stable ID saved under `/powermem/identity.json`. | +| `dualWrite` | `false` | HTTP only: remote + local SQLite dual-write. | +| `localDbPath` | — | Local SQLite path for dual-write. | +| `localUserId` | — | Local namespace for dual-write (defaults to `userId`). | +| `localAgentId` | — | Local namespace for dual-write (defaults to `agentId`). | +| `localVector` | — | Optional local vector search for dual-write fallback (OpenAI/Ollama embeddings + sqlite-vec). | +| `syncOnResume` | `true` | Sync pending writes on startup. | +| `syncBatchSize` | `50` | Batch size for sync. | +| `syncMinIntervalMs` | `5000` | Minimum sync interval. | +| `syncBaseDelayMs` | `5000` | Base retry delay. | +| `syncMaxDelayMs` | `60000` | Max retry delay. | +| `syncMaxRetries` | `10` | Max retries per item. | + +**`localVector` fields (optional):** + +```json +{ + "localVector": { + "enabled": true, + "provider": "openai", + "model": "text-embedding-3-small", + "apiKey": "YOUR_KEY", + "baseUrl": "https://api.openai.com", + "headers": { "X-Org": "..." } + } +} +``` + +- If `localVector` is omitted and `dualWrite: true`, the plugin attempts to reuse **OpenClaw** `agents.*.memorySearch` provider/model; otherwise defaults to OpenAI (`text-embedding-3-small`). +- If embedding auth is unavailable, it automatically falls back to local **FTS/token** search. --- @@ -87,7 +121,7 @@ Prefer `openclaw config set` when possible; use these when editing **`~/.opencla "config": { "mode": "cli", "envFile": "/home/you/.openclaw/powermem/powermem.env", - "pmemPath": "pmem", + "pmemPath": "bundled", "autoCapture": true, "autoRecall": true, "inferOnAdd": true @@ -98,7 +132,7 @@ Prefer `openclaw config set` when possible; use these when editing **`~/.opencla } ``` -If `pmem` lives only inside a venv, set **`pmemPath`** to that binary’s absolute path. With **`useOpenClawModel: true`** and no need for a file, you can omit **`envFile`** (see **SKILL.md** for the recommended `openclaw config set` flow). +Default **`pmemPath`** is **`bundled`** (npm **powermem-ts**). If you use **Python** `pmem` inside a venv only, set **`pmemPath`** to that binary’s absolute path. With **`useOpenClawModel: true`** and no need for a file, you can omit **`envFile`** (see **SKILL.md** for the recommended `openclaw config set` flow). **HTTP mode (shared server):** diff --git a/skills/install-memory-powermem-full/powermem-intro.md b/skills/install-memory-powermem-full/powermem-intro.md index cc7f672..ed00dac 100644 --- a/skills/install-memory-powermem-full/powermem-intro.md +++ b/skills/install-memory-powermem-full/powermem-intro.md @@ -6,9 +6,9 @@ Ships with OpenClaw skill **`install-memory-powermem-full`** (folder `install-me ## What is PowerMem? -**PowerMem** ([GitHub: oceanbase/powermem](https://github.com/oceanbase/powermem)) is a **long-term memory engine** that gives AI applications persistent, retrievable memory. With the **memory-powermem** plugin it is usually used via the **CLI** (`pmem`) on the same machine as OpenClaw; you can instead run an **HTTP server** (`powermem-server`) for shared or team setups. +**PowerMem** is a **long-term memory engine** with multiple implementations. The **memory-powermem** plugin’s **default** is **powermem-ts** ([ob-labs/powermem-ts](https://github.com/ob-labs/powermem-ts) on npm as package **`powermem`**): the plugin runs the **`pmem` CLI** from **`node_modules`** (**`pmemPath: bundled`**) on the same machine as OpenClaw. Alternatively you can point **`pmemPath`** at the **Python** CLI from [oceanbase/powermem](https://github.com/oceanbase/powermem), or run an **HTTP server** (**`powermem-server`**) for shared or team setups. -- **OpenClaw does not bundle Python**: The plugin runs `pmem` as a subprocess (CLI) or talks to a HTTP API (server mode). Install PowerMem with `pip` (or use Docker for server mode). +- **No Python required for the default path**: The bundled npm CLI is sufficient. Python / Docker remain optional for operators who prefer the upstream Python stack or containerized server. - **Data stays on the user’s machine** (typical setup): **SQLite** under the OpenClaw **state directory** (`/powermem/data/powermem.db`) when using plugin defaults—**no `powermem.env` file is required** for that layout. Larger deployments can still use OceanBase, PostgreSQL, etc., configured in PowerMem’s own `.env` or server config. --- @@ -18,9 +18,11 @@ Ships with OpenClaw skill **`install-memory-powermem-full`** (folder `install-me | Feature | Description | |---------|-------------| | **Intelligent extraction (Infer)** | On write, an LLM can summarize, dedupe, and structure content. Needs LLM + embedding configured—either injected from **OpenClaw** (default) or from a PowerMem `.env`. | +| **Experience extraction** | The plugin can distill procedural experiences with LLMs and recall them later. | | **Ebbinghaus forgetting curve** | Adjusts retention / importance so less relevant memories fade over time. | | **Multi-agent / multi-user isolation** | `userId`, `agentId`, etc. separate namespaces in the store. | | **Vector search** | Embedding-based semantic search for recall. | +| **Local dual-write vector fallback** | Optional local SQLite + sqlite-vec for vector search when HTTP backend is down. | --- @@ -30,11 +32,11 @@ Ships with OpenClaw skill **`install-memory-powermem-full`** (folder `install-me - **memory-powermem**: Implements that slot and forwards add/search/forget to PowerMem (CLI or HTTP). - **PowerMem**: Stores data, runs extraction, search, and forgetting logic. -**Typical personal setup:** `pip install powermem`, ensure **`agents.defaults.model`** and provider keys are set in OpenClaw, install the plugin, use **CLI mode** with defaults (`useOpenClawModel: true`, no `envFile`). The plugin supplies SQLite paths and LLM/embedding env to each `pmem` call. +**Typical personal setup:** Install **memory-powermem** (plugin runs **powermem-ts** via **`bundled`**), ensure **`agents.defaults.model`** and provider keys are set in OpenClaw, use **CLI mode** with defaults (`useOpenClawModel: true`, no `envFile`). The plugin supplies SQLite paths and LLM/embedding env to each `pmem` call. *Optional:* `pip install powermem` (Python) and set **`pmemPath`** to that binary if you do not use the bundled CLI. **Optional:** Point **`envFile`** at a PowerMem `.env` for advanced DB/provider tuning; OpenClaw can still override LLM-related keys when `useOpenClawModel` is true. -**HTTP mode:** Run `powermem-server`, set plugin `mode: http` and `baseUrl`. +**HTTP mode:** Run `powermem-server`, set plugin `mode: http` and `baseUrl`. HTTP v2 supports per-request `config` and agent memory sharing. --- @@ -54,7 +56,7 @@ OpenClaw can use **files as memory** (e.g. `memory/YYYY-MM-DD.md`, `MEMORY.md`). ## Two usage modes -- **CLI mode (default)**: Plugin runs `pmem`; SQLite + LLM often come from **OpenClaw config** (no mandatory `.env`). +- **CLI mode (default)**: Plugin runs **`pmem`** (default: npm **powermem-ts**); SQLite + LLM often come from **OpenClaw config** (no mandatory `.env`). - **HTTP mode**: Central `powermem-server`; plugin uses `baseUrl` (and optional `apiKey`). Full steps: **SKILL.md** in this folder. diff --git a/skills/install-memory-powermem/SKILL.md b/skills/install-memory-powermem/SKILL.md index dd6af1b..59ee11c 100644 --- a/skills/install-memory-powermem/SKILL.md +++ b/skills/install-memory-powermem/SKILL.md @@ -1,6 +1,6 @@ --- name: install-memory-powermem -description: OpenClaw skill「快速安装」路径(skill id 与目录名均为 install-memory-powermem):memory-powermem + PowerMem 最少步骤,面向个人用户;无需单独配置 powermem.env,复用 OpenClaw 里已配好的对话模型。可独立分发;完整选项、工具说明与排错见 install-memory-powermem-full。 +description: OpenClaw skill「快速安装」路径(skill id 与目录名均为 install-memory-powermem):memory-powermem + PowerMem 最少步骤,面向个人用户;默认 powermem-ts(npm 包 powermem)CLI,无需 Python;无需单独配置 powermem.env,复用 OpenClaw 里已配好的对话模型。可独立分发;完整选项、工具说明与排错见 install-memory-powermem-full。 triggers: - "PowerMem 快速安装" - "PowerMem 最简单安装" @@ -19,7 +19,7 @@ triggers: 本 skill 在 OpenClaw 中的标识与建议目录名为 **`install-memory-powermem`**。若需要 HTTP/多实例、工具表与详细排错,请改用 **`install-memory-powermem-full`**(仓库内 `skills/install-memory-powermem-full/`,需一并拷贝该目录下全部 `.md`)。 -你只要记住几件事:**OpenClaw 能正常聊天**、**Python 先确认 ≥ 3.10**、**本机装好 PowerMem**、**装上插件**。不用手写 `powermem.env`,记忆用的模型和 Key 会跟你在 OpenClaw 里配的一样。 +你只要记住几件事:**OpenClaw 能正常聊天**、**装上 memory-powermem 插件**。默认走 **powermem-ts**(npm 包名 `powermem`,由插件依赖提供,**不需要**先装 Python)。不用手写 `powermem.env`,记忆用的模型和 Key 会跟你在 OpenClaw 里配的一样。 --- @@ -28,42 +28,26 @@ triggers: 1. **确认 OpenClaw 已经能用** 终端执行 `openclaw --version`,并且你已经在 OpenClaw 里配好了**平时对话用的模型**(能正常回复即可)。 -2. **先检查 Python 版本(必须 ≥ 3.10)** - 在创建虚拟环境或执行 `pip install` **之前**必须先确认版本,否则后续容易装失败或运行异常: - ```bash - python3 --version - ``` - 输出应为 **Python 3.10.x、3.11.x、3.12.x** 等(次版本号 ≥ 10)。也可用下面命令做一次硬性校验(不通过会报错退出): - ```bash - python3 -c "import sys; assert sys.version_info >= (3, 10), '需要 Python 3.10 或更高'; print(sys.version.split()[0], 'OK')" - ``` - 若版本不够:先升级本机 Python,或安装并使用 `python3.11` / `python3.12` 等满足要求的解释器,并将下面步骤里的 **`python3`** 换成实际命令(例如 `python3.12 -m venv ...`)。 +2. **安装 memory-powermem 插件** + 任选其一: + - **registry:** `openclaw plugins install memory-powermem` + - **一键脚本(Mac / Linux):** + ```bash + curl -fsSL https://raw.githubusercontent.com/ob-labs/memory-powermem/main/install.sh | bash -s -y + ``` + 已克隆本仓库时可在根目录执行 `bash install.sh`(可加 `-y`;多实例:`bash -s -- --workdir ~/.openclaw-second`)。 + - **本地克隆:** `openclaw plugins install /path/to/memory-powermem` 或 **`openclaw plugins install -l`**(软链开发) + 默认 **`pmemPath: bundled`**:使用插件依赖里的 **powermem-ts**(npm 包名 **`powermem`**)提供的 CLI,**不需要**本机 `pip install powermem`。 -3. **安装 PowerMem(Python)** - 建议用虚拟环境,然后安装: - ```bash - python3 -m venv ~/.openclaw/powermem/.venv - source ~/.openclaw/powermem/.venv/bin/activate - pip install powermem - ``` - 装好后执行 `pmem --version`,能输出版本就行。 - -4. **让网关能找到 `pmem`** - 如果你启动 `openclaw gateway` 的终端**没有**激活上面的 venv,有两种简单办法二选一: - - 每次开网关前先 `source ~/.openclaw/powermem/.venv/bin/activate`;或 - - 在插件配置里把 **`pmemPath`** 写成 venv 里 `pmem` 的**完整路径**(装完后可用 `which pmem` 查看)。 +3. **若从本地路径安装:在插件目录安装 Node 依赖** + 从 **npm registry** 安装或 **`install.sh`** 已在插件目录执行过依赖安装时,**可跳过本步**。否则进入 OpenClaw 指向的插件目录(或克隆根目录),执行 **`pnpm install` / `npm install`**,确保拉取 **`powermem`**、**`@langchain/openai`** 等。使用 **pnpm 10+** 时若 **`better-sqlite3`** 未编译,可执行 **`pnpm rebuild better-sqlite3`**(仓库 `package.json` 已配置 **`pnpm.onlyBuiltDependencies`** 时一般可自动构建)。 -5. **一键装插件(推荐)** - 在 **Mac / Linux** 上执行(需已安装 OpenClaw)。脚本**不会**替你执行 `pip install powermem`;装插件前仍需完成上面的 PowerMem 与 `pmem` 步骤。 - ```bash - curl -fsSL https://raw.githubusercontent.com/ob-labs/memory-powermem/main/install.sh | bash -s -y - ``` - 已克隆本仓库时,也可在仓库根目录执行:`bash install.sh`(可加 `-y`、或 `bash -s -- --workdir ~/.openclaw-second` 指定另一套 OpenClaw 数据目录)。 - 脚本会把插件放进 OpenClaw,并打开「用 OpenClaw 的模型驱动记忆」等默认选项;带 `-y` 时仍可能生成可选模板 **`~/.openclaw/powermem/powermem.env`**(默认路径下通常不必手改)。 +4. **(可选)改用 Python 版 `pmem`** + 若你希望使用 [oceanbase/powermem](https://github.com/oceanbase/powermem) 的 **Python CLI**:**Python ≥ 3.10**,`pip install powermem`,并在插件配置里将 **`pmemPath`** 设为 venv 中 `pmem` 的**绝对路径**。详见 **`install-memory-powermem-full`** 与 **config-reference.md**。 -6. **重启网关并检查** +5. **重启网关并检查** ```bash - openclaw gateway + openclaw gateway restart ``` 另开终端,**先**确认插件已被网关加载: ```bash @@ -86,9 +70,9 @@ triggers: | 情况 | 怎么办 | |------|--------| -| `python3 --version` 低于 3.10 | **先升级或换用** `python3.11` / `python3.12` 等,再重做「检查 Python」与 venv 步骤;不要跳过版本检查强行 `pip install`。 | -| `pip install powermem` 报错 | 再次确认 Python ≥ 3.10;换干净 venv 再试。 | -| `pmem` 找不到 | 激活 venv,或配置 **`pmemPath`** 为绝对路径。 | +| `pmem` / CLI 找不到、`ERR_MODULE_NOT_FOUND`(如 `@langchain/openai`) | 在插件目录执行 **`pnpm install` / `npm install`**;路径安装用 **`openclaw plugins install -l`** 时确保依赖完整。 | +| `better-sqlite3` 未编译(pnpm 忽略构建脚本) | 在插件目录 **`pnpm rebuild better-sqlite3`**,或配置 **`pnpm.onlyBuiltDependencies`** 后重装依赖(见仓库 `package.json`)。 | +| 坚持用 **Python** `pmem` 但找不到命令 | 激活 venv,或配置 **`pmemPath`** 为 `which pmem` 的绝对路径。 | | `plugins list` 没有 **memory-powermem**,或状态不是 **loaded** | 确认已执行安装脚本或 `openclaw plugins install`;`plugins.enabled` 为 true、`plugins.slots.memory` 为 **memory-powermem**;改完后**重启 gateway**,再执行 `openclaw plugins list` 复查。 | | `ltm health` 不健康 | 确认 OpenClaw 里**默认模型**和 API Key 本身能聊天;升级 OpenClaw 到较新版本后再试。 | | 想要更多选项(多实例、HTTP、`install.sh` 细节、工具与排错表等) | 使用 **`install-memory-powermem-full`** skill(含 **config-reference.md**),或查阅 **[memory-powermem](https://github.com/ob-labs/memory-powermem)** 的 **README**。 | @@ -97,4 +81,4 @@ triggers: ## 说明(一句话) -记忆数据默认存在本机 OpenClaw 数据目录下的 SQLite 里;**不需要**你再单独维护一份 PowerMem 的 `.env`,除非你熟悉进阶配置。 +记忆数据默认存在本机 OpenClaw 数据目录下的 SQLite 里;默认 CLI 为 **powermem-ts(npm)**;**不需要**你再单独维护一份 PowerMem 的 `.env`,除非你熟悉进阶配置。`userId/agentId` 未配置会自动生成并持久化。HTTP + `dualWrite` 场景可选 `localVector`(sqlite-vec)提升本地兜底搜索质量。 diff --git a/client-cli.ts b/src/client-cli.ts similarity index 70% rename from client-cli.ts rename to src/client-cli.ts index f840159..6f51742 100644 --- a/client-cli.ts +++ b/src/client-cli.ts @@ -6,8 +6,9 @@ import { existsSync } from "node:fs"; import { execFileSync } from "node:child_process"; -import type { PowerMemConfig } from "./config.js"; +import { DEFAULT_PMEM_PATH, type PowerMemConfig } from "./config.js"; import type { PowerMemAddResult, PowerMemSearchResult } from "./client.js"; +import { resolvePmemExecutable } from "./resolve-powermem-cli.js"; const DEFAULT_MAX_BUFFER = 10 * 1024 * 1024; // 10 MiB @@ -17,6 +18,7 @@ export type PowerMemCLIClientOptions = { resolvedEnvFile?: string; userId: string; agentId: string; + timeoutMs?: number; /** * Vars merged into the subprocess environment (after process.env). * OpenClaw + SQLite defaults; cached for the plugin process lifetime. @@ -36,50 +38,60 @@ function parseJsonOrThrow(stdout: string, context: string): T { } } -/** Normalize CLI add result to PowerMemAddResult[]. */ -function normalizeAddOutput(raw: unknown): PowerMemAddResult[] { +function coerceId(v: unknown): string | number { + if (v === null || v === undefined) return ""; + if (typeof v === "number" && Number.isFinite(v)) return v; + const s = String(v).trim(); + if (s !== "" && /^\d+$/.test(s)) { + const n = Number(s); + if (Number.isSafeInteger(n)) return n; + } + return s; +} + +function mapAddRow(r: Record): PowerMemAddResult { + const idRaw = r.memoryId ?? r.memory_id ?? r.id; + return { + memory_id: coerceId(idRaw), + content: String(r.memory ?? r.content ?? ""), + user_id: (r.userId ?? r.user_id) as string | undefined, + agent_id: (r.agentId ?? r.agent_id) as string | undefined, + metadata: r.metadata as Record | undefined, + }; +} + +function mapSearchRow(r: Record): PowerMemSearchResult { + const idRaw = r.memory_id ?? r.memoryId ?? r.id; + return { + memory_id: coerceId(idRaw), + content: String(r.content ?? r.memory ?? ""), + score: Number(r.score ?? r.similarity ?? 0), + metadata: r.metadata as Record | undefined, + }; +} + +/** Normalize CLI add JSON (Python pmem or powermem-ts) to PowerMemAddResult[]. */ +export function normalizeAddOutput(raw: unknown): PowerMemAddResult[] { if (Array.isArray(raw)) { - return raw.map((r) => ({ - memory_id: Number((r as Record).id ?? (r as Record).memory_id ?? 0), - content: String((r as Record).memory ?? (r as Record).content ?? ""), - user_id: (r as Record).user_id as string | undefined, - agent_id: (r as Record).agent_id as string | undefined, - metadata: (r as Record).metadata as Record | undefined, - })); + return raw.map((r) => mapAddRow(r as Record)); } const obj = raw as Record; - const results = obj?.results ?? obj?.data; + const results = obj?.memories ?? obj?.results ?? obj?.data; if (Array.isArray(results)) { - return results.map((r: Record) => ({ - memory_id: Number(r.id ?? r.memory_id ?? 0), - content: String(r.memory ?? r.content ?? ""), - user_id: r.user_id as string | undefined, - agent_id: r.agent_id as string | undefined, - metadata: r.metadata as Record | undefined, - })); + return results.map((r: Record) => mapAddRow(r)); } return []; } -/** Normalize CLI search result to PowerMemSearchResult[]. */ -function normalizeSearchOutput(raw: unknown): PowerMemSearchResult[] { +/** Normalize CLI search JSON to PowerMemSearchResult[]. */ +export function normalizeSearchOutput(raw: unknown): PowerMemSearchResult[] { if (Array.isArray(raw)) { - return raw.map((r) => ({ - memory_id: Number((r as Record).memory_id ?? (r as Record).id ?? 0), - content: String((r as Record).content ?? (r as Record).memory ?? ""), - score: Number((r as Record).score ?? (r as Record).similarity ?? 0), - metadata: (r as Record).metadata as Record | undefined, - })); + return raw.map((r) => mapSearchRow(r as Record)); } const obj = raw as Record; const results = obj?.results ?? obj?.data ?? obj?.memories; if (Array.isArray(results)) { - return results.map((r: Record) => ({ - memory_id: Number(r.memory_id ?? r.id ?? 0), - content: String(r.content ?? r.memory ?? ""), - score: Number(r.score ?? r.similarity ?? 0), - metadata: r.metadata as Record | undefined, - })); + return results.map((r: Record) => mapSearchRow(r)); } return []; } @@ -90,6 +102,7 @@ export class PowerMemCLIClient { private readonly userId: string; private readonly agentId: string; private readonly buildProcessEnv?: () => Promise>; + private readonly timeoutMs: number; private injectPromise: Promise> | null = null; constructor(options: PowerMemCLIClientOptions) { @@ -98,6 +111,7 @@ export class PowerMemCLIClient { this.userId = options.userId; this.agentId = options.agentId; this.buildProcessEnv = options.buildProcessEnv; + this.timeoutMs = options.timeoutMs ?? 60000; } static fromConfig( @@ -109,11 +123,12 @@ export class PowerMemCLIClient { const raw = cfg.envFile?.trim(); const resolved = raw && existsSync(raw) ? raw : undefined; return new PowerMemCLIClient({ - pmemPath: cfg.pmemPath ?? "pmem", + pmemPath: resolvePmemExecutable(cfg.pmemPath ?? DEFAULT_PMEM_PATH), resolvedEnvFile: resolved, userId, agentId, buildProcessEnv: extras?.buildProcessEnv, + timeoutMs: cfg.requestTimeoutMs, }); } @@ -139,6 +154,7 @@ export class PowerMemCLIClient { encoding: "utf-8", maxBuffer: DEFAULT_MAX_BUFFER, env, + timeout: this.timeoutMs > 0 ? this.timeoutMs : undefined, }); return out; } catch (err) { @@ -155,7 +171,7 @@ export class PowerMemCLIClient { return this.resolvedEnvFile ? ["--env-file", this.resolvedEnvFile] : []; } - async health(): Promise<{ status: string }> { + async health(): Promise<{ status: string; error?: string }> { const argsList = [ ...this.envFileArgs(), "--json", @@ -172,8 +188,9 @@ export class PowerMemCLIClient { try { await this.run(argsList, "health"); return { status: "healthy" }; - } catch { - return { status: "unhealthy" }; + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + return { status: "unhealthy", error: msg }; } } diff --git a/src/client-v2.ts b/src/client-v2.ts new file mode 100644 index 0000000..8d565da --- /dev/null +++ b/src/client-v2.ts @@ -0,0 +1,300 @@ +/** + * PowerMem HTTP API v2 client. + * Uses /api/v2 endpoints and per-request config. + */ + +import type { PowerMemConfig } from "./config.js"; +import { fetchWithTimeout } from "./http.js"; +import type { PowerMemAddResult, PowerMemSearchResult } from "./client.js"; + +export type PowermemRequestConfig = Record; + +type ApiResponse = { + success: boolean; + data?: T; + message?: string; +}; + +export type PowerMemV2ClientOptions = { + baseUrl: string; + apiKey?: string; + userId?: string; + agentId?: string; + requestConfig?: PowermemRequestConfig; + timeoutMs?: number; +}; + +function buildUrl(baseUrl: string, path: string): string { + const base = baseUrl.replace(/\/+$/, ""); + const p = path.startsWith("/") ? path : `/${path}`; + return `${base}${p}`; +} + +function buildHeaders(apiKey?: string): Record { + const headers: Record = { + "Content-Type": "application/json", + }; + if (apiKey) { + headers["X-API-Key"] = apiKey; + } + return headers; +} + +async function handleResponse(res: Response, parseJson = true): Promise { + const text = await res.text(); + if (!res.ok) { + let message = `PowerMem API ${res.status}: ${res.statusText}`; + try { + const body = text ? JSON.parse(text) : null; + if (body?.message) message = body.message; + else if (body?.detail) { + message = Array.isArray(body.detail) + ? body.detail.map((d: { msg?: string }) => d.msg ?? String(d)).join("; ") + : String(body.detail); + } + } catch { + if (text) message = text.slice(0, 200); + } + throw new Error(message); + } + if (!parseJson) return undefined as T; + if (!text) return undefined as T; + return JSON.parse(text) as T; +} + +function normalizeMemoryId(value: unknown): string | number { + if (value === null || value === undefined) return ""; + const str = String(value); + return str.trim() !== "" ? str : ""; +} + +export class PowerMemV2Client { + private readonly baseUrl: string; + private readonly apiKey?: string; + private readonly userId: string; + private readonly agentId: string; + private readonly requestConfig?: PowermemRequestConfig; + private readonly timeoutMs: number; + + constructor(options: PowerMemV2ClientOptions) { + this.baseUrl = options.baseUrl.replace(/\/+$/, ""); + this.apiKey = options.apiKey; + this.userId = options.userId ?? "openclaw-user"; + this.agentId = options.agentId ?? "openclaw-agent"; + this.requestConfig = options.requestConfig; + this.timeoutMs = options.timeoutMs ?? 30000; + } + + static fromConfig(cfg: PowerMemConfig, userId: string, agentId: string): PowerMemV2Client { + return new PowerMemV2Client({ + baseUrl: cfg.baseUrl, + apiKey: cfg.apiKey, + userId, + agentId, + requestConfig: cfg.requestConfig, + timeoutMs: cfg.requestTimeoutMs, + }); + } + + /** Share-all or many rows can exceed default timeout; floor avoids AbortError masking as generic failure. */ + private static readonly shareRequestMinTimeoutMs = 180_000; + + private async request( + method: string, + path: string, + body?: unknown, + parseJson = true, + timeoutOverrideMs?: number, + ): Promise { + const url = buildUrl(this.baseUrl, path); + const effectiveMs = + typeof timeoutOverrideMs === "number" + ? timeoutOverrideMs + : this.timeoutMs; + const res = await fetchWithTimeout( + url, + { + method, + headers: buildHeaders(this.apiKey), + body: body !== undefined ? JSON.stringify(body) : undefined, + }, + effectiveMs, + ); + return handleResponse(res, parseJson); + } + + private buildConfigPayload(): { config?: PowermemRequestConfig } { + if (!this.requestConfig) return {}; + return { config: this.requestConfig }; + } + + /** GET /api/v2/system/health */ + async health(): Promise<{ status: string; error?: string }> { + try { + const data = await this.request>( + "GET", + "/api/v2/system/health", + undefined, + ); + return { status: data?.data?.status ?? "unknown" }; + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + return { status: "unhealthy", error: msg }; + } + } + + /** POST /api/v2/memories */ + async add( + content: string, + options: { infer?: boolean; metadata?: Record } = {}, + ): Promise { + const body = { + content, + user_id: this.userId, + agent_id: this.agentId, + infer: options.infer ?? true, + ...(options.metadata && { metadata: options.metadata }), + ...this.buildConfigPayload(), + }; + const res = await this.request>>>( + "POST", + "/api/v2/memories", + body, + ); + const rows = res?.data ?? []; + return rows.map((row) => ({ + memory_id: normalizeMemoryId(row.memory_id ?? row.id), + content: String(row.content ?? ""), + user_id: row.user_id as string | undefined, + agent_id: row.agent_id as string | undefined, + metadata: row.metadata as Record | undefined, + })); + } + + /** POST /api/v2/memories/search */ + async search(query: string, limit = 5): Promise { + const body = { + query, + user_id: this.userId, + agent_id: this.agentId, + limit, + ...this.buildConfigPayload(), + }; + const res = await this.request>( + "POST", + "/api/v2/memories/search", + body, + ); + const rows = res?.data?.results ?? []; + return rows.map((row) => ({ + ...row, + memory_id: normalizeMemoryId(row.memory_id), + })); + } + + /** POST /api/v2/memories/delete/{id} */ + async delete(memoryId: number | string): Promise { + const id = typeof memoryId === "string" ? memoryId : String(memoryId); + const body = { + user_id: this.userId, + agent_id: this.agentId, + ...this.buildConfigPayload(), + }; + await this.request( + "POST", + `/api/v2/memories/delete/${encodeURIComponent(id)}`, + body, + false, + ); + } + + /** POST /api/v2/agents/{agent_id}/memories */ + async agentMemoryAdd( + targetAgentId: string, + content: string, + ): Promise { + const body = { + content, + user_id: this.userId, + agent_id: this.agentId, + ...this.buildConfigPayload(), + }; + const res = await this.request>>( + "POST", + `/api/v2/agents/${encodeURIComponent(targetAgentId)}/memories`, + body, + ); + if (!res?.data) return null; + return { + memory_id: normalizeMemoryId(res.data.memory_id ?? res.data.id), + content: String(res.data.content ?? ""), + user_id: res.data.user_id as string | undefined, + agent_id: res.data.agent_id as string | undefined, + metadata: res.data.metadata as Record | undefined, + }; + } + + /** POST /api/v2/agents/{agent_id}/memories/list */ + async agentMemoryList( + targetAgentId: string, + limit = 20, + offset = 0, + ): Promise>> { + const body = { + limit, + offset, + ...this.buildConfigPayload(), + }; + const res = await this.request> }>>( + "POST", + `/api/v2/agents/${encodeURIComponent(targetAgentId)}/memories/list`, + body, + ); + return res?.data?.memories ?? []; + } + + /** POST /api/v2/agents/{agent_id}/memories/share */ + async agentMemoryShare( + fromAgentId: string, + targetAgentId: string, + memoryIds?: number[], + ): Promise<{ shared_count?: number }> { + const body = { + target_agent_id: targetAgentId, + ...(memoryIds && memoryIds.length > 0 ? { memory_ids: memoryIds } : {}), + ...this.buildConfigPayload(), + }; + const shareTimeout = Math.max( + this.timeoutMs, + PowerMemV2Client.shareRequestMinTimeoutMs, + ); + const res = await this.request>>( + "POST", + `/api/v2/agents/${encodeURIComponent(fromAgentId)}/memories/share`, + body, + true, + shareTimeout, + ); + return { shared_count: Number(res?.data?.shared_count ?? 0) }; + } + + /** POST /api/v2/agents/{agent_id}/memories/shared */ + async agentMemoryShared( + targetAgentId: string, + limit = 20, + offset = 0, + ): Promise>> { + const body = { + limit, + offset, + user_id: this.userId, + ...this.buildConfigPayload(), + }; + const res = await this.request> }>>( + "POST", + `/api/v2/agents/${encodeURIComponent(targetAgentId)}/memories/shared`, + body, + ); + return res?.data?.memories ?? []; + } +} diff --git a/client.ts b/src/client.ts similarity index 76% rename from client.ts rename to src/client.ts index 9eeddd9..83d92b9 100644 --- a/client.ts +++ b/src/client.ts @@ -4,16 +4,18 @@ */ import type { PowerMemConfig } from "./config.js"; +import { fetchWithTimeout } from "./http.js"; export type PowerMemSearchResult = { - memory_id: number; + /** String IDs are used by powermem-ts; HTTP API may return numeric ids. */ + memory_id: string | number; content: string; score: number; metadata?: Record; }; export type PowerMemAddResult = { - memory_id: number; + memory_id: string | number; content: string; user_id?: string; agent_id?: string; @@ -59,6 +61,7 @@ export type PowerMemClientOptions = { apiKey?: string; userId?: string; agentId?: string; + timeoutMs?: number; }; export class PowerMemClient { @@ -66,12 +69,14 @@ export class PowerMemClient { private readonly apiKey?: string; private readonly userId: string; private readonly agentId: string; + private readonly timeoutMs: number; constructor(options: PowerMemClientOptions) { this.baseUrl = options.baseUrl.replace(/\/+$/, ""); this.apiKey = options.apiKey; this.userId = options.userId ?? "openclaw-user"; this.agentId = options.agentId ?? "openclaw-agent"; + this.timeoutMs = options.timeoutMs ?? 30000; } static fromConfig(cfg: PowerMemConfig, userId: string, agentId: string): PowerMemClient { @@ -80,6 +85,7 @@ export class PowerMemClient { apiKey: cfg.apiKey, userId, agentId, + timeoutMs: cfg.requestTimeoutMs, }); } @@ -90,22 +96,27 @@ export class PowerMemClient { parseJson = true, ): Promise { const url = buildUrl(this.baseUrl, path); - const res = await fetch(url, { + const res = await fetchWithTimeout(url, { method, headers: buildHeaders(this.apiKey), body: body !== undefined ? JSON.stringify(body) : undefined, - }); + }, this.timeoutMs); return handleResponse(res, parseJson); } /** GET /api/v1/system/health */ - async health(): Promise<{ status: string }> { - const data = await this.request<{ data?: { status?: string } }>( - "GET", - "/api/v1/system/health", - undefined, - ); - return { status: data?.data?.status ?? "unknown" }; + async health(): Promise<{ status: string; error?: string }> { + try { + const data = await this.request<{ data?: { status?: string } }>( + "GET", + "/api/v1/system/health", + undefined, + ); + return { status: data?.data?.status ?? "unknown" }; + } catch (err) { + const msg = err instanceof Error ? err.message : String(err); + return { status: "unhealthy", error: msg }; + } } /** POST /api/v1/memories */ @@ -126,7 +137,13 @@ export class PowerMemClient { body, ); if (!res?.data) return []; - return res.data; + return res.data.map((row) => ({ + ...row, + memory_id: + row.memory_id !== undefined && row.memory_id !== null + ? String(row.memory_id) + : row.memory_id, + })); } /** POST /api/v1/memories/search */ @@ -141,7 +158,14 @@ export class PowerMemClient { success: boolean; data?: { results?: PowerMemSearchResult[] }; }>("POST", "/api/v1/memories/search", body); - return res?.data?.results ?? []; + const rows = res?.data?.results ?? []; + return rows.map((row) => ({ + ...row, + memory_id: + row.memory_id !== undefined && row.memory_id !== null + ? String(row.memory_id) + : row.memory_id, + })); } /** DELETE /api/v1/memories/:memory_id */ diff --git a/src/config.ts b/src/config.ts new file mode 100644 index 0000000..d03bc31 --- /dev/null +++ b/src/config.ts @@ -0,0 +1,393 @@ +/** + * PowerMem memory plugin configuration. + * Validates baseUrl, optional apiKey, and user/agent mapping. + */ + +import { homedir } from "node:os"; +import { join } from "node:path"; + +function assertAllowedKeys( + value: Record, + allowed: string[], + label: string, +) { + const unknown = Object.keys(value).filter((key) => !allowed.includes(key)); + if (unknown.length === 0) return; + throw new Error(`${label} has unknown keys: ${unknown.join(", ")}`); +} + +function resolveEnvVars(value: string): string { + return value.replace(/\$\{([^}]+)\}/g, (_, envVar) => { + const envValue = process.env[envVar]; + if (!envValue) { + throw new Error(`Environment variable ${envVar} is not set`); + } + return envValue; + }); +} + +export type PowerMemMode = "http" | "cli"; +export type PowerMemHttpApiVersion = "v1" | "v2"; + +export type PowerMemConfig = { + mode: PowerMemMode; + baseUrl: string; + apiKey?: string; + httpApiVersion?: PowerMemHttpApiVersion; + requestTimeoutMs?: number; + requestConfig?: Record; + /** CLI mode: path to .env (optional; pmem discovers if omitted). */ + envFile?: string; + /** + * CLI: how to run `pmem`. + * - `bundled` (default): prefer npm `powermem` next to this plugin; else `pmem` on PATH (e.g. Python). + * - `auto`: same resolution as `bundled`. + * - any other string: command name or absolute path to a `pmem` binary. + */ + pmemPath?: string; + /** + * When true (default), inject LLM/embedding from OpenClaw gateway config into `pmem` + * (overrides the same keys from an optional .env file). SQLite defaults live under the OpenClaw state dir. + */ + useOpenClawModel?: boolean; + userId?: string; + agentId?: string; + /** Max memories to return in recall / inject in auto-recall. Default 5. */ + recallLimit?: number; + /** Min score (0–1) for recall; memories below are filtered. Default 0. */ + recallScoreThreshold?: number; + /** Incremental write-ahead capture during conversations. */ + walCapture: boolean; + autoCapture: boolean; + autoRecall: boolean; + autoExperience: boolean; + experienceRecall: boolean; + inferOnAdd: boolean; + debugPerfLog?: boolean; + perfSlowMs?: number; + dualWrite?: boolean; + localDbPath?: string; + localUserId?: string; + localAgentId?: string; + syncOnResume?: boolean; + syncBatchSize?: number; + syncMinIntervalMs?: number; + syncBaseDelayMs?: number; + syncMaxDelayMs?: number; + syncMaxRetries?: number; + localVector?: { + enabled?: boolean; + provider?: string; + model?: string; + apiKey?: string; + baseUrl?: string; + headers?: Record; + extensionPath?: string; + }; +}; + +const DEFAULT_RECALL_LIMIT = 5; +const DEFAULT_RECALL_SCORE_THRESHOLD = 0; + +const ALLOWED_KEYS = [ + "mode", + "baseUrl", + "apiKey", + "httpApiVersion", + "requestTimeoutMs", + "requestConfig", + "envFile", + "pmemPath", + "useOpenClawModel", + "userId", + "agentId", + "recallLimit", + "recallScoreThreshold", + "walCapture", + "autoCapture", + "autoRecall", + "autoExperience", + "experienceRecall", + "inferOnAdd", + "debugPerfLog", + "perfSlowMs", + "dualWrite", + "localDbPath", + "localUserId", + "localAgentId", + "syncOnResume", + "syncBatchSize", + "syncMinIntervalMs", + "syncBaseDelayMs", + "syncMaxDelayMs", + "syncMaxRetries", + "localVector", +] as const; + +/** CLI `pmemPath` when omitted; npm `powermem` bundled with this plugin. */ +export const DEFAULT_PMEM_PATH = "bundled"; + +export const powerMemConfigSchema = { + parse(value: unknown): PowerMemConfig { + if (!value || typeof value !== "object" || Array.isArray(value)) { + throw new Error("memory-powermem config required"); + } + const cfg = value as Record; + assertAllowedKeys(cfg, [...ALLOWED_KEYS], "memory-powermem config"); + + const modeExplicit = + cfg.mode === "cli" || cfg.mode === "http" ? cfg.mode : undefined; + const baseUrlForInfer = + typeof cfg.baseUrl === "string" ? cfg.baseUrl.trim() : ""; + const mode = + modeExplicit ?? (baseUrlForInfer ? "http" : "cli"); + + let baseUrl = ""; + let apiKey: string | undefined; + if (mode === "http") { + const baseUrlRaw = cfg.baseUrl; + if (typeof baseUrlRaw !== "string" || !baseUrlRaw.trim()) { + throw new Error("memory-powermem baseUrl is required when mode is http"); + } + baseUrl = resolveEnvVars(baseUrlRaw.trim()).replace(/\/+$/, ""); + const apiKeyRaw = cfg.apiKey; + apiKey = + typeof apiKeyRaw === "string" && apiKeyRaw.trim() + ? resolveEnvVars(apiKeyRaw.trim()) + : undefined; + } + + const envFileRaw = cfg.envFile; + const envFile = + typeof envFileRaw === "string" && envFileRaw.trim() + ? envFileRaw.trim() + : undefined; + + const pmemPathRaw = cfg.pmemPath; + const pmemPath = + typeof pmemPathRaw === "string" && pmemPathRaw.trim() + ? pmemPathRaw.trim() + : DEFAULT_PMEM_PATH; + + const httpApiVersion = + cfg.httpApiVersion === "v2" ? "v2" : "v1"; + + const requestTimeoutMs = toPositiveInt(cfg.requestTimeoutMs, 30000, 0, 300000); + const requestConfig = + cfg.requestConfig && typeof cfg.requestConfig === "object" && !Array.isArray(cfg.requestConfig) + ? cfg.requestConfig as Record + : undefined; + + const localDbPathRaw = cfg.localDbPath; + const localDbPath = + typeof localDbPathRaw === "string" && localDbPathRaw.trim() + ? resolveEnvVars(localDbPathRaw.trim()) + : undefined; + const localVectorRaw = cfg.localVector; + const localVectorCandidate = + localVectorRaw && typeof localVectorRaw === "object" && !Array.isArray(localVectorRaw) + ? (localVectorRaw as Record) + : undefined; + const localVector = + localVectorCandidate + ? pruneUndefined({ + enabled: + typeof localVectorCandidate.enabled === "boolean" + ? localVectorCandidate.enabled + : undefined, + provider: + typeof localVectorCandidate.provider === "string" && + localVectorCandidate.provider.trim() + ? localVectorCandidate.provider.trim() + : undefined, + model: + typeof localVectorCandidate.model === "string" && localVectorCandidate.model.trim() + ? localVectorCandidate.model.trim() + : undefined, + apiKey: + typeof localVectorCandidate.apiKey === "string" && localVectorCandidate.apiKey.trim() + ? resolveEnvVars(localVectorCandidate.apiKey.trim()) + : undefined, + baseUrl: + typeof localVectorCandidate.baseUrl === "string" && + localVectorCandidate.baseUrl.trim() + ? resolveEnvVars(localVectorCandidate.baseUrl.trim()).replace(/\/+$/, "") + : undefined, + headers: parseHeaderMap(localVectorCandidate.headers), + extensionPath: + typeof localVectorCandidate.extensionPath === "string" && + localVectorCandidate.extensionPath.trim() + ? resolveEnvVars(localVectorCandidate.extensionPath.trim()) + : undefined, + }) + : undefined; + + const syncBatchSize = toPositiveInt(cfg.syncBatchSize, 50, 1, 500); + const syncMinIntervalMs = toPositiveInt(cfg.syncMinIntervalMs, 5000, 1000, 600000); + const syncBaseDelayMs = toPositiveInt(cfg.syncBaseDelayMs, 5000, 1000, 600000); + const syncMaxDelayMs = toPositiveInt(cfg.syncMaxDelayMs, 60000, 1000, 3600000); + const syncMaxRetries = toPositiveInt(cfg.syncMaxRetries, 10, 0, 100); + + return { + mode, + baseUrl, + apiKey, + httpApiVersion, + requestTimeoutMs, + requestConfig, + envFile, + pmemPath, + useOpenClawModel: cfg.useOpenClawModel !== false, + userId: + typeof cfg.userId === "string" && cfg.userId.trim() + ? cfg.userId.trim() + : undefined, + agentId: + typeof cfg.agentId === "string" && cfg.agentId.trim() + ? cfg.agentId.trim() + : undefined, + recallLimit: toRecallLimit(cfg.recallLimit), + recallScoreThreshold: toRecallScoreThreshold(cfg.recallScoreThreshold), + walCapture: cfg.walCapture !== false, + autoCapture: cfg.autoCapture !== false, + autoRecall: cfg.autoRecall !== false, + autoExperience: cfg.autoExperience !== false, + experienceRecall: cfg.experienceRecall !== false, + inferOnAdd: cfg.inferOnAdd !== false, + debugPerfLog: cfg.debugPerfLog === true, + perfSlowMs: toPositiveInt(cfg.perfSlowMs, 800, 1, 600000), + dualWrite: cfg.dualWrite === true, + localDbPath, + localUserId: + typeof cfg.localUserId === "string" && cfg.localUserId.trim() + ? cfg.localUserId.trim() + : undefined, + localAgentId: + typeof cfg.localAgentId === "string" && cfg.localAgentId.trim() + ? cfg.localAgentId.trim() + : undefined, + syncOnResume: cfg.syncOnResume !== false, + syncBatchSize, + syncMinIntervalMs, + syncBaseDelayMs, + syncMaxDelayMs, + syncMaxRetries, + localVector, + }; + }, +}; + +function toRecallLimit(v: unknown): number { + if (typeof v === "number" && Number.isFinite(v) && v >= 1) { + return Math.min(100, Math.floor(v)); + } + if (typeof v === "string" && /^\d+$/.test(v)) { + const n = parseInt(v, 10); + return n >= 1 ? Math.min(100, n) : DEFAULT_RECALL_LIMIT; + } + return DEFAULT_RECALL_LIMIT; +} + +function toRecallScoreThreshold(v: unknown): number { + if (typeof v === "number" && Number.isFinite(v)) { + return Math.max(0, Math.min(1, v)); + } + if (typeof v === "string" && v.trim() !== "") { + const n = Number(v); + if (Number.isFinite(n)) return Math.max(0, Math.min(1, n)); + } + return DEFAULT_RECALL_SCORE_THRESHOLD; +} + +function toPositiveInt( + v: unknown, + fallback: number, + min: number, + max: number, +): number { + if (typeof v === "number" && Number.isFinite(v)) { + const n = Math.floor(v); + return Math.min(max, Math.max(min, n)); + } + if (typeof v === "string" && v.trim() !== "") { + const n = Number(v); + if (Number.isFinite(n)) { + return Math.min(max, Math.max(min, Math.floor(n))); + } + } + return fallback; +} + +function parseHeaderMap(value: unknown): Record | undefined { + if (!value || typeof value !== "object" || Array.isArray(value)) { + return undefined; + } + const entries = Object.entries(value).filter(([, v]) => typeof v === "string"); + if (entries.length === 0) { + return undefined; + } + return Object.fromEntries( + entries.map(([key, val]) => [key, resolveEnvVars(String(val))]), + ) as Record; +} + +function pruneUndefined>(value: T): T | undefined { + const entries = Object.entries(value).filter(([, v]) => v !== undefined); + if (entries.length === 0) { + return undefined; + } + return Object.fromEntries(entries) as T; +} + +/** Default user/agent IDs when not configured (single-tenant style). */ +export const DEFAULT_USER_ID = "openclaw-user"; +export const DEFAULT_AGENT_ID = "openclaw-agent"; + +/** Canonical PowerMem `.env` path for consumer (CLI) setups; matches install.sh. */ +export function defaultConsumerPowermemEnvPath(): string { + return join(homedir(), ".openclaw", "powermem", "powermem.env"); +} + +/** + * Default plugin config when openclaw.json has no plugins.entries["memory-powermem"].config. + * Consumer default: CLI, no .env required — SQLite under OpenClaw state dir + LLM from OpenClaw `agents.defaults.model`. + * Optional: set `envFile` to merge a powermem .env under OpenClaw-derived vars. + * Enterprise / shared server: set `mode: "http"` and `baseUrl`. + */ +export const DEFAULT_PLUGIN_CONFIG: PowerMemConfig = { + mode: "cli", + baseUrl: "", + httpApiVersion: "v1", + requestTimeoutMs: 30000, + requestConfig: undefined, + envFile: undefined, + pmemPath: DEFAULT_PMEM_PATH, + useOpenClawModel: true, + walCapture: true, + autoCapture: true, + autoRecall: true, + autoExperience: true, + experienceRecall: true, + inferOnAdd: true, + debugPerfLog: false, + perfSlowMs: 800, + dualWrite: false, + localDbPath: undefined, + localUserId: undefined, + localAgentId: undefined, + syncOnResume: true, + syncBatchSize: 50, + syncMinIntervalMs: 5000, + syncBaseDelayMs: 5000, + syncMaxDelayMs: 60000, + syncMaxRetries: 10, + localVector: undefined, +}; + +export function resolveUserId(cfg: PowerMemConfig): string { + return cfg.userId ?? DEFAULT_USER_ID; +} + +export function resolveAgentId(cfg: PowerMemConfig): string { + return cfg.agentId ?? DEFAULT_AGENT_ID; +} diff --git a/src/dual-write-client.ts b/src/dual-write-client.ts new file mode 100644 index 0000000..6559e15 --- /dev/null +++ b/src/dual-write-client.ts @@ -0,0 +1,325 @@ +import type { PowerMemAddResult, PowerMemSearchResult } from "./client.js"; +import type { LocalEmbeddingFactory } from "./local-embedding.js"; +import { LocalSqliteStore } from "./local-sqlite.js"; + +export type RemoteClient = { + health: () => Promise<{ status: string; error?: string }>; + add: ( + content: string, + options?: { infer?: boolean; metadata?: Record }, + ) => Promise; + search: (query: string, limit?: number) => Promise; + delete: (memoryId: number | string) => Promise; + agentMemoryAdd?: ( + targetAgentId: string, + content: string, + ) => Promise; + agentMemoryList?: ( + targetAgentId: string, + limit?: number, + offset?: number, + ) => Promise>>; + agentMemoryShare?: ( + fromAgentId: string, + targetAgentId: string, + memoryIds?: number[], + ) => Promise<{ shared_count?: number }>; + agentMemoryShared?: ( + targetAgentId: string, + limit?: number, + offset?: number, + ) => Promise>>; +}; + +type Logger = { info?: (msg: string) => void; warn?: (msg: string) => void }; + +export type DualWriteOptions = { + localUserId: string; + localAgentId: string; + syncOnResume: boolean; + syncBatchSize: number; + syncMinIntervalMs: number; + syncBaseDelayMs: number; + syncMaxDelayMs: number; + syncMaxRetries: number; + embedding?: LocalEmbeddingFactory | null; + logger?: Logger; +}; + +export class DualWriteClient { + private remote: RemoteClient; + private local: LocalSqliteStore; + private localUserId: string; + private localAgentId: string; + private syncOnResume: boolean; + private syncBatchSize: number; + private syncMinIntervalMs: number; + private syncBaseDelayMs: number; + private syncMaxDelayMs: number; + private syncMaxRetries: number; + private embedding?: LocalEmbeddingFactory | null; + private logger?: Logger; + private pendingSyncInFlight = false; + private lastSyncAt = 0; + + constructor(remote: RemoteClient, local: LocalSqliteStore, options: DualWriteOptions) { + this.remote = remote; + this.local = local; + this.localUserId = options.localUserId; + this.localAgentId = options.localAgentId; + this.syncOnResume = options.syncOnResume; + this.syncBatchSize = options.syncBatchSize; + this.syncMinIntervalMs = options.syncMinIntervalMs; + this.syncBaseDelayMs = options.syncBaseDelayMs; + this.syncMaxDelayMs = options.syncMaxDelayMs; + this.syncMaxRetries = options.syncMaxRetries; + this.embedding = options.embedding ?? null; + this.logger = options.logger; + } + + private async upsertEmbedding(localId: number, content: string): Promise { + if (!this.embedding) return; + const provider = await this.embedding.get(); + if (!provider) return; + try { + const embedding = await provider.embed(content); + if (embedding.length === 0) return; + this.local.upsertEmbedding(localId, embedding); + } catch (err) { + this.logger?.warn?.(`dual-write: local embedding failed: ${String(err)}`); + } + } + + async health(): Promise<{ status: string; error?: string }> { + return this.remote.health(); + } + + async add( + content: string, + options: { infer?: boolean; metadata?: Record } = {}, + ): Promise { + try { + const created = await this.remote.add(content, options); + if (created.length > 0) { + for (const row of created) { + const remoteId = String(row.memory_id ?? ""); + if (remoteId) { + const localId = this.local.upsertRemoteMemory({ + remoteId, + content: row.content, + metadata: row.metadata ?? options.metadata, + userId: this.localUserId, + agentId: this.localAgentId, + }); + await this.upsertEmbedding(localId, row.content); + } + } + } + void this.syncPending("remote-add-success"); + return created; + } catch (err) { + const localId = this.local.addLocalMemory({ + content, + metadata: options.metadata, + userId: this.localUserId, + agentId: this.localAgentId, + }); + await this.upsertEmbedding(localId, content); + this.local.enqueuePending({ + localMemoryId: localId, + content, + metadata: options.metadata, + userId: this.localUserId, + agentId: this.localAgentId, + infer: options.infer ?? true, + }); + this.logger?.warn?.( + `dual-write: remote add failed, stored locally (id=${localId}): ${String(err)}`, + ); + return [ + { + memory_id: String(localId), + content, + user_id: this.localUserId, + agent_id: this.localAgentId, + metadata: options.metadata, + }, + ]; + } + } + + async search(query: string, limit = 5): Promise { + try { + const results = await this.remote.search(query, limit); + if (results.length > 0) { + for (const row of results) { + const remoteId = String(row.memory_id ?? ""); + if (!remoteId) continue; + const localId = this.local.upsertRemoteMemory({ + remoteId, + content: row.content, + metadata: row.metadata, + userId: this.localUserId, + agentId: this.localAgentId, + }); + // Do not await: local embed can be slow or fail (e.g. fetch to embedding API); + // serial await here blocks before_agent_start / autoRecall for minutes. + void this.upsertEmbedding(localId, row.content); + } + } + void this.syncPending("remote-search-success"); + return results; + } catch (err) { + this.logger?.warn?.(`dual-write: remote search failed, fallback to local: ${String(err)}`); + const provider = await this.embedding?.get(); + if (provider) { + try { + const embedding = await provider.embed(query); + const vectorRows = this.local.searchVector({ + embedding, + limit, + userId: this.localUserId, + agentId: this.localAgentId, + }); + if (vectorRows.length > 0) { + return vectorRows.map((row) => ({ + memory_id: row.remote_id ?? String(row.id), + content: row.content, + score: row.score, + metadata: row.metadata, + })); + } + } catch (embedErr) { + this.logger?.warn?.(`dual-write: local vector search failed: ${String(embedErr)}`); + } + } + const rows = this.local.search({ + query, + limit, + userId: this.localUserId, + agentId: this.localAgentId, + }); + return rows.map((row) => ({ + memory_id: row.remote_id ?? String(row.id), + content: row.content, + score: row.score, + metadata: row.metadata, + })); + } + } + + async delete(memoryId: number | string): Promise { + const id = typeof memoryId === "string" ? memoryId : String(memoryId); + try { + await this.remote.delete(memoryId); + this.local.deleteByRemoteId(id); + return; + } catch (err) { + this.logger?.warn?.(`dual-write: remote delete failed, try local: ${String(err)}`); + const localId = Number(id); + if (Number.isFinite(localId)) { + this.local.deleteByLocalId(localId); + } else { + this.local.deleteByRemoteId(id); + } + } + } + + async agentMemoryAdd( + targetAgentId: string, + content: string, + ): Promise { + if (!this.remote.agentMemoryAdd) { + throw new Error("agent memory APIs require http v2 backend"); + } + return this.remote.agentMemoryAdd(targetAgentId, content); + } + + async agentMemoryList( + targetAgentId: string, + limit = 20, + offset = 0, + ): Promise>> { + if (!this.remote.agentMemoryList) { + throw new Error("agent memory APIs require http v2 backend"); + } + return this.remote.agentMemoryList(targetAgentId, limit, offset); + } + + async agentMemoryShare( + fromAgentId: string, + targetAgentId: string, + memoryIds?: number[], + ): Promise<{ shared_count?: number }> { + if (!this.remote.agentMemoryShare) { + throw new Error("agent memory APIs require http v2 backend"); + } + return this.remote.agentMemoryShare(fromAgentId, targetAgentId, memoryIds); + } + + async agentMemoryShared( + targetAgentId: string, + limit = 20, + offset = 0, + ): Promise>> { + if (!this.remote.agentMemoryShared) { + throw new Error("agent memory APIs require http v2 backend"); + } + return this.remote.agentMemoryShared(targetAgentId, limit, offset); + } + + async syncPending(trigger: string): Promise { + if (!this.syncOnResume) return; + const now = Date.now(); + if (now - this.lastSyncAt < this.syncMinIntervalMs) return; + if (this.pendingSyncInFlight) return; + const pending = this.local.listPending(this.syncBatchSize, true); + if (pending.length === 0) return; + this.lastSyncAt = now; + this.pendingSyncInFlight = true; + this.logger?.info?.(`dual-write: ${trigger}, syncing ${pending.length} pending writes`); + const synced: number[] = []; + try { + for (const row of pending) { + if (this.syncMaxRetries > 0 && row.retries >= this.syncMaxRetries) { + const reason = row.last_error ? `, reason=${row.last_error}` : ""; + this.logger?.warn?.( + `dual-write: skip pending id=${row.id}, retries=${row.retries}${reason}`, + ); + continue; + } + try { + const created = await this.remote.add(row.content, { + infer: row.infer, + metadata: row.metadata, + }); + if (created.length === 1 && row.local_memory_id) { + const remoteId = String(created[0].memory_id ?? ""); + if (remoteId) { + this.local.updateRemoteId(row.local_memory_id, remoteId); + } + } + synced.push(row.id); + } catch (err) { + const delay = Math.min( + this.syncMaxDelayMs, + this.syncBaseDelayMs * Math.pow(2, row.retries), + ); + const nextRetryAt = new Date(Date.now() + delay).toISOString(); + const reasonRaw = err instanceof Error ? err.message : String(err); + const reason = reasonRaw.slice(0, 500); + this.local.scheduleRetries([row.id], nextRetryAt, reason); + this.logger?.warn?.( + `dual-write: pending id=${row.id} retry scheduled at ${nextRetryAt}, reason=${reason}`, + ); + break; + } + } + if (synced.length > 0) { + this.local.removePending(synced); + } + } finally { + this.pendingSyncInFlight = false; + } + } +} diff --git a/src/http.ts b/src/http.ts new file mode 100644 index 0000000..f47c779 --- /dev/null +++ b/src/http.ts @@ -0,0 +1,18 @@ +export async function fetchWithTimeout( + url: string, + options: RequestInit, + timeoutMs?: number, +): Promise { + const timeout = typeof timeoutMs === "number" ? timeoutMs : 0; + if (!timeout || timeout <= 0) { + return fetch(url, options); + } + + const controller = new AbortController(); + const timer = setTimeout(() => controller.abort(), timeout); + try { + return await fetch(url, { ...options, signal: controller.signal }); + } finally { + clearTimeout(timer); + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..a06cd21 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,1878 @@ +/** + * OpenClaw Memory (PowerMem) Plugin + * + * Long-term memory via PowerMem: intelligent extraction, Ebbinghaus + * forgetting curve, multi-agent isolation. Supports two backends: + * - CLI (default): runs pmem locally; SQLite + LLM from OpenClaw state / agents.defaults.model (optional .env). + * - HTTP: powermem-server (e.g. --port 8000) for shared / enterprise setups. + */ + +import { Type } from "@sinclair/typebox"; +import type { + OpenClawPluginApi, + OpenClawPluginCliContext, +} from "openclaw/plugin-sdk/memory-core"; +import type { OpenClawPluginServiceContext } from "openclaw/plugin-sdk"; + +import { + powerMemConfigSchema, + DEFAULT_PLUGIN_CONFIG, + DEFAULT_PMEM_PATH, + type PowerMemConfig, +} from "./config.js"; +import { randomUUID } from "node:crypto"; +import { mkdirSync, readFileSync, writeFileSync } from "node:fs"; +import { homedir } from "node:os"; +import { dirname, join } from "node:path"; + +import { PowerMemClient, type PowerMemSearchResult } from "./client.js"; +import { PowerMemV2Client } from "./client-v2.js"; +import { PowerMemCLIClient } from "./client-cli.js"; +import { DualWriteClient } from "./dual-write-client.js"; +import { createLocalEmbeddingFactory } from "./local-embedding.js"; +import { LocalSqliteStore } from "./local-sqlite.js"; +import { callLlm } from "./llm.js"; +import { WalSession, walCapture as walCaptureCore } from "./wal.js"; +import { + buildDefaultSqlitePowermemEnv, + buildPowermemCliProcessEnv, +} from "./openclaw-powermem-env.js"; +import { resolvePmemExecutable } from "./resolve-powermem-cli.js"; + +type GatewayApi = OpenClawPluginApi & { + config?: unknown; + runtime?: { + state?: { resolveStateDir?: (env?: NodeJS.ProcessEnv) => string }; + modelAuth?: { + resolveApiKeyForProvider?: (params: { + provider: string; + cfg?: unknown; + }) => Promise<{ apiKey?: string }>; + }; + }; +}; + +type Logger = { info?: (msg: string) => void; warn?: (msg: string) => void }; + +function resolveOpenClawStateDir(api: GatewayApi): string { + const fn = api.runtime?.state?.resolveStateDir; + if (typeof fn === "function") { + try { + return fn(process.env); + } catch { + /* ignore */ + } + } + return join(homedir(), ".openclaw"); +} + +function normalizeId(value: unknown): string | undefined { + if (typeof value !== "string") return undefined; + const trimmed = value.trim(); + if (!trimmed) return undefined; + if (trimmed.toLowerCase() === "auto") return undefined; + return trimmed; +} + +function resolveIdentityIds( + cfg: PowerMemConfig, + stateDir: string, + logger: Logger, +): { userId: string; agentId: string } { + const baseDir = join(stateDir, "powermem"); + const identityPath = join(baseDir, "identity.json"); + let stored: { userId?: string; agentId?: string } = {}; + try { + const raw = readFileSync(identityPath, "utf-8"); + const parsed = JSON.parse(raw); + if (parsed && typeof parsed === "object") { + stored = parsed as { userId?: string; agentId?: string }; + } + } catch { + // ignore missing or invalid file + } + + const userId = normalizeId(cfg.userId) ?? normalizeId(stored.userId) ?? `user-${randomUUID()}`; + const agentId = + normalizeId(cfg.agentId) ?? normalizeId(stored.agentId) ?? `agent-${randomUUID()}`; + + if (userId !== stored.userId || agentId !== stored.agentId) { + try { + mkdirSync(baseDir, { recursive: true }); + writeFileSync(identityPath, JSON.stringify({ userId, agentId }, null, 2), "utf-8"); + } catch (err) { + logger.warn?.(`memory-powermem: failed to persist identity: ${String(err)}`); + } + } + + return { userId, agentId }; +} + +type AgentIdentity = { userId: string; agentId: string }; + +function loadAgentIdentityMap( + identityPath: string, + logger: Logger, +): Map { + const map = new Map(); + try { + const raw = readFileSync(identityPath, "utf-8"); + const parsed = JSON.parse(raw) as Record; + if (parsed && typeof parsed === "object") { + for (const [agentId, identity] of Object.entries(parsed)) { + if ( + identity && + typeof identity === "object" && + typeof identity.userId === "string" && + typeof identity.agentId === "string" + ) { + map.set(agentId, { userId: identity.userId, agentId: identity.agentId }); + } + } + } + } catch (err) { + if (String(err).includes("ENOENT")) { + return map; + } + logger.warn?.(`memory-powermem: failed to load agent identity map: ${String(err)}`); + } + return map; +} + +function saveAgentIdentityMap( + identityPath: string, + map: Map, + logger: Logger, +): void { + try { + const dir = dirname(identityPath); + mkdirSync(dir, { recursive: true }); + const payload: Record = {}; + for (const [agentId, identity] of map.entries()) { + payload[agentId] = identity; + } + writeFileSync(identityPath, JSON.stringify(payload, null, 2), "utf-8"); + } catch (err) { + logger.warn?.(`memory-powermem: failed to save agent identity map: ${String(err)}`); + } +} + +type MemoryClient = { + health: () => Promise<{ status: string; error?: string }>; + add: ( + content: string, + options?: { infer?: boolean; metadata?: Record }, + ) => Promise }>>; + search: (query: string, limit?: number) => Promise; + delete: (memoryId: number | string) => Promise; +}; + +type AgentMemoryClient = { + agentMemoryAdd?: ( + targetAgentId: string, + content: string, + ) => Promise<{ memory_id: string | number; content: string } | null>; + agentMemoryList?: ( + targetAgentId: string, + limit?: number, + offset?: number, + ) => Promise>>; + agentMemoryShare?: ( + fromAgentId: string, + targetAgentId: string, + memoryIds?: number[], + ) => Promise<{ shared_count?: number }>; + agentMemoryShared?: ( + targetAgentId: string, + limit?: number, + offset?: number, + ) => Promise>>; +}; + +type CrossScopeIdentity = { + userId: string; + agentId: string; +}; + +type ToolContext = { agentId?: string } | undefined; + +function resolveLocalDbPath(cfg: PowerMemConfig, stateDir: string): string { + if (cfg.localDbPath && cfg.localDbPath.trim()) return cfg.localDbPath.trim(); + return join(stateDir, "powermem", "local-memories.sqlite"); +} + +// ============================================================================ +// Plugin Definition +// ============================================================================ + +const memoryPlugin = { + id: "memory-powermem", + name: "Memory (PowerMem)", + description: + "PowerMem-backed long-term memory (intelligent extraction, forgetting curve). Default: local CLI (npm powermem / TS, or pmem on PATH); optional HTTP server for shared deployments.", + kind: "memory" as const, + configSchema: powerMemConfigSchema, + + register(api: OpenClawPluginApi) { + const gw = api as GatewayApi; + const raw = api.pluginConfig; + const toParse = + raw && + typeof raw === "object" && + !Array.isArray(raw) && + Object.keys(raw).length > 0 + ? { ...DEFAULT_PLUGIN_CONFIG, ...raw } + : DEFAULT_PLUGIN_CONFIG; + const cfg = powerMemConfigSchema.parse(toParse) as PowerMemConfig; + const perfEnabled = cfg.debugPerfLog === true; + const perfSlowMs = Math.max(1, cfg.perfSlowMs ?? 800); + const perfNow = () => Date.now(); + const perfLog = (stage: string, startAt: number, extra?: Record) => { + if (!perfEnabled) return; + const elapsedMs = perfNow() - startAt; + if (elapsedMs < perfSlowMs) return; + const detail = + extra && Object.keys(extra).length > 0 ? ` ${JSON.stringify(extra)}` : ""; + api.logger.info(`memory-powermem: perf ${stage} ${elapsedMs}ms${detail}`); + }; + const stateDir = resolveOpenClawStateDir(gw); + const { userId, agentId } = resolveIdentityIds(cfg, stateDir, api.logger); + const buildProcessEnv = + cfg.mode === "cli" + ? cfg.useOpenClawModel !== false + ? () => + buildPowermemCliProcessEnv({ + openclawConfig: gw.config, + stateDir, + resolveProviderAuth: async (provider) => { + const fn = gw.runtime?.modelAuth?.resolveApiKeyForProvider; + if (typeof fn !== "function") return {}; + try { + return await fn({ provider, cfg: gw.config }); + } catch { + return {}; + } + }, + warn: (m) => api.logger.warn(m), + }) + : () => Promise.resolve(buildDefaultSqlitePowermemEnv(stateDir)) + : undefined; + + const defaultIdentity: AgentIdentity = { userId, agentId }; + const agentIdentityPath = join(stateDir, "powermem", "agent-identities.json"); + const agentIdentityMap = loadAgentIdentityMap(agentIdentityPath, api.logger); + let defaultIdentityBound = agentIdentityMap.size > 0; + + const resolveAgentIdentity = (ctxAgentId?: string): AgentIdentity => { + if (!ctxAgentId) return defaultIdentity; + const cached = agentIdentityMap.get(ctxAgentId); + if (cached) return cached; + const identity = defaultIdentityBound + ? { userId: `user-${randomUUID()}`, agentId: `agent-${randomUUID()}` } + : defaultIdentity; + defaultIdentityBound = true; + agentIdentityMap.set(ctxAgentId, identity); + saveAgentIdentityMap(agentIdentityPath, agentIdentityMap, api.logger); + return identity; + }; + + const resolveLocalIdentity = (identity: AgentIdentity): AgentIdentity => ({ + userId: cfg.localUserId ?? identity.userId, + agentId: cfg.localAgentId ?? identity.agentId, + }); + + const localStore = cfg.dualWrite + ? new LocalSqliteStore(resolveLocalDbPath(cfg, stateDir), { + logger: api.logger, + vector: { + enabled: cfg.localVector?.enabled ?? (cfg.dualWrite === true), + extensionPath: cfg.localVector?.extensionPath, + }, + }) + : null; + + const embeddingFactoryCache = new Map | null>(); + const getLocalEmbeddingFactory = (ctxAgentId?: string) => { + if (!cfg.dualWrite) return null; + const key = ctxAgentId ?? "__default__"; + if (embeddingFactoryCache.has(key)) { + return embeddingFactoryCache.get(key) ?? null; + } + const localEmbedding = createLocalEmbeddingFactory({ + api: gw, + cfg, + agentId: ctxAgentId ?? agentId, + logger: api.logger, + }); + embeddingFactoryCache.set(key, localEmbedding); + return localEmbedding; + }; + + const clientCache = new Map(); + const walSession = new WalSession(); + let inFlightAutoCapture = 0; + let inFlightAutoExperience = 0; + + const buildHttpClient = (identity: AgentIdentity) => + cfg.httpApiVersion === "v2" + ? PowerMemV2Client.fromConfig(cfg, identity.userId, identity.agentId) + : PowerMemClient.fromConfig(cfg, identity.userId, identity.agentId); + + const createClientForIdentity = (identity: AgentIdentity, ctxAgentId?: string) => { + if (cfg.mode === "cli") { + return PowerMemCLIClient.fromConfig(cfg, identity.userId, identity.agentId, { + buildProcessEnv, + }) as MemoryClient; + } + + const httpClient = buildHttpClient(identity); + if (cfg.dualWrite && localStore) { + const localIdentity = resolveLocalIdentity(identity); + const localEmbedding = getLocalEmbeddingFactory(ctxAgentId); + return new DualWriteClient(httpClient, localStore, { + localUserId: localIdentity.userId, + localAgentId: localIdentity.agentId, + syncOnResume: cfg.syncOnResume !== false, + syncBatchSize: cfg.syncBatchSize ?? 50, + syncMinIntervalMs: cfg.syncMinIntervalMs ?? 5000, + syncBaseDelayMs: cfg.syncBaseDelayMs ?? 5000, + syncMaxDelayMs: cfg.syncMaxDelayMs ?? 60000, + syncMaxRetries: cfg.syncMaxRetries ?? 10, + embedding: localEmbedding, + logger: api.logger, + }) as MemoryClient & AgentMemoryClient; + } + + return httpClient as MemoryClient & AgentMemoryClient; + }; + + const getClientForAgent = (ctxAgentId?: string) => { + const key = ctxAgentId ?? "__default__"; + const cached = clientCache.get(key); + if (cached) return cached; + const identity = resolveAgentIdentity(ctxAgentId); + const created = createClientForIdentity(identity, ctxAgentId); + clientCache.set(key, created); + return created; + }; + + function dedupeSearchResults(items: PowerMemSearchResult[]): PowerMemSearchResult[] { + const deduped = new Map(); + for (const item of items) { + const keyBase = + item.memory_id !== undefined && item.memory_id !== null + ? String(item.memory_id) + : item.content; + const key = keyBase.trim() ? keyBase : item.content; + const existing = deduped.get(key); + if (!existing || (existing.score ?? 0) < (item.score ?? 0)) { + deduped.set(key, item); + } + } + return Array.from(deduped.values()).sort((a, b) => (b.score ?? 0) - (a.score ?? 0)); + } + + async function mergeSearchWithSharedInbox( + agentClient: MemoryClient & AgentMemoryClient, + ctxAgentId: string | undefined, + query: string, + primary: PowerMemSearchResult[], + requestLimit: number, + perfStagePrefix: string, + ): Promise<{ merged: PowerMemSearchResult[]; sharedFetched: number }> { + let merged: PowerMemSearchResult[] = [...primary]; + let sharedFetched = 0; + + if (agentClient.agentMemoryShared) { + const targetAgentId = resolveAgentIdentity(ctxAgentId).agentId; + try { + const sharedStartedAt = perfNow(); + const sharedRows = await agentClient.agentMemoryShared(targetAgentId, requestLimit, 0); + perfLog(`${perfStagePrefix}.shared_fetch`, sharedStartedAt, { + agent: targetAgentId, + requestLimit, + sharedRowCount: sharedRows.length, + }); + const normalizedQuery = query.trim().toLowerCase(); + const sharedAsSearch: PowerMemSearchResult[] = []; + for (let idx = 0; idx < sharedRows.length; idx++) { + const record = sharedRows[idx] as Record; + const rawText = record.content ?? record.memory; + const content = + typeof rawText === "string" ? rawText.trim() : String(rawText ?? "").trim(); + if (!content) continue; + const rawMetadata = record.metadata; + const metadata = + rawMetadata && typeof rawMetadata === "object" && !Array.isArray(rawMetadata) + ? ({ ...(rawMetadata as Record) } as Record) + : {}; + metadata.shared = true; + metadata.source = "shared"; + const id = record.memory_id ?? record.id ?? `shared-${idx}`; + const hasQueryHit = + normalizedQuery.length > 0 && content.toLowerCase().includes(normalizedQuery); + const score = hasQueryHit ? 0.92 : 0.55; + sharedAsSearch.push({ + memory_id: String(id), + content, + score, + metadata, + }); + } + sharedFetched = sharedAsSearch.length; + merged = merged.concat(sharedAsSearch); + } catch (err) { + api.logger.warn(`memory-powermem: shared recall fallback failed: ${String(err)}`); + } + } + + return { merged: dedupeSearchResults(merged), sharedFetched }; + } + + const client = getClientForAgent(); + if (cfg.dualWrite && "syncPending" in client) { + void (client as DualWriteClient).syncPending("startup"); + } + const resolvedPmem = + cfg.mode === "cli" ? resolvePmemExecutable(cfg.pmemPath ?? DEFAULT_PMEM_PATH) : ""; + const modeLabel = + cfg.mode === "cli" + ? `cli (${resolvedPmem})` + : `${cfg.baseUrl}${cfg.httpApiVersion === "v2" ? " (v2)" : ""}${cfg.dualWrite ? " + sqlite" : ""}`; + + api.logger.info( + `memory-powermem: plugin registered (mode: ${cfg.mode}, ${modeLabel}, user: ${userId}, agent: ${agentId})`, + ); + if (perfEnabled) { + api.logger.info(`memory-powermem: perf logging enabled (slow >= ${perfSlowMs}ms)`); + } + + // ======================================================================== + // Tools + // ======================================================================== + + api.registerTool( + (ctx: ToolContext) => ({ + name: "memory_recall", + label: "Memory Recall", + description: + "Search through long-term memories. Use when you need context about user preferences, past decisions, or previously discussed topics.", + parameters: Type.Object({ + query: Type.String({ description: "Search query" }), + limit: Type.Optional( + Type.Number({ description: "Max results (default: plugin recallLimit)" }), + ), + scoreThreshold: Type.Optional( + Type.Number({ description: "Min score 0–1 to include (default: plugin recallScoreThreshold)" }), + ), + }), + async execute(_toolCallId: string, params: Record) { + const recallStartedAt = perfNow(); + const agentClient = getClientForAgent(ctx?.agentId) as MemoryClient & AgentMemoryClient; + const limit = + typeof (params as { limit?: number }).limit === "number" + ? Math.max(1, Math.min(100, Math.floor((params as { limit: number }).limit))) + : cfg.recallLimit ?? 5; + const scoreThreshold = + typeof (params as { scoreThreshold?: number }).scoreThreshold === "number" + ? Math.max(0, Math.min(1, (params as { scoreThreshold: number }).scoreThreshold)) + : (cfg.recallScoreThreshold ?? 0); + const query = String((params as { query?: string }).query ?? ""); + + try { + const requestLimit = Math.min(100, Math.max(limit * 2, limit + 10)); + const primaryStartedAt = perfNow(); + const primary = await agentClient.search(query, requestLimit); + perfLog("memory_recall.search", primaryStartedAt, { + agent: resolveAgentIdentity(ctx?.agentId).agentId, + queryLen: query.length, + requestLimit, + resultCount: primary.length, + }); + const { merged, sharedFetched } = await mergeSearchWithSharedInbox( + agentClient, + ctx?.agentId, + query, + primary, + requestLimit, + "memory_recall", + ); + + const results = merged + .filter((r) => (r.score ?? 0) >= scoreThreshold) + .slice(0, limit); + perfLog("memory_recall.total", recallStartedAt, { + queryLen: query.length, + limit, + primaryCount: primary.length, + sharedCount: sharedFetched, + finalCount: results.length, + }); + + if (results.length === 0) { + return { + content: [{ type: "text", text: "No relevant memories found." }], + details: { count: 0, primaryCount: primary.length, sharedCount: sharedFetched }, + }; + } + + const text = results + .map( + (r, i) => { + const source = + r.metadata && typeof r.metadata === "object" && (r.metadata as Record).shared + ? "shared" + : "owned"; + return `${i + 1}. [${source}] ${r.content} (${((r.score ?? 0) * 100).toFixed(0)}%)`; + }, + ) + .join("\n"); + + const sanitizedResults = results.map((r) => ({ + id: String(r.memory_id), + text: r.content, + score: r.score, + source: + r.metadata && typeof r.metadata === "object" && (r.metadata as Record).shared + ? "shared" + : "owned", + })); + + return { + content: [ + { type: "text", text: `Found ${results.length} memories:\n\n${text}` }, + ], + details: { + count: results.length, + primaryCount: primary.length, + sharedCount: sharedFetched, + memories: sanitizedResults, + }, + }; + } catch (err) { + api.logger.warn(`memory-powermem: recall failed: ${String(err)}`); + return { + content: [ + { + type: "text", + text: `Memory search failed: ${err instanceof Error ? err.message : String(err)}`, + }, + ], + details: { error: String(err) }, + }; + } + }, + }), + { name: "memory_recall" }, + ); + + api.registerTool( + (ctx: ToolContext) => ({ + name: "memory_store", + label: "Memory Store", + description: + "Save important information in long-term memory. Use for preferences, facts, decisions.", + parameters: Type.Object({ + text: Type.String({ description: "Information to remember" }), + importance: Type.Optional( + Type.Number({ description: "Importance 0-1 (default: 0.7)" }), + ), + }), + async execute(_toolCallId: string, params: Record) { + const storeStartedAt = perfNow(); + const agentClient = getClientForAgent(ctx?.agentId); + const { text, importance = 0.7 } = params as { + text: string; + importance?: number; + }; + + try { + const addStartedAt = perfNow(); + const created = await agentClient.add(text, { + infer: cfg.inferOnAdd, + metadata: { importance }, + }); + perfLog("memory_store.add", addStartedAt, { + agent: resolveAgentIdentity(ctx?.agentId).agentId, + textLen: text.length, + infer: cfg.inferOnAdd, + createdCount: created.length, + }); + + if (created.length === 0) { + return { + content: [{ type: "text", text: "Stored (no inferred items)." }], + details: { action: "created" }, + }; + } + + const summary = + created.length === 1 + ? created[0].content.slice(0, 80) + : `${created.length} items stored`; + return { + content: [ + { type: "text", text: `Stored: ${summary}${summary.length >= 80 ? "..." : ""}` }, + ], + details: { + action: "created", + count: created.length, + ids: created.map((c) => String(c.memory_id)), + }, + }; + } catch (err) { + api.logger.warn(`memory-powermem: store failed: ${String(err)}`); + return { + content: [ + { + type: "text", + text: `Failed to store memory: ${err instanceof Error ? err.message : String(err)}`, + }, + ], + details: { error: String(err) }, + }; + } finally { + perfLog("memory_store.total", storeStartedAt, { + agent: resolveAgentIdentity(ctx?.agentId).agentId, + textLen: text.length, + }); + } + }, + }), + { name: "memory_store" }, + ); + + api.registerTool( + (ctx: ToolContext) => ({ + name: "memory_forget", + label: "Memory Forget", + description: "Delete specific memories. GDPR-compliant.", + parameters: Type.Object({ + query: Type.Optional(Type.String({ description: "Search to find memory" })), + memoryId: Type.Optional(Type.String({ description: "Specific memory ID" })), + }), + async execute(_toolCallId: string, params: Record) { + const forgetStartedAt = perfNow(); + const agentClient = getClientForAgent(ctx?.agentId); + const { query, memoryId } = params as { query?: string; memoryId?: string }; + + try { + if (memoryId) { + const deleteStartedAt = perfNow(); + await agentClient.delete(memoryId); + perfLog("memory_forget.delete_by_id", deleteStartedAt, { + agent: resolveAgentIdentity(ctx?.agentId).agentId, + memoryId, + }); + return { + content: [{ type: "text", text: `Memory ${memoryId} forgotten.` }], + details: { action: "deleted", id: memoryId }, + }; + } + + if (query) { + const searchStartedAt = perfNow(); + const results = await agentClient.search(query, 5); + perfLog("memory_forget.search", searchStartedAt, { + agent: resolveAgentIdentity(ctx?.agentId).agentId, + queryLen: query.length, + candidateCount: results.length, + }); + if (results.length === 0) { + return { + content: [{ type: "text", text: "No matching memories found." }], + details: { found: 0 }, + }; + } + if (results.length === 1 && (results[0].score ?? 0) > 0.9) { + const deleteTopStartedAt = perfNow(); + await agentClient.delete(results[0].memory_id); + perfLog("memory_forget.delete_top_hit", deleteTopStartedAt, { + agent: resolveAgentIdentity(ctx?.agentId).agentId, + memoryId: String(results[0].memory_id), + score: results[0].score, + }); + return { + content: [ + { + type: "text", + text: `Forgotten: "${results[0].content.slice(0, 60)}..."`, + }, + ], + details: { action: "deleted", id: String(results[0].memory_id) }, + }; + } + const list = results + .map( + (r) => + `- [${String(r.memory_id).slice(0, 8)}] ${r.content.slice(0, 60)}...`, + ) + .join("\n"); + return { + content: [ + { + type: "text", + text: `Found ${results.length} candidates. Specify memoryId:\n${list}`, + }, + ], + details: { + action: "candidates", + candidates: results.map((r) => ({ + id: String(r.memory_id), + text: r.content, + score: r.score, + })), + }, + }; + } + + return { + content: [{ type: "text", text: "Provide query or memoryId." }], + details: { error: "missing_param" }, + }; + } catch (err) { + api.logger.warn(`memory-powermem: forget failed: ${String(err)}`); + return { + content: [ + { + type: "text", + text: `Failed to forget: ${err instanceof Error ? err.message : String(err)}`, + }, + ], + details: { error: String(err) }, + }; + } finally { + perfLog("memory_forget.total", forgetStartedAt, { + agent: resolveAgentIdentity(ctx?.agentId).agentId, + hasQuery: Boolean(query), + hasMemoryId: Boolean(memoryId), + }); + } + }, + }), + { name: "memory_forget" }, + ); + + api.registerTool( + (ctx: ToolContext) => ({ + name: "experience_store", + label: "Experience Store", + description: "Store a procedural experience or lesson learned.", + parameters: Type.Object({ + text: Type.String({ description: "Experience content" }), + importance: Type.Optional( + Type.Number({ description: "Importance 0-1 (default: 0.7)" }), + ), + tags: Type.Optional(Type.Array(Type.String(), { description: "Optional tags" })), + }), + async execute(_toolCallId: string, params: Record) { + const expStoreStartedAt = perfNow(); + const agentClient = getClientForAgent(ctx?.agentId); + const { text, importance = 0.7, tags } = params as { + text: string; + importance?: number; + tags?: string[]; + }; + try { + const addStartedAt = perfNow(); + const created = await agentClient.add(text, { + infer: false, + metadata: { type: "experience", importance, tags }, + }); + perfLog("experience_store.add", addStartedAt, { + agent: resolveAgentIdentity(ctx?.agentId).agentId, + textLen: text.length, + createdCount: created.length, + }); + const id = created[0]?.memory_id ? String(created[0].memory_id) : "unknown"; + return { + content: [{ type: "text", text: `Experience stored (id: ${id}).` }], + details: { action: "created", id }, + }; + } catch (err) { + api.logger.warn(`memory-powermem: experience_store failed: ${String(err)}`); + return { + content: [ + { + type: "text", + text: `Failed to store experience: ${err instanceof Error ? err.message : String(err)}`, + }, + ], + details: { error: String(err) }, + }; + } finally { + perfLog("experience_store.total", expStoreStartedAt, { + agent: resolveAgentIdentity(ctx?.agentId).agentId, + textLen: text.length, + }); + } + }, + }), + { name: "experience_store" }, + ); + + api.registerTool( + (ctx: ToolContext) => ({ + name: "experience_recall", + label: "Experience Recall", + description: "Search stored experiences for procedural guidance.", + parameters: Type.Object({ + query: Type.String({ description: "Search query" }), + limit: Type.Optional( + Type.Number({ description: "Max results (default: plugin recallLimit)" }), + ), + scoreThreshold: Type.Optional( + Type.Number({ description: "Min score 0–1 to include (default: plugin recallScoreThreshold)" }), + ), + }), + async execute(_toolCallId: string, params: Record) { + const agentClient = getClientForAgent(ctx?.agentId); + const limit = + typeof (params as { limit?: number }).limit === "number" + ? Math.max(1, Math.min(100, Math.floor((params as { limit: number }).limit))) + : cfg.recallLimit ?? 5; + const scoreThreshold = + typeof (params as { scoreThreshold?: number }).scoreThreshold === "number" + ? Math.max(0, Math.min(1, (params as { scoreThreshold: number }).scoreThreshold)) + : (cfg.recallScoreThreshold ?? 0); + const query = String((params as { query?: string }).query ?? ""); + + try { + const requestLimit = Math.min(100, Math.max(limit * 2, limit + 10)); + const raw = await agentClient.search(query, requestLimit); + const { experiences } = splitExperiences(raw); + const results = experiences + .filter((r) => (r.score ?? 0) >= scoreThreshold) + .slice(0, limit); + + if (results.length === 0) { + return { + content: [{ type: "text", text: "No relevant experiences found." }], + details: { count: 0 }, + }; + } + + const text = results + .map( + (r, i) => + `${i + 1}. ${r.content} (${((r.score ?? 0) * 100).toFixed(0)}%)`, + ) + .join("\n"); + + return { + content: [ + { type: "text", text: `Found ${results.length} experiences:\n\n${text}` }, + ], + details: { count: results.length }, + }; + } catch (err) { + api.logger.warn(`memory-powermem: experience_recall failed: ${String(err)}`); + return { + content: [ + { + type: "text", + text: `Experience search failed: ${err instanceof Error ? err.message : String(err)}`, + }, + ], + details: { error: String(err) }, + }; + } + }, + }), + { name: "experience_recall" }, + ); + + if (cfg.httpApiVersion === "v2") { + const createScopedV2Client = (identity: CrossScopeIdentity) => + new PowerMemV2Client({ + baseUrl: cfg.baseUrl, + apiKey: cfg.apiKey, + userId: identity.userId, + agentId: identity.agentId, + requestConfig: cfg.requestConfig, + timeoutMs: cfg.requestTimeoutMs, + }); + + api.registerTool( + (ctx: ToolContext) => ({ + name: "agent_memory_add", + label: "Agent Memory Add", + description: "Add memory to a target agent's memory pool (v2 only).", + parameters: Type.Object({ + agentId: Type.String({ description: "Target agent ID" }), + text: Type.String({ description: "Memory content" }), + }), + async execute(_toolCallId: string, params: Record) { + const agentClient = getClientForAgent(ctx?.agentId) as AgentMemoryClient; + if (!agentClient.agentMemoryAdd) { + return { + content: [{ type: "text", text: "Agent memory add not available in this mode." }], + details: { error: "unsupported" }, + }; + } + const { agentId, text } = params as { agentId: string; text: string }; + try { + const record = await agentClient.agentMemoryAdd(agentId, text); + const id = record?.memory_id ? String(record.memory_id) : "unknown"; + return { + content: [{ type: "text", text: `Agent memory stored (id: ${id}).` }], + details: { action: "created", id }, + }; + } catch (err) { + api.logger.warn(`memory-powermem: agent_memory_add failed: ${String(err)}`); + return { + content: [ + { + type: "text", + text: `Failed to add agent memory: ${err instanceof Error ? err.message : String(err)}`, + }, + ], + details: { error: String(err) }, + }; + } + }, + }), + { name: "agent_memory_add" }, + ); + + api.registerTool( + (ctx: ToolContext) => ({ + name: "agent_memory_share", + label: "Agent Memory Share", + description: + "Share memories from one agent to another (v2 only). Omitting memoryIds shares ALL memories for the source agent (can be slow); pass memoryIds to share only specific rows and avoid timeouts.", + parameters: Type.Object({ + fromAgentId: Type.Optional(Type.String({ description: "Source agent ID (default: current)" })), + targetAgentId: Type.String({ description: "Target agent ID" }), + memoryIds: Type.Optional( + Type.Array(Type.Number(), { + description: + "Numeric memory IDs to share. Strongly recommended when sharing one or a few memories; omit only for full export (may take minutes).", + }), + ), + }), + async execute(_toolCallId: string, params: Record) { + const agentClient = getClientForAgent(ctx?.agentId) as AgentMemoryClient; + if (!agentClient.agentMemoryShare) { + return { + content: [{ type: "text", text: "Agent memory share not available in this mode." }], + details: { error: "unsupported" }, + }; + } + const { fromAgentId, targetAgentId, memoryIds } = params as { + fromAgentId?: string; + targetAgentId: string; + memoryIds?: number[]; + }; + const currentSource = resolveAgentIdentity(ctx?.agentId).agentId; + if (fromAgentId && fromAgentId !== currentSource) { + return { + content: [ + { + type: "text", + text: + "fromAgentId does not match the current agent identity. " + + "Leave fromAgentId empty to use current agent automatically.", + }, + ], + details: { + error: "from_agent_mismatch", + currentAgentId: currentSource, + }, + }; + } + const source = fromAgentId ?? currentSource; + try { + const result = await agentClient.agentMemoryShare(source, targetAgentId, memoryIds); + const shared = result?.shared_count ?? 0; + return { + content: [ + { type: "text", text: `Shared ${shared} memories to agent ${targetAgentId}.` }, + ], + details: { shared }, + }; + } catch (err) { + api.logger.warn(`memory-powermem: agent_memory_share failed: ${String(err)}`); + return { + content: [ + { + type: "text", + text: `Failed to share agent memories: ${err instanceof Error ? err.message : String(err)}`, + }, + ], + details: { error: String(err) }, + }; + } + }, + }), + { name: "agent_memory_share" }, + ); + + api.registerTool( + (_ctx: ToolContext) => ({ + name: "cross_scope_share", + label: "Cross Scope Share", + description: + "Share memories across arbitrary userId/agentId scopes by copying matched memories.", + parameters: Type.Object({ + fromUserId: Type.String({ description: "Source user ID" }), + fromAgentId: Type.String({ description: "Source agent ID" }), + toUserId: Type.String({ description: "Target user ID" }), + toAgentId: Type.String({ description: "Target agent ID" }), + query: Type.String({ description: "Search query in source scope" }), + limit: Type.Optional( + Type.Number({ description: "Max memories to copy (default: 20, range: 1-100)" }), + ), + scoreThreshold: Type.Optional( + Type.Number({ description: "Min score 0-1 to include (default: plugin recallScoreThreshold)" }), + ), + inferOnTarget: Type.Optional( + Type.Boolean({ description: "Whether target writes should infer memory extraction (default: false)" }), + ), + }), + async execute(_toolCallId: string, params: Record) { + const { + fromUserId, + fromAgentId, + toUserId, + toAgentId, + query, + limit = 20, + scoreThreshold, + inferOnTarget = false, + } = params as { + fromUserId: string; + fromAgentId: string; + toUserId: string; + toAgentId: string; + query: string; + limit?: number; + scoreThreshold?: number; + inferOnTarget?: boolean; + }; + + const srcUser = fromUserId?.trim(); + const srcAgent = fromAgentId?.trim(); + const dstUser = toUserId?.trim(); + const dstAgent = toAgentId?.trim(); + const q = query?.trim(); + if (!srcUser || !srcAgent || !dstUser || !dstAgent) { + return { + content: [{ type: "text", text: "fromUserId/fromAgentId/toUserId/toAgentId are required." }], + details: { error: "missing_identity" }, + }; + } + if (!q) { + return { + content: [{ type: "text", text: "query is required for cross_scope_share." }], + details: { error: "missing_query" }, + }; + } + + const boundedLimit = Math.max(1, Math.min(100, Math.floor(limit))); + const threshold = + typeof scoreThreshold === "number" + ? Math.max(0, Math.min(1, scoreThreshold)) + : (cfg.recallScoreThreshold ?? 0); + + const sourceIdentity: CrossScopeIdentity = { userId: srcUser, agentId: srcAgent }; + const targetIdentity: CrossScopeIdentity = { userId: dstUser, agentId: dstAgent }; + const sourceClient = createScopedV2Client(sourceIdentity); + const targetClient = createScopedV2Client(targetIdentity); + + try { + const requestLimit = Math.min(100, Math.max(boundedLimit * 2, boundedLimit + 10)); + const sourceRows = await sourceClient.search(q, requestLimit); + const selected = sourceRows + .filter((row) => (row.score ?? 0) >= threshold) + .slice(0, boundedLimit); + + if (selected.length === 0) { + return { + content: [{ type: "text", text: "No source memories matched for cross-scope sharing." }], + details: { copied: 0, scanned: sourceRows.length }, + }; + } + + let copied = 0; + const copiedIds: string[] = []; + const sharedAt = new Date().toISOString(); + for (const row of selected) { + const metadata = { + ...(row.metadata ?? {}), + shared_via: "cross_scope_share", + shared_at: sharedAt, + shared_from_user_id: sourceIdentity.userId, + shared_from_agent_id: sourceIdentity.agentId, + shared_from_memory_id: String(row.memory_id), + }; + const created = await targetClient.add(row.content, { + infer: inferOnTarget, + metadata, + }); + copied += created.length; + for (const item of created) { + copiedIds.push(String(item.memory_id)); + } + } + + return { + content: [ + { + type: "text", + text: + `Cross-scope share completed: copied ${copied} memories ` + + `from ${sourceIdentity.userId}/${sourceIdentity.agentId} ` + + `to ${targetIdentity.userId}/${targetIdentity.agentId}.`, + }, + ], + details: { + copied, + requestedLimit: boundedLimit, + selected: selected.length, + source: sourceIdentity, + target: targetIdentity, + copiedIds, + }, + }; + } catch (err) { + api.logger.warn(`memory-powermem: cross_scope_share failed: ${String(err)}`); + return { + content: [ + { + type: "text", + text: `Failed to share across scopes: ${err instanceof Error ? err.message : String(err)}`, + }, + ], + details: { error: String(err) }, + }; + } + }, + }), + { name: "cross_scope_share" }, + ); + + api.registerTool( + (ctx: ToolContext) => ({ + name: "agent_memory_list", + label: "Agent Memory List", + description: + "List memories **owned by** an agent (v2 only). Omit agentId to list **this bot's** own memories.", + parameters: Type.Object({ + agentId: Type.Optional( + Type.String({ + description: + "Which agent's vault to list (PowerMem agentId). Omit = current OpenClaw agent.", + }), + ), + limit: Type.Optional(Type.Number({ description: "Max results (default: 20)" })), + offset: Type.Optional(Type.Number({ description: "Offset (default: 0)" })), + }), + async execute(_toolCallId: string, params: Record) { + const agentClient = getClientForAgent(ctx?.agentId) as AgentMemoryClient; + if (!agentClient.agentMemoryList) { + return { + content: [{ type: "text", text: "Agent memory list not available in this mode." }], + details: { error: "unsupported" }, + }; + } + const currentAgentId = resolveAgentIdentity(ctx?.agentId).agentId; + const requested = (params as { agentId?: string }).agentId?.trim(); + const targetAgentId = + requested && requested.length > 0 ? requested : currentAgentId; + const { limit = 20, offset = 0 } = params as { + limit?: number; + offset?: number; + }; + if (!targetAgentId) { + return { + content: [ + { + type: "text", + text: "Cannot list agent memories: no agentId (configure memory-powermem agentId or pass agentId).", + }, + ], + details: { error: "missing_agent_id" }, + }; + } + try { + const rows = await agentClient.agentMemoryList(targetAgentId, limit, offset); + const list = rows ?? []; + const text = list + .map( + (row, idx) => + `${idx + 1}. ${String((row.content ?? row.memory) as string).slice(0, 80)}`, + ) + .join("\n"); + return { + content: [ + { type: "text", text: list.length ? text : "No agent memories found." }, + ], + details: { count: list.length }, + }; + } catch (err) { + api.logger.warn(`memory-powermem: agent_memory_list failed: ${String(err)}`); + return { + content: [ + { + type: "text", + text: `Failed to list agent memories: ${err instanceof Error ? err.message : String(err)}`, + }, + ], + details: { error: String(err) }, + }; + } + }, + }), + { name: "agent_memory_list" }, + ); + + api.registerTool( + (ctx: ToolContext) => ({ + name: "agent_memory_shared", + label: "Agent Memory Shared", + description: + "List memories **shared to** an agent (inbound, v2 only). Pass the **receiver** agent id — usually **this bot's** PowerMem agentId. You can omit agentId to use the current OpenClaw agent automatically (not userId).", + parameters: Type.Object({ + agentId: Type.Optional( + Type.String({ + description: + "Receiver agent id (PowerMem agentId of **this** bot). Omit = current session agent.", + }), + ), + limit: Type.Optional(Type.Number({ description: "Max results (default: 20)" })), + offset: Type.Optional(Type.Number({ description: "Offset (default: 0)" })), + }), + async execute(_toolCallId: string, params: Record) { + const agentClient = getClientForAgent(ctx?.agentId) as AgentMemoryClient; + if (!agentClient.agentMemoryShared) { + return { + content: [{ type: "text", text: "Agent memory shared not available in this mode." }], + details: { error: "unsupported" }, + }; + } + const currentAgentId = resolveAgentIdentity(ctx?.agentId).agentId; + const requested = (params as { agentId?: string }).agentId?.trim(); + const targetAgentId = + requested && requested.length > 0 ? requested : currentAgentId; + const { limit = 20, offset = 0 } = params as { + limit?: number; + offset?: number; + }; + if (!targetAgentId) { + return { + content: [ + { + type: "text", + text: "Cannot list shared memories: no agentId (configure memory-powermem agentId or pass agentId).", + }, + ], + details: { error: "missing_agent_id" }, + }; + } + try { + const rows = await agentClient.agentMemoryShared(targetAgentId, limit, offset); + const list = rows ?? []; + const text = list + .map( + (row, idx) => + `${idx + 1}. ${String((row.content ?? row.memory) as string).slice(0, 80)}`, + ) + .join("\n"); + return { + content: [ + { type: "text", text: list.length ? text : "No shared memories found." }, + ], + details: { count: list.length }, + }; + } catch (err) { + api.logger.warn(`memory-powermem: agent_memory_shared failed: ${String(err)}`); + return { + content: [ + { + type: "text", + text: `Failed to list shared memories: ${err instanceof Error ? err.message : String(err)}`, + }, + ], + details: { error: String(err) }, + }; + } + }, + }), + { name: "agent_memory_shared" }, + ); + } + + // ======================================================================== + // CLI Commands + // ======================================================================== + + api.registerCli( + ({ program }: OpenClawPluginCliContext) => { + const ltm = program + .command("ltm") + .description("PowerMem long-term memory plugin commands"); + + ltm + .command("search") + .description("Search memories") + .argument("", "Search query") + .option("--limit ", "Max results", "5") + .option("--score-threshold ", "Min score (0-1) to keep") + .action(async (...args: unknown[]) => { + const cliSearchStartedAt = perfNow(); + const query = String(args[0] ?? ""); + const opts = (args[1] ?? {}) as { limit?: string; scoreThreshold?: string }; + const limit = parseInt(opts.limit ?? "5", 10); + const rawThreshold = opts.scoreThreshold?.trim(); + const threshold = + rawThreshold && Number.isFinite(Number(rawThreshold)) + ? Math.max(0, Math.min(1, Number(rawThreshold))) + : undefined; + const searchStartedAt = perfNow(); + const results = await client.search(query, limit); + const filtered = + threshold === undefined + ? results + : results.filter((r) => (r.score ?? 0) >= threshold); + perfLog("cli.ltm.search", cliSearchStartedAt, { + queryLen: query.length, + limit, + threshold: threshold ?? null, + resultCount: results.length, + filteredCount: filtered.length, + upstreamMs: perfNow() - searchStartedAt, + }); + console.log(JSON.stringify(filtered, null, 2)); + }); + + ltm + .command("health") + .description("Check PowerMem server health") + .action(async () => { + const cliHealthStartedAt = perfNow(); + try { + const healthStartedAt = perfNow(); + const h = await client.health(); + perfLog("cli.ltm.health", cliHealthStartedAt, { + status: h.status, + upstreamMs: perfNow() - healthStartedAt, + }); + console.log("PowerMem:", h.status); + if (h.status !== "healthy" && "error" in h && h.error) { + console.error(h.error); + } + } catch (err) { + console.error("PowerMem health check failed:", err); + process.exitCode = 1; + } finally { + perfLog("cli.ltm.health.total", cliHealthStartedAt); + } + }); + + ltm + .command("add") + .description("Manually add a memory (for testing or one-off storage)") + .argument("", "Content to store") + .action(async (...args: unknown[]) => { + const cliAddStartedAt = perfNow(); + const text = String(args[0] ?? ""); + try { + const addStartedAt = perfNow(); + const created = await client.add(text.trim(), { infer: cfg.inferOnAdd }); + perfLog("cli.ltm.add", cliAddStartedAt, { + textLen: text.trim().length, + infer: cfg.inferOnAdd, + createdCount: created.length, + upstreamMs: perfNow() - addStartedAt, + }); + if (created.length === 0) { + console.log("Stored (no inferred items)."); + } else { + console.log(`Stored ${created.length} item(s):`, created.map((c) => c.memory_id)); + } + } catch (err) { + console.error("PowerMem add failed:", err); + process.exitCode = 1; + } finally { + perfLog("cli.ltm.add.total", cliAddStartedAt, { textLen: text.trim().length }); + } + }); + }, + { commands: ["ltm"] }, + ); + + // ======================================================================== + // Lifecycle Hooks + // ======================================================================== + + const MEMORY_RECALL_GUIDANCE = + "## Long-term memory (PowerMem)\n" + + "When answering about past events, user preferences, people, or anything the user may have told you before: use the memory_recall tool to search long-term memory first, or use any already injected in this turn.\n" + + "When you need procedural guidance or lessons learned, consider experience_recall or if available.\n"; + + function lastUserMessageText(messages: unknown[] | undefined): string { + if (!Array.isArray(messages) || messages.length === 0) return ""; + for (let i = messages.length - 1; i >= 0; i--) { + const msg = messages[i]; + if (!msg || typeof msg !== "object") continue; + const role = (msg as Record).role; + if (role !== "user") continue; + const content = (msg as Record).content; + if (typeof content === "string" && content.trim().length >= 5) return content.trim(); + if (Array.isArray(content)) { + for (const block of content) { + if ( + block && + typeof block === "object" && + (block as Record).type === "text" && + typeof (block as Record).text === "string" + ) { + const t = String((block as Record).text).trim(); + if (t.length >= 5) return t; + } + } + } + } + return ""; + } + + function extractText(content: unknown): string { + if (typeof content === "string") return content; + if (Array.isArray(content)) { + return content + .filter( + (block) => + block && + typeof block === "object" && + (block as Record).type === "text" && + typeof (block as Record).text === "string", + ) + .map((block) => String((block as Record).text)) + .join("\n"); + } + return ""; + } + + function extractToolNames(messages: unknown[]): string[] { + const names = new Set(); + for (const msg of messages) { + if (!msg || typeof msg !== "object") continue; + const msgObj = msg as Record; + const role = msgObj.role; + if (role === "tool" || role === "toolResult") { + const toolName = msgObj.name ?? msgObj.toolName; + if (typeof toolName === "string" && toolName.trim()) { + names.add(toolName.trim()); + } + } + const content = msgObj.content; + if (Array.isArray(content)) { + for (const block of content) { + if (!block || typeof block !== "object") continue; + const blockObj = block as Record; + const type = blockObj.type; + if ((type === "tool_use" || type === "toolCall") && typeof blockObj.name === "string") { + names.add(blockObj.name); + } + } + } + } + return Array.from(names); + } + + function lastRoleText(messages: unknown[], role: string): string { + for (let i = messages.length - 1; i >= 0; i--) { + const msg = messages[i]; + if (!msg || typeof msg !== "object") continue; + const msgObj = msg as Record; + if (msgObj.role !== role) continue; + const text = extractText(msgObj.content); + if (text.trim()) return text.trim(); + } + return ""; + } + + const EXPERIENCE_SYSTEM_PROMPT = + "You are extracting durable procedural experiences from an agent session.\n" + + "Return a JSON array of 1-3 concise experience statements. Each item should be actionable guidance\n" + + "that can help future tasks. Avoid sensitive data, greetings, or boilerplate.\n" + + "Output ONLY valid JSON array of strings, no extra text."; + + function buildExperiencePrompt(messages: unknown[]): string { + const recent = Array.isArray(messages) + ? messages.filter((m) => m && typeof m === "object").slice(-12) + : []; + const lines = recent + .map((msg) => { + const obj = msg as Record; + const role = typeof obj.role === "string" ? obj.role : "unknown"; + const text = extractText(obj.content).slice(0, 800); + if (!text.trim()) return ""; + return `${role}: ${text}`; + }) + .filter(Boolean); + return lines.join("\n"); + } + + function parseExperienceList(raw: string | null): string[] { + if (!raw) return []; + const trimmed = raw.trim(); + if (!trimmed) return []; + try { + const parsed = JSON.parse(trimmed); + if (Array.isArray(parsed)) { + return parsed + .filter((item) => typeof item === "string") + .map((item) => item.trim()) + .filter((item) => item.length >= 20); + } + } catch { + // fall through + } + return trimmed + .split("\n") + .map((line) => line.replace(/^[-*\d.\s]+/, "").trim()) + .filter((line) => line.length >= 20); + } + + async function extractExperiencesWithLlm(messages: unknown[]): Promise { + const prompt = buildExperiencePrompt(messages); + if (!prompt.trim()) return []; + const reply = await callLlm(api, prompt, { + systemPrompt: EXPERIENCE_SYSTEM_PROMPT, + maxTokens: 512, + temperature: 0.2, + }); + const list = parseExperienceList(reply).slice(0, 3); + return list; + } + + function splitExperiences(results: PowerMemSearchResult[]): { + memories: PowerMemSearchResult[]; + experiences: PowerMemSearchResult[]; + } { + const memories: PowerMemSearchResult[] = []; + const experiences: PowerMemSearchResult[] = []; + for (const r of results) { + const meta = r.metadata ?? {}; + const kind = typeof meta.type === "string" ? meta.type : ""; + if (kind === "experience") experiences.push(r); + else memories.push(r); + } + return { memories, experiences }; + } + + async function walCapture(prompt: string, sessionKey: string, ctxAgentId?: string): Promise { + const agentClient = getClientForAgent(ctxAgentId); + await walCaptureCore(prompt, sessionKey, walSession, { + callLlm: (p, opts) => callLlm(api, p, opts), + store: async (content, metadata) => { + const created = await agentClient.add(content, { infer: false, metadata }); + const id = created[0]?.memory_id; + return { id }; + }, + logger: api.logger, + }); + } + + if (cfg.autoRecall) { + api.on("before_agent_start", async (...args: unknown[]) => { + const autoRecallStartedAt = perfNow(); + const [event, ctx] = args as [unknown, ToolContext]; + const agentClient = getClientForAgent(ctx?.agentId) as MemoryClient & AgentMemoryClient; + const e = event as { prompt: string; messages?: unknown[] }; + const query = + (typeof e.prompt === "string" && e.prompt.trim().length >= 5 + ? e.prompt.trim() + : lastUserMessageText(e.messages)) || ""; + if (query.length < 5) { + return { prependSystemContext: MEMORY_RECALL_GUIDANCE }; + } + + const recallLimit = Math.max(1, Math.min(100, cfg.recallLimit ?? 5)); + const scoreThreshold = Math.max(0, Math.min(1, cfg.recallScoreThreshold ?? 0)); + + try { + const requestLimit = Math.min(100, Math.max(recallLimit * 2, recallLimit + 10)); + const searchStartedAt = perfNow(); + const primary = await agentClient.search(query, requestLimit); + perfLog("autoRecall.search", searchStartedAt, { + agent: resolveAgentIdentity(ctx?.agentId).agentId, + queryLen: query.length, + requestLimit, + resultCount: primary.length, + }); + const { merged: recallMerged, sharedFetched } = await mergeSearchWithSharedInbox( + agentClient, + ctx?.agentId, + query, + primary, + requestLimit, + "autoRecall", + ); + const { memories, experiences } = splitExperiences(recallMerged); + const memoryResults = memories + .filter((r) => (r.score ?? 0) >= scoreThreshold) + .slice(0, recallLimit); + const experienceResults = cfg.experienceRecall + ? experiences.filter((r) => (r.score ?? 0) >= scoreThreshold).slice(0, recallLimit) + : []; + + const memoryContext = + memoryResults.length > 0 + ? memoryResults.map((r) => `- ${r.content}`).join("\n") + : ""; + const experienceContext = + experienceResults.length > 0 + ? experienceResults.map((r) => `- ${r.content}`).join("\n") + : ""; + + const contexts: string[] = []; + if (memoryContext) { + contexts.push( + `\nThe following memories may be relevant to this conversation:\n${memoryContext}\n`, + ); + } + if (experienceContext) { + contexts.push( + `\nThe following experiences may be relevant to this conversation:\n${experienceContext}\n`, + ); + } + + if (memoryResults.length > 0 || experienceResults.length > 0) { + api.logger.info( + `memory-powermem: injecting ${memoryResults.length} memories and ${experienceResults.length} experiences into context`, + ); + } + perfLog("autoRecall.total", autoRecallStartedAt, { + queryLen: query.length, + memoryCount: memoryResults.length, + experienceCount: experienceResults.length, + sharedCount: sharedFetched, + }); + + return { + prependSystemContext: MEMORY_RECALL_GUIDANCE, + ...(contexts.length > 0 ? { prependContext: contexts.join("\n\n") } : {}), + }; + } catch (err) { + api.logger.warn(`memory-powermem: recall failed: ${String(err)}`); + return { prependSystemContext: MEMORY_RECALL_GUIDANCE }; + } + }); + } + + if (cfg.walCapture) { + api.on("before_agent_start", async (...args: unknown[]) => { + const [event, ctx] = args as [unknown, ToolContext & { sessionKey?: string }]; + const e = event as { prompt?: string; messages?: unknown[] }; + const prompt = + typeof e.prompt === "string" && e.prompt.trim().length >= 5 + ? e.prompt.trim() + : lastUserMessageText(e.messages); + if (!prompt) return; + const sessionKey = ctx?.sessionKey ?? "fallback"; + walCapture(prompt, sessionKey, ctx?.agentId).catch((err) => { + api.logger.warn(`memory-powermem: wal capture failed: ${String(err)}`); + }); + }); + } + + if (cfg.autoCapture) { + api.on("agent_end", (...args: unknown[]) => { + const [event, ctx] = args as [unknown, ToolContext]; + const e = event as { messages: unknown[]; success: boolean; error?: string }; + if (!e.success || !e.messages || e.messages.length === 0) { + return; + } + const messages = e.messages; + const agentId = ctx?.agentId; + + void (async () => { + const autoCaptureStartedAt = perfNow(); + inFlightAutoCapture += 1; + try { + const agentClient = getClientForAgent(agentId); + const texts: string[] = []; + for (const msg of messages) { + if (!msg || typeof msg !== "object") continue; + const msgObj = msg as Record; + const role = msgObj.role; + if (role !== "user" && role !== "assistant") continue; + const content = msgObj.content; + if (typeof content === "string") { + texts.push(content); + continue; + } + if (Array.isArray(content)) { + for (const block of content) { + if ( + block && + typeof block === "object" && + "type" in block && + (block as Record).type === "text" && + "text" in block && + typeof (block as Record).text === "string" + ) { + texts.push((block as Record).text as string); + } + } + } + } + + const MIN_LEN = 10; + const MAX_CHUNK_LEN = 6000; + const MAX_CHUNKS_PER_SESSION = 3; + const sanitized = texts + .filter((t): t is string => typeof t === "string" && t.trim().length >= MIN_LEN) + .map((t) => t.trim()) + .filter( + (t) => + !t.includes("") && + !(t.startsWith("<") && t.includes("= MAX_CHUNKS_PER_SESSION) break; + chunks.push(combined.slice(i, i + MAX_CHUNK_LEN)); + } + + let stored = 0; + for (const chunk of chunks) { + const addStartedAt = perfNow(); + const created = await agentClient.add(chunk, { infer: cfg.inferOnAdd }); + perfLog("autoCapture.add_chunk", addStartedAt, { + agent: resolveAgentIdentity(agentId).agentId, + chunkLen: chunk.length, + createdCount: created.length, + inFlightAutoCapture, + }); + stored += created.length; + } + if (stored > 0) { + api.logger.info( + `memory-powermem: auto-captured ${stored} memories from conversation`, + ); + } + perfLog("autoCapture.total", autoCaptureStartedAt, { + agent: resolveAgentIdentity(agentId).agentId, + inputMessageCount: messages.length, + chunkCount: chunks.length, + stored, + inFlightAutoCapture, + }); + } catch (err) { + api.logger.warn(`memory-powermem: capture failed: ${String(err)}`); + } finally { + inFlightAutoCapture = Math.max(0, inFlightAutoCapture - 1); + } + })(); + }); + } + + if (cfg.autoExperience) { + api.on("agent_end", (...args: unknown[]) => { + const [event, ctx] = args as [unknown, ToolContext]; + const e = event as { messages: unknown[]; success: boolean; error?: string }; + if (!e.success || !e.messages || e.messages.length === 0) { + return; + } + const messages = e.messages; + const agentId = ctx?.agentId; + + void (async () => { + const autoExperienceStartedAt = perfNow(); + inFlightAutoExperience += 1; + try { + const agentClient = getClientForAgent(agentId); + const tools = extractToolNames(messages); + const extractStartedAt = perfNow(); + const experiences = await extractExperiencesWithLlm(messages); + perfLog("autoExperience.extract_llm", extractStartedAt, { + agent: resolveAgentIdentity(agentId).agentId, + messageCount: messages.length, + toolCount: tools.length, + experienceCount: experiences.length, + inFlightAutoExperience, + }); + if (experiences.length === 0) return; + for (const exp of experiences) { + const addStartedAt = perfNow(); + await agentClient.add(exp, { + infer: false, + metadata: { + type: "experience", + source: "auto", + tools, + }, + }); + perfLog("autoExperience.add", addStartedAt, { + agent: resolveAgentIdentity(agentId).agentId, + experienceLen: exp.length, + inFlightAutoExperience, + }); + } + api.logger.info(`memory-powermem: auto-experience stored (${experiences.length})`); + perfLog("autoExperience.total", autoExperienceStartedAt, { + agent: resolveAgentIdentity(agentId).agentId, + messageCount: messages.length, + stored: experiences.length, + inFlightAutoExperience, + }); + } catch (err) { + api.logger.warn(`memory-powermem: auto-experience failed: ${String(err)}`); + } finally { + inFlightAutoExperience = Math.max(0, inFlightAutoExperience - 1); + } + })(); + }); + } + + if (cfg.walCapture) { + api.on("session_end", (...args: unknown[]) => { + const [, ctx] = args as [unknown, ToolContext & { sessionKey?: string }]; + const key = ctx?.sessionKey ?? "fallback"; + walSession.clear(key); + }); + } + + // ======================================================================== + // Service + // ======================================================================== + + api.registerService({ + id: "memory-powermem", + start: async (_ctx: OpenClawPluginServiceContext) => { + try { + const h = await client.health(); + const where = + cfg.mode === "cli" + ? `cli ${resolvePmemExecutable(cfg.pmemPath ?? DEFAULT_PMEM_PATH)}` + : cfg.baseUrl; + const detail = + h.status !== "healthy" && "error" in h && h.error ? `: ${h.error}` : ""; + api.logger.info( + `memory-powermem: initialized (${where}, health: ${h.status}${detail})`, + ); + } catch (err) { + const hint = + cfg.mode === "cli" + ? "is npm powermem installed (plugin dependencies)? Or set pmemPath to auto / a Python venv pmem. Check agents.defaults.model + keys, or envFile." + : "is PowerMem server running?"; + api.logger.warn( + `memory-powermem: health check failed (${hint}): ${String(err)}`, + ); + } + }, + stop: (_ctx: OpenClawPluginServiceContext) => { + api.logger.info("memory-powermem: stopped"); + }, + }); + }, +}; + +export default memoryPlugin; diff --git a/src/llm.ts b/src/llm.ts new file mode 100644 index 0000000..9b82ff4 --- /dev/null +++ b/src/llm.ts @@ -0,0 +1,207 @@ +import { + completeSimple, + getEnvApiKey, + getModel, + type Api, + type Model, +} from "@mariozechner/pi-ai"; +import type { OpenClawPluginApi } from "openclaw/plugin-sdk"; + +const API_REMAP: Record = { + ollama: "openai-completions", +}; + +function resolveCompatBaseUrl(originalApi: string, baseUrl: string | undefined): string | undefined { + if (originalApi === "ollama") { + const base = (baseUrl ?? "http://localhost:11434").replace(/\/+$/, ""); + return base.endsWith("/v1") ? base : `${base}/v1`; + } + return baseUrl; +} + +type Logger = OpenClawPluginApi["logger"]; + +function buildModelFromConfig( + provider: string, + modelId: string, + cfg: OpenClawPluginApi["config"], + logger: Logger, +): Model | null { + const providers = cfg?.models?.providers ?? {}; + const providerCfg = + (providers as Record)[provider] ?? + Object.entries(providers).find(([k]) => k.toLowerCase() === provider.toLowerCase())?.[1]; + + if (!providerCfg || typeof providerCfg !== "object") { + logger.warn(`powermem/llm: provider "${provider}" not found in config`); + return null; + } + + const cfg_ = providerCfg as Record; + const rawApi = (cfg_.api as string | undefined) ?? "openai-completions"; + const configuredBaseUrl = cfg_.baseUrl as string | undefined; + + const effectiveApi = API_REMAP[rawApi] ?? rawApi; + const effectiveBaseUrl = resolveCompatBaseUrl(rawApi, configuredBaseUrl); + + const modelsList = cfg_.models as Array> | undefined; + const modelCfg = modelsList?.find((m) => m.id === modelId); + + logger.info?.( + `powermem/llm: built model from config — provider=${provider}, model=${modelId}, api=${effectiveApi}, baseUrl=${effectiveBaseUrl ?? "(none)"}`, + ); + + return { + id: modelId, + name: modelId, + api: effectiveApi as Api, + provider, + baseUrl: effectiveBaseUrl, + reasoning: (modelCfg?.reasoning as boolean | undefined) ?? false, + input: ["text"], + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + contextWindow: + (modelCfg?.contextWindow as number | undefined) ?? + (modelCfg?.maxTokens as number | undefined) ?? + 8192, + maxTokens: (modelCfg?.maxTokens as number | undefined) ?? 4096, + } as Model; +} + +function resolveModel( + provider: string, + modelId: string, + cfg: OpenClawPluginApi["config"], + logger: Logger, +): Model | null { + const builtIn = getModel(provider, modelId) as Model | null | undefined; + if (builtIn) { + logger.info?.(`powermem/llm: resolved model from built-in catalog — ${provider}/${modelId}`); + return builtIn; + } + logger.info?.(`powermem/llm: model not in built-in catalog, trying user config — ${provider}/${modelId}`); + return buildModelFromConfig(provider, modelId, cfg, logger); +} + +async function resolveApiKey(api: OpenClawPluginApi, provider: string): Promise { + const cfg = api.config; + + try { + const modelAuth = (api.runtime as any)?.modelAuth; + if (modelAuth?.resolveApiKeyForProvider) { + const auth = await modelAuth.resolveApiKeyForProvider({ provider, cfg }); + if (auth?.apiKey) { + api.logger.info?.(`powermem/llm: auth via runtime.modelAuth — provider="${provider}"`); + return auth.apiKey; + } + } + } catch (e) { + api.logger.warn(`powermem/llm: runtime.modelAuth failed: ${String(e)}`); + } + + try { + const envKey = getEnvApiKey(provider); + if (envKey) { + api.logger.info?.(`powermem/llm: auth via env var — provider="${provider}"`); + return envKey; + } + } catch { + // ignore + } + + const providers = (cfg?.models?.providers ?? {}) as Record>; + const providerCfg = + providers[provider] ?? + Object.values(providers).find( + (_, idx) => Object.keys(providers)[idx].toLowerCase() === provider.toLowerCase(), + ); + const configKey = providerCfg?.apiKey as string | undefined; + if (configKey) { + api.logger.info?.(`powermem/llm: auth via config apiKey — provider="${provider}"`); + return configKey; + } + + return undefined; +} + +export async function callLlm( + api: OpenClawPluginApi, + prompt: string, + opts?: { + maxTokens?: number; + temperature?: number; + systemPrompt?: string; + }, +): Promise { + const cfg = api.config; + const defaultModel = cfg?.agents?.defaults?.model; + const primary = + typeof defaultModel === "string" + ? defaultModel + : ((defaultModel as Record | undefined)?.primary as string | undefined); + + if (!primary?.trim()) { + api.logger.warn("powermem/llm: no default model configured, skipping"); + return null; + } + + const slashIdx = primary.indexOf("/"); + if (slashIdx < 0) { + api.logger.warn( + `powermem/llm: invalid model format "${primary}", expected "provider/model"`, + ); + return null; + } + + const provider = primary.slice(0, slashIdx); + const modelId = primary.slice(slashIdx + 1); + + api.logger.info?.(`powermem/llm: resolving model ${provider}/${modelId}`); + const model = resolveModel(provider, modelId, cfg, api.logger); + if (!model) { + api.logger.warn( + `powermem/llm: could not resolve model ${provider}/${modelId}, skipping LLM call`, + ); + return null; + } + + api.logger.info?.(`powermem/llm: resolving auth for provider "${provider}"`); + const apiKey = await resolveApiKey(api, provider); + if (!apiKey) { + api.logger.warn( + `powermem/llm: no apiKey found for provider "${provider}". ` + + `Ensure openclaw auth, env var, or models.providers.${provider}.apiKey.`, + ); + return null; + } + + const messages: Array<{ role: string; content: string; timestamp: number }> = []; + if (opts?.systemPrompt) { + messages.push({ + role: "system", + content: opts.systemPrompt, + timestamp: Date.now(), + }); + } + messages.push({ role: "user", content: prompt, timestamp: Date.now() }); + + const maxTokens = opts?.maxTokens ?? 512; + const temperature = opts?.temperature ?? 0.2; + + try { + const result = await completeSimple( + model, + { messages }, + { apiKey, maxTokens, temperature }, + ); + const text = (result.content as Array<{ type: string; text?: string }>) + ?.filter((block) => block.type === "text" && typeof block.text === "string") + .map((block) => block.text as string) + .join("") + .trim(); + return text || null; + } catch (err) { + api.logger.warn(`powermem/llm: completeSimple failed: ${String(err)}`); + return null; + } +} diff --git a/src/local-embedding.ts b/src/local-embedding.ts new file mode 100644 index 0000000..d2baa31 --- /dev/null +++ b/src/local-embedding.ts @@ -0,0 +1,358 @@ +import { getEnvApiKey } from "@mariozechner/pi-ai"; +import type { OpenClawPluginApi } from "openclaw/plugin-sdk/memory-core"; + +import type { PowerMemConfig } from "./config.js"; + +type Logger = { info?: (msg: string) => void; warn?: (msg: string) => void }; + +export type LocalEmbeddingProvider = { + id: string; + model: string; + embed: (text: string) => Promise; + embedBatch?: (texts: string[]) => Promise; +}; + +export type LocalEmbeddingConfig = { + enabled: boolean; + provider: string; + providerKey?: string; + model: string; + apiKey?: string; + baseUrl?: string; + headers?: Record; + extensionPath?: string; +}; + +export type LocalEmbeddingFactory = { + config: LocalEmbeddingConfig; + get: () => Promise; +}; + +const DEFAULT_OPENAI_MODEL = "text-embedding-3-small"; +const DEFAULT_OLLAMA_MODEL = "nomic-embed-text"; + +const PROVIDER_ALIASES: Record = { + bailian: { provider: "openai", providerKey: "bailian" }, + dashscope: { provider: "openai", providerKey: "dashscope" }, + qwen: { provider: "openai", providerKey: "qwen" }, +}; + +function resolveProviderMapping(provider: string): { provider: string; providerKey: string } { + const normalized = provider.trim().toLowerCase(); + if (normalized === "auto") { + return { provider: "openai", providerKey: "openai" }; + } + const alias = PROVIDER_ALIASES[normalized]; + if (alias) { + return { provider: alias.provider, providerKey: alias.providerKey ?? normalized }; + } + return { provider: normalized, providerKey: normalized }; +} + +function resolveDefaultModel(provider: string): string { + if (provider === "ollama") { + return DEFAULT_OLLAMA_MODEL; + } + return DEFAULT_OPENAI_MODEL; +} + +function normalizeBaseUrl(provider: string, baseUrl?: string): string | undefined { + const trimmed = baseUrl?.trim(); + if (!trimmed) { + if (provider === "ollama") { + return "http://localhost:11434/v1"; + } + return "https://api.openai.com"; + } + const cleaned = trimmed.replace(/\/+$/, ""); + if (provider === "ollama") { + return cleaned.endsWith("/v1") ? cleaned : `${cleaned}/v1`; + } + return cleaned; +} + +function buildEmbeddingsUrl(baseUrl: string): string { + return baseUrl.endsWith("/v1") ? `${baseUrl}/embeddings` : `${baseUrl}/v1/embeddings`; +} + +/** Avoid `res.json()` on empty/truncated bodies (throws Unexpected end of JSON input). */ +async function parseEmbeddingsResponseBody(res: Response): Promise { + const text = await res.text(); + const trimmed = text.trim(); + if (!trimmed) { + throw new Error(`embeddings HTTP ${res.status}: empty response body`); + } + try { + return JSON.parse(trimmed) as unknown; + } catch (err) { + const preview = trimmed.length > 240 ? `${trimmed.slice(0, 240)}…` : trimmed; + const cause = err instanceof Error ? err.message : String(err); + throw new Error(`embeddings HTTP ${res.status}: invalid JSON (${cause}). Preview: ${preview}`); + } +} + +function normalizeEmbedding(vec: number[]): number[] { + const sanitized = vec.map((value) => (Number.isFinite(value) ? value : 0)); + const magnitude = Math.sqrt(sanitized.reduce((sum, value) => sum + value * value, 0)); + if (magnitude < 1e-10) { + return sanitized; + } + return sanitized.map((value) => value / magnitude); +} + +function extractStringMap(value: unknown): Record | undefined { + if (!value || typeof value !== "object" || Array.isArray(value)) return undefined; + const entries = Object.entries(value).filter(([, v]) => typeof v === "string"); + if (entries.length === 0) return undefined; + return Object.fromEntries(entries as Array<[string, string]>); +} + +function resolveMemorySearchConfig( + openclawConfig: Record | undefined, + agentId: string, +): Record | undefined { + const agents = + openclawConfig && typeof openclawConfig === "object" + ? (openclawConfig as Record).agents + : undefined; + const agentsRecord = + agents && typeof agents === "object" ? (agents as Record) : undefined; + const list = Array.isArray(agentsRecord?.list) ? agentsRecord?.list : undefined; + const matched = list?.find((entry: unknown) => { + if (!entry || typeof entry !== "object") return false; + const record = entry as Record; + return typeof record.id === "string" && record.id === agentId; + }); + const agentMemorySearch = + matched && typeof matched === "object" + ? (matched as Record).memorySearch + : undefined; + if (agentMemorySearch && typeof agentMemorySearch === "object") { + return agentMemorySearch as Record; + } + const defaultsMemorySearch = + agentsRecord?.defaults && typeof agentsRecord.defaults === "object" + ? (agentsRecord.defaults as Record).memorySearch + : undefined; + if (defaultsMemorySearch && typeof defaultsMemorySearch === "object") { + return defaultsMemorySearch as Record; + } + return undefined; +} + +function resolveLocalEmbeddingConfig(params: { + api: OpenClawPluginApi; + cfg: PowerMemConfig; + agentId: string; + logger: Logger; +}): LocalEmbeddingConfig | null { + const localVector = params.cfg.localVector; + const enabled = localVector?.enabled ?? params.cfg.dualWrite === true; + if (!enabled) { + return null; + } + + const configRecord = + params.api.config && typeof params.api.config === "object" + ? (params.api.config as Record) + : undefined; + const memorySearch = resolveMemorySearchConfig(configRecord, params.agentId); + const memoryProviderRaw = + typeof memorySearch?.provider === "string" ? memorySearch.provider : undefined; + const resolvedProvider = resolveProviderMapping( + localVector?.provider ?? memoryProviderRaw ?? "openai", + ); + const provider = resolvedProvider.provider; + const providerKey = resolvedProvider.providerKey; + if (provider !== "openai" && provider !== "ollama") { + params.logger.warn?.( + `dual-write: local vector search supports openai/ollama providers only, got "${provider}"`, + ); + return null; + } + + const model = + localVector?.model ?? + (typeof memorySearch?.model === "string" ? memorySearch.model : undefined) ?? + resolveDefaultModel(provider); + if (!model) { + params.logger.warn?.("dual-write: local vector search model is required"); + return null; + } + + const memoryRemote = + memorySearch?.remote && typeof memorySearch.remote === "object" + ? (memorySearch.remote as Record) + : undefined; + const memoryHeaders = extractStringMap(memoryRemote?.headers); + const localHeaders = extractStringMap(localVector?.headers); + const headers = localHeaders ?? memoryHeaders; + + const modelsRecord = + configRecord?.models && typeof configRecord.models === "object" + ? (configRecord.models as Record) + : undefined; + const providersRecord = + modelsRecord?.providers as Record> | undefined; + const providerCfg = providersRecord?.[providerKey] ?? providersRecord?.[provider]; + const baseUrl = normalizeBaseUrl( + provider, + localVector?.baseUrl ?? + (typeof memoryRemote?.baseUrl === "string" ? memoryRemote.baseUrl : undefined) ?? + (typeof providerCfg?.baseUrl === "string" ? providerCfg.baseUrl : undefined), + ); + + const apiKey = + localVector?.apiKey ?? + (typeof memoryRemote?.apiKey === "string" ? memoryRemote.apiKey : undefined) ?? + (typeof providerCfg?.apiKey === "string" ? providerCfg.apiKey : undefined); + + return { + enabled: true, + provider, + providerKey, + model, + apiKey, + baseUrl, + headers, + extensionPath: localVector?.extensionPath, + }; +} + +async function resolveApiKey( + api: OpenClawPluginApi, + providerKey: string, + provider: string, + fallback?: string, +): Promise { + const candidates = Array.from(new Set([providerKey, provider].filter(Boolean))); + try { + const modelAuth = (api.runtime as { modelAuth?: { resolveApiKeyForProvider?: Function } } | undefined) + ?.modelAuth; + if (modelAuth?.resolveApiKeyForProvider) { + for (const candidate of candidates) { + const auth = await modelAuth.resolveApiKeyForProvider({ provider: candidate, cfg: api.config }); + if (auth?.apiKey) { + return auth.apiKey; + } + } + } + } catch { + // ignore + } + + try { + for (const candidate of candidates) { + const envKey = getEnvApiKey(candidate); + if (envKey) { + return envKey; + } + } + } catch { + // ignore + } + + return fallback; +} + +async function createEmbeddingProvider(params: { + api: OpenClawPluginApi; + cfg: LocalEmbeddingConfig; + logger: Logger; +}): Promise { + const providerKey = params.cfg.providerKey ?? params.cfg.provider; + const apiKey = await resolveApiKey( + params.api, + providerKey, + params.cfg.provider, + params.cfg.apiKey, + ); + if (!apiKey && params.cfg.provider !== "ollama") { + params.logger.warn?.( + `dual-write: local vector search missing apiKey for provider "${params.cfg.provider}"`, + ); + return null; + } + + const baseUrl = params.cfg.baseUrl ?? normalizeBaseUrl(params.cfg.provider); + if (!baseUrl) { + params.logger.warn?.("dual-write: local vector search baseUrl is required"); + return null; + } + + const headers: Record = { + "Content-Type": "application/json", + ...(params.cfg.headers ?? {}), + }; + if (apiKey) { + headers.Authorization = `Bearer ${apiKey}`; + } + + const embedBatch = async (texts: string[]): Promise => { + const res = await fetch(buildEmbeddingsUrl(baseUrl), { + method: "POST", + headers, + body: JSON.stringify({ model: params.cfg.model, input: texts }), + }); + const payload = (await parseEmbeddingsResponseBody(res)) as { + data?: Array<{ embedding?: number[] }>; + error?: { message?: string }; + }; + if (!res.ok) { + const message = + payload?.error?.message ?? + (typeof payload === "string" ? payload : `Embeddings failed: ${res.status}`); + throw new Error(message); + } + const rows = payload?.data ?? []; + return rows.map((row) => normalizeEmbedding(row.embedding ?? [])); + }; + + return { + id: params.cfg.provider, + model: params.cfg.model, + embed: async (text) => { + const [vec] = await embedBatch([text]); + return vec ?? []; + }, + embedBatch, + }; +} + +export function createLocalEmbeddingFactory(params: { + api: OpenClawPluginApi; + cfg: PowerMemConfig; + agentId: string; + logger: Logger; +}): LocalEmbeddingFactory | null { + const config = resolveLocalEmbeddingConfig(params); + if (!config) { + return null; + } + let providerPromise: Promise | null = null; + let disabled = false; + + const get = async () => { + if (disabled) return null; + if (!providerPromise) { + providerPromise = createEmbeddingProvider({ + api: params.api, + cfg: config, + logger: params.logger, + }); + } + try { + const provider = await providerPromise; + if (!provider) { + disabled = true; + } + return provider; + } catch (err) { + params.logger.warn?.(`dual-write: local embedding init failed: ${String(err)}`); + disabled = true; + return null; + } + }; + + return { config, get }; +} diff --git a/src/local-sqlite.ts b/src/local-sqlite.ts new file mode 100644 index 0000000..cf27235 --- /dev/null +++ b/src/local-sqlite.ts @@ -0,0 +1,738 @@ +/** + * Local sqlite store for dual-write mode. + * Provides lightweight storage + pending queue for remote sync. + */ + +import Database from "better-sqlite3"; +import sqliteVec from "sqlite-vec"; +import { mkdirSync } from "node:fs"; +import { dirname } from "node:path"; + +export type LocalMemoryRow = { + id: number; + remote_id: string | null; + content: string; + metadata: Record; + user_id: string | null; + agent_id: string | null; + created_at: string; + updated_at: string; +}; + +export type PendingRow = { + id: number; + local_memory_id: number | null; + content: string; + metadata: Record; + user_id: string | null; + agent_id: string | null; + infer: boolean; + queued_at: string; + retries: number; + last_error: string | null; +}; + +export type LocalVectorConfig = { + enabled: boolean; + extensionPath?: string; +}; + +type Logger = { info?: (msg: string) => void; warn?: (msg: string) => void }; + +function nowIso(): string { + return new Date().toISOString(); +} + +function safeJsonParse(value: string | null): Record { + if (!value) return {}; + try { + const parsed = JSON.parse(value); + return parsed && typeof parsed === "object" ? parsed as Record : {}; + } catch { + return {}; + } +} + +function tokenize(text: string): string[] { + const tokens: string[] = []; + const parts = text.toLowerCase().split(/[\s,.;:!?。,;:!?、]+/); + for (const part of parts) { + if (!part) continue; + const subTokens = part.match(/[\u4e00-\u9fff\u3400-\u4dbf]|[a-z0-9_-]+/g); + if (subTokens) tokens.push(...subTokens); + } + return tokens; +} + +function tokenOverlap(queryTokens: string[], contentTokens: string[]): number { + if (queryTokens.length === 0) return 0; + const contentSet = new Set(contentTokens); + let hits = 0; + for (const t of queryTokens) { + if (contentSet.has(t)) hits++; + } + return hits / queryTokens.length; +} + +const VECTOR_TABLE = "memories_vec"; +const META_TABLE = "meta"; +const VECTOR_DIMS_KEY = "vector_dims"; + +function vectorToBlob(embedding: number[]): Buffer { + return Buffer.from(new Float32Array(embedding).buffer); +} + +export class LocalSqliteStore { + private db: Database.Database; + private logger?: Logger; + private ftsEnabled = false; + private hasNextRetryAt = true; + private hasLastError = true; + private vector = { + enabled: false, + available: false, + dims: undefined as number | undefined, + extensionPath: undefined as string | undefined, + loadError: undefined as string | undefined, + }; + + constructor(dbPath: string, options?: { logger?: Logger; vector?: LocalVectorConfig }) { + mkdirSync(dirname(dbPath), { recursive: true }); + this.db = new Database(dbPath); + this.logger = options?.logger; + this.vector.enabled = options?.vector?.enabled ?? false; + this.vector.extensionPath = options?.vector?.extensionPath; + this.init(); + } + + private init(): void { + this.db.exec(` + CREATE TABLE IF NOT EXISTS ${META_TABLE} ( + key TEXT PRIMARY KEY, + value TEXT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS memories ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + remote_id TEXT, + content TEXT NOT NULL, + metadata TEXT, + user_id TEXT, + agent_id TEXT, + created_at TEXT NOT NULL, + updated_at TEXT NOT NULL + ); + + CREATE TABLE IF NOT EXISTS pending_writes ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + local_memory_id INTEGER, + content TEXT NOT NULL, + metadata TEXT, + user_id TEXT, + agent_id TEXT, + infer INTEGER DEFAULT 1, + queued_at TEXT NOT NULL, + retries INTEGER DEFAULT 0, + next_retry_at TEXT, + last_error TEXT + ); + + CREATE INDEX IF NOT EXISTS idx_memories_user_agent + ON memories(user_id, agent_id); + + CREATE INDEX IF NOT EXISTS idx_memories_remote_id + ON memories(remote_id); + + CREATE UNIQUE INDEX IF NOT EXISTS idx_memories_remote_unique + ON memories(remote_id) + WHERE remote_id IS NOT NULL; + + CREATE INDEX IF NOT EXISTS idx_pending_created + ON pending_writes(queued_at); + `); + + this.vector.dims = this.readVectorDims(); + if (this.vector.enabled) { + this.loadVectorExtension(); + } + + try { + this.db.exec(` + CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5( + content, + user_id, + agent_id, + content='memories', + content_rowid='id' + ); + `); + + this.db.exec(` + CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN + INSERT INTO memories_fts(rowid, content, user_id, agent_id) + VALUES (new.id, new.content, new.user_id, new.agent_id); + END; + + CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN + INSERT INTO memories_fts(memories_fts, rowid, content, user_id, agent_id) + VALUES ('delete', old.id, old.content, old.user_id, old.agent_id); + END; + + CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN + INSERT INTO memories_fts(memories_fts, rowid, content, user_id, agent_id) + VALUES ('delete', old.id, old.content, old.user_id, old.agent_id); + INSERT INTO memories_fts(rowid, content, user_id, agent_id) + VALUES (new.id, new.content, new.user_id, new.agent_id); + END; + `); + this.ftsEnabled = true; + } catch (err) { + this.logger?.warn?.(`local-sqlite: fts5 disabled: ${String(err)}`); + this.ftsEnabled = false; + } + + try { + this.db.exec(`ALTER TABLE pending_writes ADD COLUMN next_retry_at TEXT`); + this.hasNextRetryAt = true; + } catch (err) { + const msg = String(err ?? ""); + if (msg.includes("duplicate column name") || msg.includes("duplicate column")) { + this.hasNextRetryAt = true; + } else { + this.hasNextRetryAt = false; + } + } + try { + this.db.exec(`ALTER TABLE pending_writes ADD COLUMN last_error TEXT`); + this.hasLastError = true; + } catch (err) { + const msg = String(err ?? ""); + if (msg.includes("duplicate column name") || msg.includes("duplicate column")) { + this.hasLastError = true; + } else { + this.hasLastError = false; + } + } + } + + private readVectorDims(): number | undefined { + try { + const row = this.db + .prepare(`SELECT value FROM ${META_TABLE} WHERE key = ?`) + .get(VECTOR_DIMS_KEY) as { value?: string } | undefined; + const raw = row?.value; + if (!raw) return undefined; + const n = Number(raw); + return Number.isFinite(n) ? Math.floor(n) : undefined; + } catch { + return undefined; + } + } + + private writeVectorDims(value?: number): void { + try { + if (!value) { + this.db.prepare(`DELETE FROM ${META_TABLE} WHERE key = ?`).run(VECTOR_DIMS_KEY); + return; + } + this.db + .prepare( + `INSERT INTO ${META_TABLE} (key, value) VALUES (?, ?)\n` + + `ON CONFLICT(key) DO UPDATE SET value = excluded.value`, + ) + .run(VECTOR_DIMS_KEY, String(value)); + } catch (err) { + this.logger?.warn?.(`local-sqlite: failed to persist vector dims: ${String(err)}`); + } + } + + private loadVectorExtension(): void { + try { + if (this.vector.extensionPath) { + this.db.loadExtension(this.vector.extensionPath); + } else { + sqliteVec.load(this.db); + } + this.vector.available = true; + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + this.vector.available = false; + this.vector.loadError = message; + this.logger?.warn?.(`local-sqlite: sqlite-vec unavailable: ${message}`); + } + } + + private ensureVectorTable(dimensions: number): boolean { + if (!this.vector.enabled || !this.vector.available) { + return false; + } + if (this.vector.dims === dimensions && !this.vectorTableNeedsRebuild()) { + return true; + } + if (this.vector.dims && this.vector.dims !== dimensions) { + this.dropVectorTable(); + } else if (this.vectorTableNeedsRebuild()) { + this.dropVectorTable(); + } + this.db.exec( + `CREATE VIRTUAL TABLE IF NOT EXISTS ${VECTOR_TABLE} USING vec0(\n` + + ` embedding FLOAT[${dimensions}]\n` + + `)`, + ); + this.vector.dims = dimensions; + this.writeVectorDims(dimensions); + return true; + } + + private dropVectorTable(): void { + try { + this.db.exec(`DROP TABLE IF EXISTS ${VECTOR_TABLE}`); + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + this.logger?.warn?.(`local-sqlite: failed to drop ${VECTOR_TABLE}: ${message}`); + } + this.vector.dims = undefined; + this.writeVectorDims(undefined); + } + + private vectorTableNeedsRebuild(): boolean { + try { + const cols = this.db + .prepare(`PRAGMA table_info(${VECTOR_TABLE})`) + .all() as Array<{ name?: string }>; + if (!cols || cols.length === 0) { + return false; + } + return cols.some((col) => col?.name === "id"); + } catch { + return false; + } + } + + upsertRemoteMemory(params: { + remoteId: string; + content: string; + metadata?: Record; + userId?: string; + agentId?: string; + }): number { + const now = nowIso(); + const existing = this.db + .prepare(`SELECT id FROM memories WHERE remote_id = ?`) + .get(params.remoteId) as { id: number } | undefined; + if (existing?.id) { + const stmt = this.db.prepare(` + UPDATE memories + SET content = @content, + metadata = @metadata, + user_id = @user_id, + agent_id = @agent_id, + updated_at = @updated_at + WHERE id = @id + `); + stmt.run({ + id: existing.id, + content: params.content, + metadata: params.metadata ? JSON.stringify(params.metadata) : null, + user_id: params.userId ?? null, + agent_id: params.agentId ?? null, + updated_at: now, + }); + return existing.id; + } + + const stmt = this.db.prepare(` + INSERT INTO memories (remote_id, content, metadata, user_id, agent_id, created_at, updated_at) + VALUES (@remote_id, @content, @metadata, @user_id, @agent_id, @created_at, @updated_at) + `); + const info = stmt.run({ + remote_id: params.remoteId, + content: params.content, + metadata: params.metadata ? JSON.stringify(params.metadata) : null, + user_id: params.userId ?? null, + agent_id: params.agentId ?? null, + created_at: now, + updated_at: now, + }); + return Number(info.lastInsertRowid ?? 0); + } + + addLocalMemory(params: { + content: string; + metadata?: Record; + userId?: string; + agentId?: string; + }): number { + const now = nowIso(); + const stmt = this.db.prepare(` + INSERT INTO memories (remote_id, content, metadata, user_id, agent_id, created_at, updated_at) + VALUES (NULL, @content, @metadata, @user_id, @agent_id, @created_at, @updated_at) + `); + const info = stmt.run({ + content: params.content, + metadata: params.metadata ? JSON.stringify(params.metadata) : null, + user_id: params.userId ?? null, + agent_id: params.agentId ?? null, + created_at: now, + updated_at: now, + }); + return Number(info.lastInsertRowid ?? 0); + } + + upsertEmbedding(localId: number, embedding: number[]): boolean { + if (!this.ensureVectorTable(embedding.length)) { + return false; + } + const rowid = + typeof localId === "bigint" + ? localId + : Number.isSafeInteger(localId) && localId > 0 + ? BigInt(localId) + : null; + if (!rowid) { + this.logger?.warn?.( + `local-sqlite: skip vector write (invalid rowid=${String(localId)})`, + ); + return false; + } + const writeOnce = () => { + this.db.prepare(`DELETE FROM ${VECTOR_TABLE} WHERE rowid = ?`).run(rowid); + this.db + .prepare(`INSERT INTO ${VECTOR_TABLE} (rowid, embedding) VALUES (?, ?)`) + .run(rowid, vectorToBlob(embedding)); + }; + try { + writeOnce(); + return true; + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + if (message.includes("primary key") || message.includes("memories_vec")) { + this.dropVectorTable(); + if (!this.ensureVectorTable(embedding.length)) { + return false; + } + try { + writeOnce(); + return true; + } catch (retryErr) { + const retryMessage = retryErr instanceof Error ? retryErr.message : String(retryErr); + this.logger?.warn?.(`local-sqlite: vector write failed: ${retryMessage}`); + return false; + } + } + this.logger?.warn?.(`local-sqlite: vector write failed: ${message}`); + return false; + } + } + + updateRemoteId(localId: number, remoteId: string): void { + const stmt = this.db.prepare(` + UPDATE memories SET remote_id = @remote_id, updated_at = @updated_at + WHERE id = @id + `); + stmt.run({ id: localId, remote_id: remoteId, updated_at: nowIso() }); + } + + deleteByRemoteId(remoteId: string): void { + const row = this.db + .prepare(`SELECT id FROM memories WHERE remote_id = ?`) + .get(remoteId) as { id: number } | undefined; + if (row?.id) { + this.deleteByLocalId(row.id); + return; + } + const stmt = this.db.prepare(`DELETE FROM memories WHERE remote_id = ?`); + stmt.run(remoteId); + } + + deleteByLocalId(localId: number): void { + const stmt = this.db.prepare(`DELETE FROM memories WHERE id = ?`); + stmt.run(localId); + if (this.vector.enabled && this.vector.available) { + const rowid = + typeof localId === "bigint" + ? localId + : Number.isSafeInteger(localId) && localId > 0 + ? BigInt(localId) + : null; + if (rowid) { + this.db.prepare(`DELETE FROM ${VECTOR_TABLE} WHERE rowid = ?`).run(rowid); + } + } + } + + search(params: { + query: string; + limit: number; + userId?: string; + agentId?: string; + }): Array { + const tokens = tokenize(params.query); + if (tokens.length === 0) return []; + + if (this.ftsEnabled) { + const clauses: string[] = []; + const values: Array = []; + if (params.userId) { + clauses.push("memories.user_id = ?"); + values.push(params.userId); + } + if (params.agentId) { + clauses.push("memories.agent_id = ?"); + values.push(params.agentId); + } + const where = clauses.length > 0 ? `AND ${clauses.join(" AND ")}` : ""; + try { + const stmt = this.db.prepare(` + SELECT memories.id, memories.remote_id, memories.content, memories.metadata, + memories.user_id, memories.agent_id, memories.created_at, memories.updated_at, + bm25(memories_fts) AS score + FROM memories_fts + JOIN memories ON memories_fts.rowid = memories.id + WHERE memories_fts MATCH ? ${where} + ORDER BY score ASC + LIMIT ? + `); + const rows = stmt.all(params.query, ...values, params.limit) as Array<{ + id: number; + remote_id: string | null; + content: string; + metadata: string | null; + user_id: string | null; + agent_id: string | null; + created_at: string; + updated_at: string; + score: number; + }>; + return rows.map((row) => ({ + id: row.id, + remote_id: row.remote_id, + content: row.content, + metadata: safeJsonParse(row.metadata), + user_id: row.user_id, + agent_id: row.agent_id, + created_at: row.created_at, + updated_at: row.updated_at, + score: 1 / (1 + Math.max(0, row.score ?? 0)), + })); + } catch (err) { + this.logger?.warn?.(`local-sqlite: fts search failed, fallback: ${String(err)}`); + } + } + + const clauses: string[] = []; + const values: Array = []; + if (params.userId) { + clauses.push("user_id = ?"); + values.push(params.userId); + } + if (params.agentId) { + clauses.push("agent_id = ?"); + values.push(params.agentId); + } + const where = clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : ""; + const stmt = this.db.prepare(` + SELECT id, remote_id, content, metadata, user_id, agent_id, created_at, updated_at + FROM memories + ${where} + ORDER BY updated_at DESC + LIMIT 500 + `); + const rows = stmt.all(...values) as Array<{ + id: number; + remote_id: string | null; + content: string; + metadata: string | null; + user_id: string | null; + agent_id: string | null; + created_at: string; + updated_at: string; + }>; + + const scored = rows + .map((row) => { + const score = tokenOverlap(tokens, tokenize(row.content)); + return { + id: row.id, + remote_id: row.remote_id, + content: row.content, + metadata: safeJsonParse(row.metadata), + user_id: row.user_id, + agent_id: row.agent_id, + created_at: row.created_at, + updated_at: row.updated_at, + score, + }; + }) + .filter((row) => row.score > 0) + .sort((a, b) => b.score - a.score) + .slice(0, params.limit); + + return scored; + } + + searchVector(params: { + embedding: number[]; + limit: number; + userId?: string; + agentId?: string; + }): Array { + if (!this.vector.enabled || !this.vector.available) { + return []; + } + if (params.embedding.length === 0) { + return []; + } + if (!this.ensureVectorTable(params.embedding.length)) { + return []; + } + const clauses: string[] = []; + const values: Array = []; + if (params.userId) { + clauses.push("m.user_id = ?"); + values.push(params.userId); + } + if (params.agentId) { + clauses.push("m.agent_id = ?"); + values.push(params.agentId); + } + const where = clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : ""; + const stmt = this.db.prepare( + `SELECT m.id, m.remote_id, m.content, m.metadata, m.user_id, m.agent_id, m.created_at, m.updated_at,\n` + + ` vec_distance_cosine(v.embedding, ?) AS dist\n` + + ` FROM ${VECTOR_TABLE} v\n` + + ` JOIN memories m ON m.id = v.rowid\n` + + ` ${where}\n` + + ` ORDER BY dist ASC\n` + + ` LIMIT ?`, + ); + const rows = stmt.all( + vectorToBlob(params.embedding), + ...values, + params.limit, + ) as Array<{ + id: number; + remote_id: string | null; + content: string; + metadata: string | null; + user_id: string | null; + agent_id: string | null; + created_at: string; + updated_at: string; + dist: number; + }>; + return rows.map((row) => ({ + id: row.id, + remote_id: row.remote_id, + content: row.content, + metadata: safeJsonParse(row.metadata), + user_id: row.user_id, + agent_id: row.agent_id, + created_at: row.created_at, + updated_at: row.updated_at, + score: 1 - row.dist, + })); + } + + enqueuePending(params: { + localMemoryId?: number | null; + content: string; + metadata?: Record; + userId?: string; + agentId?: string; + infer: boolean; + }): void { + const stmt = this.db.prepare(` + INSERT INTO pending_writes (local_memory_id, content, metadata, user_id, agent_id, infer, queued_at, retries, next_retry_at, last_error) + VALUES (@local_memory_id, @content, @metadata, @user_id, @agent_id, @infer, @queued_at, 0, @next_retry_at, NULL) + `); + stmt.run({ + local_memory_id: params.localMemoryId ?? null, + content: params.content, + metadata: params.metadata ? JSON.stringify(params.metadata) : null, + user_id: params.userId ?? null, + agent_id: params.agentId ?? null, + infer: params.infer ? 1 : 0, + queued_at: nowIso(), + next_retry_at: nowIso(), + }); + } + + listPending(limit = 200, readyOnly = true): PendingRow[] { + const readyClause = + readyOnly && this.hasNextRetryAt + ? "WHERE next_retry_at IS NULL OR next_retry_at <= ?" + : ""; + const lastErrorCol = this.hasLastError ? "last_error" : "NULL as last_error"; + const stmt = this.db.prepare(` + SELECT id, local_memory_id, content, metadata, user_id, agent_id, infer, queued_at, retries, ${lastErrorCol} + FROM pending_writes + ${readyClause} + ORDER BY id ASC + LIMIT ? + `); + const rows = (readyOnly && this.hasNextRetryAt + ? stmt.all(nowIso(), limit) + : stmt.all(limit)) as Array<{ + id: number; + local_memory_id: number | null; + content: string; + metadata: string | null; + user_id: string | null; + agent_id: string | null; + infer: number; + queued_at: string; + retries: number; + last_error: string | null; + }>; + return rows.map((row) => ({ + id: row.id, + local_memory_id: row.local_memory_id, + content: row.content, + metadata: safeJsonParse(row.metadata), + user_id: row.user_id, + agent_id: row.agent_id, + infer: row.infer !== 0, + queued_at: row.queued_at, + retries: row.retries, + last_error: row.last_error ?? null, + })); + } + + removePending(ids: number[]): void { + if (ids.length === 0) return; + const placeholders = ids.map(() => "?").join(", "); + const stmt = this.db.prepare(`DELETE FROM pending_writes WHERE id IN (${placeholders})`); + stmt.run(...ids); + } + + scheduleRetries(ids: number[], nextRetryAt: string, lastError?: string): void { + if (ids.length === 0) return; + const placeholders = ids.map(() => "?").join(", "); + if (this.hasLastError) { + const stmt = this.db.prepare( + `UPDATE pending_writes SET retries = retries + 1, next_retry_at = ?, last_error = ? WHERE id IN (${placeholders})`, + ); + stmt.run(nextRetryAt, lastError ?? null, ...ids); + return; + } + const stmt = this.db.prepare( + `UPDATE pending_writes SET retries = retries + 1, next_retry_at = ? WHERE id IN (${placeholders})`, + ); + stmt.run(nextRetryAt, ...ids); + } + + pendingCount(): number { + const stmt = this.db.prepare(`SELECT COUNT(*) as count FROM pending_writes`); + const row = stmt.get() as { count: number }; + return row?.count ?? 0; + } + + close(): void { + try { + this.db.close(); + } catch (err) { + this.logger?.warn?.(`local-sqlite: close failed: ${String(err)}`); + } + } +} diff --git a/openclaw-plugin-sdk.d.ts b/src/openclaw-plugin-sdk.d.ts similarity index 100% rename from openclaw-plugin-sdk.d.ts rename to src/openclaw-plugin-sdk.d.ts diff --git a/openclaw-powermem-env.ts b/src/openclaw-powermem-env.ts similarity index 100% rename from openclaw-powermem-env.ts rename to src/openclaw-powermem-env.ts diff --git a/src/resolve-powermem-cli.ts b/src/resolve-powermem-cli.ts new file mode 100644 index 0000000..b3518a7 --- /dev/null +++ b/src/resolve-powermem-cli.ts @@ -0,0 +1,37 @@ +/** + * Resolve the `pmem` executable for CLI mode. + * - `bundled` / `auto` / empty: npm `powermem` next to this plugin if installed, else `pmem` on PATH (e.g. Python). + * - anything else: passed through (absolute path or command name). + */ + +import { existsSync } from "node:fs"; +import { dirname, join } from "node:path"; +import { createRequire } from "node:module"; + +const require = createRequire(import.meta.url); + +/** + * Resolve npm `powermem`'s CLI script. We cannot use `require.resolve("powermem/dist/cli.js")` + * because the published package's `exports` field does not expose that subpath. + */ +export function resolveBundledPowermemCliPath(): string | undefined { + try { + const main = require.resolve("powermem"); + const cli = join(dirname(main), "cli.js"); + return existsSync(cli) ? cli : undefined; + } catch { + return undefined; + } +} + +/** + * @param pmemPath - From config: `auto` | `bundled` | `pmem` | path to binary + */ +export function resolvePmemExecutable(pmemPath: string): string { + const t = pmemPath.trim(); + if (t === "bundled" || t === "auto" || t === "") { + const p = resolveBundledPowermemCliPath(); + return p ?? "pmem"; + } + return t; +} diff --git a/src/wal.ts b/src/wal.ts new file mode 100644 index 0000000..620b4e6 --- /dev/null +++ b/src/wal.ts @@ -0,0 +1,140 @@ +/** + * WAL (Write-Ahead Capture) — Incremental memory capture during conversations. + */ + +export const WAL_EXTRACT_PROMPT = `You are a quick fact extractor. Given a single user message, extract 1-3 key facts worth remembering long-term. + +Rules: +- Keep each fact short and specific. +- Only include stable preferences, decisions, corrections, or commitments. +- Skip greetings, filler, or transient chit-chat. +- Output ONLY valid JSON: {"facts":["fact1","fact2"]}`; + +export const WAL_SIGNAL_PATTERNS = [ + /我(喜欢|偏好|习惯|倾向|prefer|like|always use)/i, + /(就用|决定|选择|不要|不用|let's use|go with|decided)/i, + /(不对|错了|应该是|其实是|actually|correction)/i, + /(deadline|截止|前完成|by tomorrow|due date|下周|明天)/i, + /(i (like|prefer|love|hate|always|never|want to))\b/i, + /(remember that|don't forget|keep in mind|note that)/i, +]; + +export function detectKeySignals(text: string): boolean { + return WAL_SIGNAL_PATTERNS.some((re) => re.test(text)); +} + +export interface WalDeps { + callLlm: (prompt: string, opts: { + systemPrompt: string; + maxTokens: number; + temperature: number; + }) => Promise; + store: (content: string, metadata: Record) => Promise<{ id?: string | number }>; + logger: { + info?: (msg: string) => void; + warn: (msg: string) => void; + }; +} + +export class WalSession { + private readonly cache = new Map>(); + + has(sessionKey: string, fact: string): boolean { + const set = this.cache.get(sessionKey); + return set ? set.has(fact) : false; + } + + add(sessionKey: string, fact: string): void { + const set = this.cache.get(sessionKey) ?? new Set(); + set.add(fact); + this.cache.set(sessionKey, set); + } + + clear(sessionKey: string): void { + this.cache.delete(sessionKey); + } +} + +function stripThinkBlocks(raw: string): string { + return raw.replace(/[\s\S]*?<\/think>/gi, "").trim(); +} + +function normalizeFact(raw: string): string { + return raw.replace(/\s+/g, " ").trim(); +} + +function parseWalFacts(raw: string | null): string[] { + if (!raw) return []; + const cleaned = stripThinkBlocks(raw); + if (!cleaned) return []; + + const attempts = [cleaned]; + const jsonMatch = cleaned.match(/(\{[\s\S]*\}|\[[\s\S]*\])/); + if (jsonMatch && jsonMatch[1] !== cleaned) { + attempts.unshift(jsonMatch[1]); + } + + for (const attempt of attempts) { + try { + const parsed = JSON.parse(attempt); + if (Array.isArray(parsed)) { + return parsed.filter((item) => typeof item === "string").map(normalizeFact); + } + if (parsed && typeof parsed === "object") { + const facts = (parsed as { facts?: unknown }).facts; + if (Array.isArray(facts)) { + return facts.filter((item) => typeof item === "string").map(normalizeFact); + } + } + } catch { + // fall through + } + } + + return cleaned + .split("\n") + .map((line) => line.replace(/^[-*\d.\s]+/, "").trim()) + .filter((line) => line.length > 0) + .map(normalizeFact); +} + +export async function walCapture( + prompt: string, + sessionKey: string, + session: WalSession, + deps: WalDeps, +): Promise> { + if (!detectKeySignals(prompt)) return []; + + const reply = await deps.callLlm(prompt, { + systemPrompt: WAL_EXTRACT_PROMPT, + maxTokens: 512, + temperature: 0.1, + }); + const facts = parseWalFacts(reply) + .map(normalizeFact) + .filter((fact) => fact.length >= 8) + .slice(0, 3) + .filter((fact) => !session.has(sessionKey, fact)); + + if (facts.length === 0) return []; + + const storedIds: Array = []; + for (const fact of facts) { + try { + const result = await deps.store(fact, { + source: "wal", + session: sessionKey, + }); + if (result?.id !== undefined) { + storedIds.push(result.id); + } + session.add(sessionKey, fact); + } catch (err) { + deps.logger.warn(`memory-powermem: wal capture failed: ${String(err)}`); + } + } + + deps.logger.info?.(`memory-powermem: wal captured ${storedIds.length} fact(s)`); + return storedIds; +} diff --git a/test/cli-json.test.ts b/test/cli-json.test.ts new file mode 100644 index 0000000..ea32ebc --- /dev/null +++ b/test/cli-json.test.ts @@ -0,0 +1,45 @@ +/** + * CLI stdout JSON shapes: Python pmem vs powermem-ts. + */ +import { describe, it, expect } from "vitest"; +import { normalizeAddOutput, normalizeSearchOutput } from "../src/client-cli.js"; + +describe("normalizeAddOutput", () => { + it("parses powermem-ts AddResult wrapper with memories + memoryId", () => { + const raw = { + message: "ok", + memories: [ + { + memoryId: "snowflake-1", + content: "User prefers dark mode", + userId: "u1", + }, + ], + }; + const out = normalizeAddOutput(raw); + expect(out).toHaveLength(1); + expect(out[0].content).toBe("User prefers dark mode"); + expect(String(out[0].memory_id)).toBe("snowflake-1"); + }); + + it("parses legacy array of rows", () => { + const raw = [{ memory_id: 42, content: "x" }]; + expect(normalizeAddOutput(raw)[0].memory_id).toBe(42); + }); +}); + +describe("normalizeSearchOutput", () => { + it("parses powermem-ts SearchResult with camelCase memoryId", () => { + const raw = { + results: [ + { memoryId: "id-9", content: "coffee", score: 0.9 }, + ], + total: 1, + query: "x", + }; + const out = normalizeSearchOutput(raw); + expect(out).toHaveLength(1); + expect(String(out[0].memory_id)).toBe("id-9"); + expect(out[0].score).toBeCloseTo(0.9); + }); +}); diff --git a/test/client-v2.test.ts b/test/client-v2.test.ts new file mode 100644 index 0000000..a589e08 --- /dev/null +++ b/test/client-v2.test.ts @@ -0,0 +1,97 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import { PowerMemV2Client } from "../src/client-v2.js"; + +describe("PowerMemV2Client", () => { + afterEach(() => { + vi.unstubAllGlobals(); + vi.restoreAllMocks(); + }); + + it("adds request config and api key headers", async () => { + const fetchMock = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { + const url = typeof input === "string" ? input : input.toString(); + expect(url).toBe("http://localhost:8000/api/v2/memories"); + expect(init?.method).toBe("POST"); + const headers = init?.headers as Record; + expect(headers["X-API-Key"]).toBe("sk-test"); + const body = JSON.parse(String(init?.body ?? "{}")) as Record; + expect(body.config).toEqual({ memory_db: { host: "db.local" } }); + return new Response( + JSON.stringify({ + success: true, + data: [{ id: "m-1", content: "hello" }], + }), + { status: 200 }, + ); + }); + vi.stubGlobal("fetch", fetchMock); + + const client = new PowerMemV2Client({ + baseUrl: "http://localhost:8000", + apiKey: "sk-test", + userId: "u-1", + agentId: "a-1", + requestConfig: { memory_db: { host: "db.local" } }, + }); + const res = await client.add("hello"); + expect(res).toHaveLength(1); + expect(res[0].memory_id).toBe("m-1"); + }); + + it("sends search payload with config", async () => { + const fetchMock = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { + const url = typeof input === "string" ? input : input.toString(); + expect(url).toBe("http://localhost:8000/api/v2/memories/search"); + expect(init?.method).toBe("POST"); + const body = JSON.parse(String(init?.body ?? "{}")) as Record; + expect(body).toMatchObject({ + query: "dark mode", + user_id: "u-1", + agent_id: "a-1", + limit: 3, + config: { vector: "on" }, + }); + return new Response( + JSON.stringify({ + success: true, + data: { results: [{ memory_id: 99, content: "prefers dark mode", score: 0.8 }] }, + }), + { status: 200 }, + ); + }); + vi.stubGlobal("fetch", fetchMock); + + const client = new PowerMemV2Client({ + baseUrl: "http://localhost:8000", + userId: "u-1", + agentId: "a-1", + requestConfig: { vector: "on" }, + }); + const res = await client.search("dark mode", 3); + expect(res[0].memory_id).toBe("99"); + }); + + it("posts delete request with config", async () => { + const fetchMock = vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { + const url = typeof input === "string" ? input : input.toString(); + expect(url).toBe("http://localhost:8000/api/v2/memories/delete/m-9"); + expect(init?.method).toBe("POST"); + const body = JSON.parse(String(init?.body ?? "{}")) as Record; + expect(body).toMatchObject({ + user_id: "u-9", + agent_id: "a-9", + config: { memory_db: { host: "db" } }, + }); + return new Response("", { status: 200 }); + }); + vi.stubGlobal("fetch", fetchMock); + + const client = new PowerMemV2Client({ + baseUrl: "http://localhost:8000", + userId: "u-9", + agentId: "a-9", + requestConfig: { memory_db: { host: "db" } }, + }); + await client.delete("m-9"); + }); +}); diff --git a/test/config.test.ts b/test/config.test.ts index d76284a..af91962 100644 --- a/test/config.test.ts +++ b/test/config.test.ts @@ -10,7 +10,7 @@ import { DEFAULT_AGENT_ID, DEFAULT_PLUGIN_CONFIG, type PowerMemConfig, -} from "../config.js"; +} from "../src/config.js"; describe("powerMemConfigSchema", () => { it("parses valid http config with required fields", () => { @@ -39,7 +39,7 @@ describe("powerMemConfigSchema", () => { inferOnAdd: false, }) as PowerMemConfig; expect(cfg.mode).toBe("cli"); - expect(cfg.pmemPath).toBe("pmem"); + expect(cfg.pmemPath).toBe("bundled"); }); it("infers http when mode omitted but baseUrl is set", () => { @@ -67,6 +67,7 @@ describe("powerMemConfigSchema", () => { expect(DEFAULT_PLUGIN_CONFIG.mode).toBe("cli"); expect(DEFAULT_PLUGIN_CONFIG.baseUrl).toBe(""); expect(DEFAULT_PLUGIN_CONFIG.envFile).toBeUndefined(); + expect(DEFAULT_PLUGIN_CONFIG.pmemPath).toBe("bundled"); expect(DEFAULT_PLUGIN_CONFIG.useOpenClawModel).toBe(true); }); diff --git a/test/dual-write-client.test.ts b/test/dual-write-client.test.ts new file mode 100644 index 0000000..94f34cc --- /dev/null +++ b/test/dual-write-client.test.ts @@ -0,0 +1,95 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; +import { mkdtempSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { DualWriteClient } from "../src/dual-write-client.js"; +import { LocalSqliteStore } from "../src/local-sqlite.js"; + +type StoreHandle = { + store: LocalSqliteStore; +}; + +function createStore(): StoreHandle { + const dir = mkdtempSync(join(tmpdir(), "powermem-dual-")); + const dbPath = join(dir, "dual.sqlite"); + return { store: new LocalSqliteStore(dbPath) }; +} + +describe("DualWriteClient", () => { + let handle: StoreHandle | null = null; + + afterEach(() => { + handle?.store.close(); + handle = null; + }); + + it("queues local writes when remote fails and syncs later", async () => { + handle = createStore(); + const remote = { + health: vi.fn(async () => ({ status: "healthy" })), + add: vi + .fn() + .mockRejectedValueOnce(new Error("down")) + .mockResolvedValueOnce([ + { memory_id: "r-1", content: "remember me", user_id: "u-1", agent_id: "a-1" }, + ]), + search: vi.fn(), + delete: vi.fn(), + }; + const client = new DualWriteClient(remote, handle.store, { + localUserId: "u-1", + localAgentId: "a-1", + syncOnResume: true, + syncBatchSize: 10, + syncMinIntervalMs: 0, + syncBaseDelayMs: 1, + syncMaxDelayMs: 100, + syncMaxRetries: 3, + }); + + const created = await client.add("remember me", { infer: true }); + expect(created[0].memory_id).toBeDefined(); + expect(handle.store.pendingCount()).toBe(1); + + await client.syncPending("test"); + expect(handle.store.pendingCount()).toBe(0); + + const rows = handle.store.search({ + query: "remember me", + limit: 5, + userId: "u-1", + agentId: "a-1", + }); + expect(rows[0]?.remote_id).toBe("r-1"); + }); + + it("falls back to local search when remote fails", async () => { + handle = createStore(); + handle.store.addLocalMemory({ + content: "local only", + userId: "u-2", + agentId: "a-2", + }); + const remote = { + health: vi.fn(async () => ({ status: "healthy" })), + add: vi.fn(), + search: vi.fn(async () => { + throw new Error("remote down"); + }), + delete: vi.fn(), + }; + const client = new DualWriteClient(remote, handle.store, { + localUserId: "u-2", + localAgentId: "a-2", + syncOnResume: true, + syncBatchSize: 10, + syncMinIntervalMs: 0, + syncBaseDelayMs: 1, + syncMaxDelayMs: 100, + syncMaxRetries: 3, + }); + + const results = await client.search("local only", 5); + expect(results[0]?.content).toBe("local only"); + }); +}); diff --git a/test/local-sqlite.test.ts b/test/local-sqlite.test.ts new file mode 100644 index 0000000..4556edf --- /dev/null +++ b/test/local-sqlite.test.ts @@ -0,0 +1,88 @@ +import { afterEach, describe, expect, it } from "vitest"; +import { mkdtempSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { LocalSqliteStore } from "../src/local-sqlite.js"; + +type StoreHandle = { + store: LocalSqliteStore; +}; + +function createStore(): StoreHandle { + const dir = mkdtempSync(join(tmpdir(), "powermem-local-")); + const dbPath = join(dir, "memories.sqlite"); + return { store: new LocalSqliteStore(dbPath) }; +} + +describe("LocalSqliteStore", () => { + let handle: StoreHandle | null = null; + + afterEach(() => { + handle?.store.close(); + handle = null; + }); + + it("stores and searches local memories", () => { + handle = createStore(); + const id = handle.store.addLocalMemory({ + content: "User prefers dark mode", + metadata: { importance: 0.7 }, + userId: "u-1", + agentId: "a-1", + }); + expect(id).toBeGreaterThan(0); + const rows = handle.store.search({ + query: "dark mode", + limit: 5, + userId: "u-1", + agentId: "a-1", + }); + expect(rows[0]?.content).toBe("User prefers dark mode"); + }); + + it("upserts remote memory by remote_id", () => { + handle = createStore(); + handle.store.upsertRemoteMemory({ + remoteId: "r-1", + content: "Initial content", + metadata: { source: "remote" }, + userId: "u-2", + agentId: "a-2", + }); + handle.store.upsertRemoteMemory({ + remoteId: "r-1", + content: "Updated content", + metadata: { source: "remote" }, + userId: "u-2", + agentId: "a-2", + }); + const rows = handle.store.search({ + query: "Updated content", + limit: 5, + userId: "u-2", + agentId: "a-2", + }); + expect(rows[0]?.remote_id).toBe("r-1"); + expect(rows[0]?.content).toBe("Updated content"); + }); + + it("tracks pending queue retries", () => { + handle = createStore(); + handle.store.enqueuePending({ + localMemoryId: 1, + content: "Queue me", + metadata: { source: "local" }, + userId: "u-3", + agentId: "a-3", + infer: true, + }); + const pending = handle.store.listPending(10, false); + expect(pending).toHaveLength(1); + const id = pending[0].id; + handle.store.scheduleRetries([id], new Date(Date.now() + 1000).toISOString()); + const retry = handle.store.listPending(10, false); + expect(retry[0].retries).toBe(1); + handle.store.removePending([id]); + expect(handle.store.pendingCount()).toBe(0); + }); +}); diff --git a/test/openclaw-powermem-env.test.ts b/test/openclaw-powermem-env.test.ts index b92c0be..8880950 100644 --- a/test/openclaw-powermem-env.test.ts +++ b/test/openclaw-powermem-env.test.ts @@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest"; import { buildDefaultSqlitePowermemEnv, buildPowermemCliProcessEnv, -} from "../openclaw-powermem-env.js"; +} from "../src/openclaw-powermem-env.js"; describe("buildDefaultSqlitePowermemEnv", () => { it("sets sqlite under state dir", () => { diff --git a/test/resolve-powermem-cli.test.ts b/test/resolve-powermem-cli.test.ts new file mode 100644 index 0000000..1a519d2 --- /dev/null +++ b/test/resolve-powermem-cli.test.ts @@ -0,0 +1,25 @@ +import { describe, it, expect } from "vitest"; +import { + resolvePmemExecutable, + resolveBundledPowermemCliPath, +} from "../src/resolve-powermem-cli.js"; + +describe("resolvePmemExecutable", () => { + it("auto prefers bundled path when powermem is installed", () => { + const bundled = resolveBundledPowermemCliPath(); + const exe = resolvePmemExecutable("auto"); + if (bundled) { + expect(exe).toBe(bundled); + } else { + expect(exe).toBe("pmem"); + } + }); + + it("pmem passes through", () => { + expect(resolvePmemExecutable("pmem")).toBe("pmem"); + }); + + it("bundled uses the same resolution as auto", () => { + expect(resolvePmemExecutable("bundled")).toBe(resolvePmemExecutable("auto")); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index d6a85f1..c366966 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,6 @@ "isolatedModules": true, "types": ["node", "vitest/globals"] }, - "include": ["*.ts", "openclaw-plugin-sdk.d.ts", "test/**/*.ts"], + "include": ["src/**/*.ts", "src/**/*.d.ts", "test/**/*.ts"], "exclude": ["node_modules"] }