diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50b907db..eb787919 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,63 @@ env: RUST_BACKTRACE: 1 jobs: + sdk-typescript: + name: TypeScript SDK + runs-on: ubuntu-latest + defaults: + run: + working-directory: sdks/typescript + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: npm + cache-dependency-path: sdks/typescript/package-lock.json + + - run: npm ci + - run: npm test -- --runInBand + - run: npm run build + - run: npm pack --dry-run + + sdk-python: + name: Python SDK + runs-on: ubuntu-latest + defaults: + run: + working-directory: sdks/python + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + cache-dependency-path: sdks/python/pyproject.toml + + - run: python -m pip install --upgrade build twine + - run: python -m pip install -e '.[dev]' + - run: pytest + - run: python -m build + - run: python -m twine check dist/* + + mcp-bridge: + name: MCP bridge package + runs-on: ubuntu-latest + defaults: + run: + working-directory: mcp-bridge + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: "20" + + - run: npm test + - run: npm pack --dry-run + test: name: Test runs-on: ubuntu-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0574987a..7d862e38 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,12 +3,37 @@ name: Release on: push: tags: - - 'v*' + - "v*" jobs: + validate-release: + name: Validate release versions + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Verify package versions match the tag + run: | + EXPECTED_VERSION="${GITHUB_REF_NAME#v}" + test "$(node -p "require('./sdks/typescript/package.json').version")" = "$EXPECTED_VERSION" + test "$(node -p "require('./mcp-bridge/package.json').version")" = "$EXPECTED_VERSION" + python - <<'PY' + import os + import pathlib + import tomllib + + expected = os.environ["GITHUB_REF_NAME"].removeprefix("v") + root = pathlib.Path(".") + with (root / "sdks/python/pyproject.toml").open("rb") as handle: + assert tomllib.load(handle)["project"]["version"] == expected + with (root / "Cargo.toml").open("rb") as handle: + assert tomllib.load(handle)["workspace"]["package"]["version"] == expected + PY + build: name: Build ${{ matrix.target }} runs-on: ${{ matrix.os }} + needs: validate-release permissions: contents: read @@ -185,13 +210,13 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.12' + python-version: "3.12" - name: Install build tools run: pip install hatch twine - name: Build and publish - run: cd sdks/python && hatch build && twine upload dist/* + run: cd sdks/python && hatch build && twine check dist/* && twine upload dist/* env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} @@ -200,17 +225,20 @@ jobs: name: Publish to npm runs-on: ubuntu-latest needs: github-release + permissions: + contents: read + id-token: write steps: - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: - node-version: '20' - registry-url: 'https://registry.npmjs.org' + node-version: "20" + registry-url: "https://registry.npmjs.org" - name: Build and publish - run: cd sdks/typescript && npm ci && npm run build && npm publish --access public + run: cd sdks/typescript && npm ci && npm run build && npm publish --access public --provenance env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} @@ -218,6 +246,9 @@ jobs: name: Publish MCP bridge to npm runs-on: ubuntu-latest needs: github-release + permissions: + contents: read + id-token: write steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -226,6 +257,6 @@ jobs: registry-url: https://registry.npmjs.org - name: Publish working-directory: mcp-bridge - run: npm publish --access public + run: npm publish --access public --provenance env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index 0542f173..5646c99a 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,8 @@ Thumbs.db .fastembed_cache/ node_modules/ **/node_modules/ +sdks/typescript/dist/ +sdks/python/dist/ # Python / macOS / DB files __pycache__/ diff --git a/CHANGELOG.md b/CHANGELOG.md index b1877a51..d0e1c63d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,26 @@ All notable changes to Cortex are documented in this file. +## [0.3.2] - 2026-08-02 + +### Added + +- Public `cortex-memory-client` packages for the TypeScript and Python SDKs. +- Complete npm documentation and metadata for `cortex-mcp-bridge`. +- SDK build, test, and package validation in CI. + +### Fixed + +- Replaced the unavailable TypeScript scope and the conflicting Python + distribution name with the shared `cortex-memory-client` name. +- Corrected the MCP bridge's default Cortex HTTP port from `19091` to `9091`. +- Updated active examples and documentation so installation commands resolve to + Cortex-owned packages. + ## [0.3.1] - 2026-03-21 ### Added + - **GitHub templates** -- Bug report, feature request, and PR templates for community contributions. - **MCP quickstart guide** -- Step-by-step guide for connecting AI agents to @@ -13,6 +30,7 @@ All notable changes to Cortex are documented in this file. ## [0.3.0] - 2026-03-19 ### Added + - **Temporal validity** -- Node fields: `valid_from`, `valid_until` for truth windows. Query with `valid_at()` filter. - **Lifecycle expiry** -- Node field: `expires_at`. Retention engine auto-sweeps @@ -38,6 +56,7 @@ All notable changes to Cortex are documented in this file. interoperability (`entity_type`, `aliases`, `parent_agent`, `task_id`, etc). ### Changed + - Briefing engine uses role-based config instead of hardcoded section kinds. - Auto-linker supports entity co-occurrence and entity promotion. - Retention engine respects `expires_at` field. @@ -46,12 +65,14 @@ All notable changes to Cortex are documented in this file. ## [0.2.0] - 2026-03-14 ### Added + - **Mutation Hooks** — `MutationHook` trait + `HookRegistry` for node/edge write callbacks. Register hooks to be notified on every create, update, or delete. - **SSE Event Stream** — `GET /events/stream` with optional `?events=` filter for real-time graph change notifications. Supports `node.created`, `node.updated`, `node.deleted`, `edge.created`, `edge.updated`, `edge.deleted`. - **Query DSL** — String filter expressions compiled to `NodeFilter`: `kind:decision AND importance>0.7`, `(kind:fact OR kind:pattern) AND tags:architecture`. - **Schema Validation** — Per-kind metadata schemas in `[schemas.*]` config. Define required fields, types, ranges, and allowed values. Validated at write time via the write gate. ### Changed + - Write gate now runs 4 checks: substance, specificity, conflict, schema. - HTTP write endpoints now fire mutation hooks (previously gRPC-only). This means SSE events are emitted for all write paths. - Schema validation is enforced in both HTTP and gRPC write handlers. @@ -59,6 +80,7 @@ All notable changes to Cortex are documented in this file. - Panicking hooks are isolated via `catch_unwind` to prevent one bad hook from crashing the write path. ### Fixed + - HTTP-created nodes now fire mutation hooks (were silently skipped before). - Schema validation was defined but not wired into any server write path. diff --git a/CLAUDE.md b/CLAUDE.md index 768a6fd3..de7a9b82 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -14,8 +14,8 @@ crates/ cortex-proto/ — Protobuf definitions + generated code. warren-adapter/ — Optional Warren integration (feature-gated). sdks/ - typescript/ — @cortex/client npm package - python/ — cortex-memory PyPI package + typescript/ — cortex-memory-client npm package + python/ — cortex-memory-client PyPI package (`cortex_memory` import) go/ — Go client module specs/ — Design specs (tagged IMPLEMENTED/DEFERRED) docs/ — User-facing documentation @@ -108,6 +108,7 @@ The `test_node_schema_golden` test in `redb_storage.rs` will fail immediately if format changes without these steps being followed. **Fields added in evolution (specs 09-10):** + - Node: `valid_from`, `valid_until`, `expires_at`, `embedding_model` (all Option, serde default None) - Edge: `metadata` (HashMap, serde default empty) - EdgeProvenance: `Custom { kind, detail }` variant @@ -137,6 +138,7 @@ The native MCP server is in `crates/cortex-server/src/mcp/mod.rs`. It implements 7 tools via stdio JSON-RPC transport. The MCP server runs in two modes: + - **Library mode** (default): opens the redb database directly. Fastest. - **Proxy mode** (`--server`): connects to a running gRPC server. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 56714a36..a5b30c15 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -39,8 +39,8 @@ crates/ warren-adapter/ Warren NATS adapter (internal) sdks/ - python/ Python SDK (cortex-memory on PyPI) - typescript/ TypeScript SDK (@cortex-memory/client on npm) + python/ Python SDK (cortex-memory-client on PyPI) + typescript/ TypeScript SDK (cortex-memory-client on npm) go/ Go SDK specs/ Phase specifications @@ -69,4 +69,4 @@ Use GitHub Issues for bugs and feature requests. For questions, use GitHub Discu ## Releasing -Releases are tagged with `vX.Y.Z`. The CI pipeline publishes to crates.io and Docker Hub automatically on tag push. +Releases are tagged with `vX.Y.Z`. The release pipeline publishes the Rust crates, Python and TypeScript SDKs, MCP bridge, binaries, and Docker image automatically on tag push. diff --git a/Cargo.lock b/Cargo.lock index c2174401..7294e7f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -735,7 +735,7 @@ dependencies = [ [[package]] name = "cortex-memory" -version = "0.3.1" +version = "0.3.2" dependencies = [ "anyhow", "async-nats", @@ -779,7 +779,7 @@ dependencies = [ [[package]] name = "cortex-memory-client" -version = "0.3.1" +version = "0.3.2" dependencies = [ "anyhow", "cortex-memory-proto", @@ -789,7 +789,7 @@ dependencies = [ [[package]] name = "cortex-memory-core" -version = "0.3.1" +version = "0.3.2" dependencies = [ "aes-gcm", "anyhow", @@ -817,7 +817,7 @@ dependencies = [ [[package]] name = "cortex-memory-proto" -version = "0.3.1" +version = "0.3.2" dependencies = [ "prost", "prost-types", @@ -4775,7 +4775,7 @@ dependencies = [ [[package]] name = "warren-adapter" -version = "0.3.1" +version = "0.3.2" dependencies = [ "async-nats", "cortex-memory-core", diff --git a/Cargo.toml b/Cargo.toml index a6e75083..88692e82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ members = [ ] [workspace.package] -version = "0.3.1" +version = "0.3.2" edition = "2021" authors = ["Mike Darlington"] license = "MIT" @@ -77,4 +77,3 @@ proptest = "1.6" criterion = "0.5" - diff --git a/README.md b/README.md index 3ff122df..9ed2d108 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,9 @@ [![CI](https://github.com/MikeSquared-Agency/cortex/actions/workflows/ci.yml/badge.svg)](https://github.com/MikeSquared-Agency/cortex/actions/workflows/ci.yml) [![Release](https://img.shields.io/github/v/release/MikeSquared-Agency/cortex)](https://github.com/MikeSquared-Agency/cortex/releases/latest) [![crates.io](https://img.shields.io/crates/v/cortex-memory.svg)](https://crates.io/crates/cortex-memory) -[![PyPI](https://img.shields.io/pypi/v/cortex-memory.svg)](https://pypi.org/project/cortex-memory/) -[![npm](https://img.shields.io/npm/v/@cortex-memory/client.svg)](https://www.npmjs.com/package/@cortex-memory/client) +[![PyPI](https://img.shields.io/pypi/v/cortex-memory-client.svg)](https://pypi.org/project/cortex-memory-client/) +[![npm SDK](https://img.shields.io/npm/v/cortex-memory-client.svg)](https://www.npmjs.com/package/cortex-memory-client) +[![npm MCP](https://img.shields.io/npm/v/cortex-mcp-bridge.svg)](https://www.npmjs.com/package/cortex-mcp-bridge) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) **Self-organizing graph memory for AI agents. One binary. Zero dependencies.** @@ -137,7 +138,8 @@ Add to `.vscode/mcp.json`: ### Without installing the binary -Use the Node.js bridge (no Rust needed): +Use the Node.js bridge with a running local or remote Cortex HTTP server. The +bridge itself does not require Rust: ```bash npx cortex-mcp-bridge @@ -159,17 +161,36 @@ Or with a remote Cortex server: } ``` +### Client SDKs + +Connect applications to the Cortex gRPC server using the language-native +clients: + +```bash +# TypeScript / Node.js +npm install cortex-memory-client + +# Python (distribution name; imports remain `cortex_memory`) +pip install cortex-memory-client + +# Go +go get github.com/MikeSquared-Agency/cortex/sdks/go + +# Rust +cargo add cortex-memory-client +``` + ### What your agent gets -| Tool | Purpose | -|------|---------| -| `cortex_store` | Remember facts, decisions, goals, events, patterns | -| `cortex_search` | Semantic search by meaning | -| `cortex_recall` | Hybrid search (semantic + graph structure) | -| `cortex_briefing` | "What do I need to know?" context document | -| `cortex_traverse` | Explore how concepts connect in the graph | -| `cortex_relate` | Explicitly link related knowledge | -| `cortex_observe` | Record performance metrics for prompt selection | +| Tool | Purpose | +| ----------------- | -------------------------------------------------- | +| `cortex_store` | Remember facts, decisions, goals, events, patterns | +| `cortex_search` | Semantic search by meaning | +| `cortex_recall` | Hybrid search (semantic + graph structure) | +| `cortex_briefing` | "What do I need to know?" context document | +| `cortex_traverse` | Explore how concepts connect in the graph | +| `cortex_relate` | Explicitly link related knowledge | +| `cortex_observe` | Record performance metrics for prompt selection | The briefing tool supports scope: `agent` (default), `shared` (cross-agent), or `unified` (multi-agent overview for orchestrators). @@ -205,6 +226,9 @@ cortex prompt performance my-prompt ### As a Library (Python) +Install the Python distribution with `pip install cortex-memory-client`, then +import its stable `cortex_memory` module: + ```python from cortex_memory import Cortex @@ -263,21 +287,21 @@ let results = cx.search("authentication", 5)?; ## How Cortex Compares -| | Cortex | Mem0 | Zep/Graphiti | Cognee | Letta | Engram | -|---|---|---|---|---|---|---| -| Embedded (no server) | Yes | No | No | No | No | Yes | -| Self-organizing graph | Yes | No | Partial | Partial | No | No | -| Auto-linking | Yes | No | No | No | No | No | -| Temporal validity | Yes | No | Yes | No | No | No | -| Knowledge decay | Yes | No | No | Partial | No | Yes | -| Contradiction detection | Yes | No | Yes | No | No | No | -| Trust from topology | Yes | No | No | No | No | No | -| Briefing synthesis | Yes | No | No | No | No | No | -| Entity resolution | Yes | Yes | Yes | Yes | No | No | -| Cross-agent discovery | Yes | Yes | No | Yes | No | No | -| Single binary | Yes | No | No | No | No | Yes | -| Rust (performance) | Yes | No | No | No | No | No (Go) | -| Open source (MIT) | Yes | Partial | Partial | Yes | Yes | Yes | +| | Cortex | Mem0 | Zep/Graphiti | Cognee | Letta | Engram | +| ----------------------- | ------ | ------- | ------------ | ------- | ----- | ------- | +| Embedded (no server) | Yes | No | No | No | No | Yes | +| Self-organizing graph | Yes | No | Partial | Partial | No | No | +| Auto-linking | Yes | No | No | No | No | No | +| Temporal validity | Yes | No | Yes | No | No | No | +| Knowledge decay | Yes | No | No | Partial | No | Yes | +| Contradiction detection | Yes | No | Yes | No | No | No | +| Trust from topology | Yes | No | No | No | No | No | +| Briefing synthesis | Yes | No | No | No | No | No | +| Entity resolution | Yes | Yes | Yes | Yes | No | No | +| Cross-agent discovery | Yes | Yes | No | Yes | No | No | +| Single binary | Yes | No | No | No | No | Yes | +| Rust (performance) | Yes | No | No | No | No | No (Go) | +| Open source (MIT) | Yes | Partial | Partial | Yes | Yes | Yes | Cortex occupies a unique position: embedded AND self-organizing. Every competitor requires external infrastructure or manual curation. Cortex does neither. diff --git a/crates/cortex-client/Cargo.toml b/crates/cortex-client/Cargo.toml index 06160c0d..5713079b 100644 --- a/crates/cortex-client/Cargo.toml +++ b/crates/cortex-client/Cargo.toml @@ -8,7 +8,7 @@ description = "Rust client for the Cortex graph memory engine" repository = "https://github.com/MikeSquared-Agency/cortex" [dependencies] -cortex-proto = { path = "../cortex-proto", package = "cortex-memory-proto", version = "0.3.1" } +cortex-proto = { path = "../cortex-proto", package = "cortex-memory-proto", version = "0.3.2" } tonic.workspace = true tokio.workspace = true anyhow.workspace = true diff --git a/crates/cortex-core/src/graph/engine.rs b/crates/cortex-core/src/graph/engine.rs index 4a4f9cd0..56784ab0 100644 --- a/crates/cortex-core/src/graph/engine.rs +++ b/crates/cortex-core/src/graph/engine.rs @@ -319,7 +319,7 @@ impl GraphEngine for GraphEngineImpl { } // Sort by degree descending - node_degrees.sort_by(|a, b| b.1.cmp(&a.1)); + node_degrees.sort_by_key(|entry| std::cmp::Reverse(entry.1)); // Take top N Ok(node_degrees.into_iter().take(limit).collect()) diff --git a/crates/cortex-core/src/graph/temporal.rs b/crates/cortex-core/src/graph/temporal.rs index e86a157a..2ce8d855 100644 --- a/crates/cortex-core/src/graph/temporal.rs +++ b/crates/cortex-core/src/graph/temporal.rs @@ -47,7 +47,7 @@ impl TemporalQueries for TemporalQueriesImpl { .collect(); // Sort by updated_at ascending (oldest changes first) - nodes.sort_by(|a, b| a.updated_at.cmp(&b.updated_at)); + nodes.sort_by_key(|node| node.updated_at); Ok(nodes) } @@ -137,7 +137,7 @@ impl TemporalQueries for TemporalQueriesImpl { let mut nodes = self.storage.list_nodes(filter)?; // Sort by created_at - nodes.sort_by(|a, b| a.created_at.cmp(&b.created_at)); + nodes.sort_by_key(|node| node.created_at); Ok(nodes) } diff --git a/crates/cortex-core/src/linker/auto_linker.rs b/crates/cortex-core/src/linker/auto_linker.rs index 0aba4deb..a867a3bd 100644 --- a/crates/cortex-core/src/linker/auto_linker.rs +++ b/crates/cortex-core/src/linker/auto_linker.rs @@ -490,6 +490,30 @@ mod tests { use std::sync::Arc; use tempfile::TempDir; + #[derive(Clone)] + struct NoopEmbedder; + + impl EmbeddingService for NoopEmbedder { + fn embed(&self, _text: &str) -> crate::error::Result { + Ok(vec![0.0; 384]) + } + + fn embed_batch( + &self, + texts: &[String], + ) -> crate::error::Result> { + Ok(texts.iter().map(|_| vec![0.0; 384]).collect()) + } + + fn dimension(&self) -> usize { + 384 + } + + fn model_name(&self) -> &str { + "noop" + } + } + #[test] #[ignore] // Requires embedding model fn test_auto_linker_cycle() { @@ -560,7 +584,7 @@ mod tests { let db_path = temp_dir.path().join("cursor_test.redb"); let storage = Arc::new(RedbStorage::open(&db_path).unwrap()); - let embedding_service = Arc::new(FastEmbedService::new().unwrap()); + let embedding_service = Arc::new(NoopEmbedder); let vector_index = Arc::new(RwLock::new(HnswIndex::new(384))); let graph_engine = Arc::new(GraphEngineImpl::new(storage.clone())); @@ -602,7 +626,7 @@ mod tests { let db_path = temp_dir.path().join("config_change_test.redb"); let storage = Arc::new(RedbStorage::open(&db_path).unwrap()); - let embedding_service = Arc::new(FastEmbedService::new().unwrap()); + let embedding_service = Arc::new(NoopEmbedder); let vector_index = Arc::new(RwLock::new(HnswIndex::new(384))); let graph_engine = Arc::new(GraphEngineImpl::new(storage.clone())); @@ -657,7 +681,7 @@ mod tests { let db_path = temp_dir.path().join("no_config_change_test.redb"); let storage = Arc::new(RedbStorage::open(&db_path).unwrap()); - let embedding_service = Arc::new(FastEmbedService::new().unwrap()); + let embedding_service = Arc::new(NoopEmbedder); let vector_index = Arc::new(RwLock::new(HnswIndex::new(384))); let graph_engine = Arc::new(GraphEngineImpl::new(storage.clone())); @@ -706,7 +730,7 @@ mod tests { let db_path = temp_dir.path().join("model_change_test.redb"); let storage = Arc::new(RedbStorage::open(&db_path).unwrap()); - let embedding_service = Arc::new(FastEmbedService::new().unwrap()); + let embedding_service = Arc::new(NoopEmbedder); let vector_index = Arc::new(RwLock::new(HnswIndex::new(384))); let graph_engine = Arc::new(GraphEngineImpl::new(storage.clone())); diff --git a/crates/cortex-core/src/linker/config.rs b/crates/cortex-core/src/linker/config.rs index 676812b6..49c25d3f 100644 --- a/crates/cortex-core/src/linker/config.rs +++ b/crates/cortex-core/src/linker/config.rs @@ -505,13 +505,11 @@ impl RuleCondition { ))); } } - Self::TagReferencesTitle { tag_prefix } => { - if tag_prefix.is_empty() { - return Err(CortexError::Validation(format!( - "Rule '{}' tag_prefix cannot be empty", - rule_name - ))); - } + Self::TagReferencesTitle { tag_prefix } if tag_prefix.is_empty() => { + return Err(CortexError::Validation(format!( + "Rule '{}' tag_prefix cannot be empty", + rule_name + ))); } _ => {} } diff --git a/crates/cortex-core/src/prompt/rollback.rs b/crates/cortex-core/src/prompt/rollback.rs index e9595599..1216fedb 100644 --- a/crates/cortex-core/src/prompt/rollback.rs +++ b/crates/cortex-core/src/prompt/rollback.rs @@ -747,7 +747,7 @@ impl RollbackMonitor { .unwrap_or(false) }) .collect(); - events.sort_by(|a, b| b.created_at.cmp(&a.created_at)); + events.sort_by_key(|event| std::cmp::Reverse(event.created_at)); Ok(events) } diff --git a/crates/cortex-core/src/storage/redb_storage.rs b/crates/cortex-core/src/storage/redb_storage.rs index 99ab72ab..16e0b502 100644 --- a/crates/cortex-core/src/storage/redb_storage.rs +++ b/crates/cortex-core/src/storage/redb_storage.rs @@ -759,7 +759,7 @@ impl Storage for RedbStorage { } // Sort by created_at descending (newest first) - nodes.sort_by(|a, b| b.created_at.cmp(&a.created_at)); + nodes.sort_by_key(|node| std::cmp::Reverse(node.created_at)); // Apply offset and limit let start = filter.offset.unwrap_or(0); diff --git a/crates/cortex-server/Cargo.toml b/crates/cortex-server/Cargo.toml index 08e92715..e90b8e96 100644 --- a/crates/cortex-server/Cargo.toml +++ b/crates/cortex-server/Cargo.toml @@ -22,9 +22,9 @@ default = [] [dependencies] # Local crates -cortex-core = { path = "../cortex-core", package = "cortex-memory-core", version = "0.3.1" } -cortex-client = { path = "../cortex-client", package = "cortex-memory-client", version = "0.3.1" } -cortex-proto = { path = "../cortex-proto", package = "cortex-memory-proto", version = "0.3.1" } +cortex-core = { path = "../cortex-core", package = "cortex-memory-core", version = "0.3.2" } +cortex-client = { path = "../cortex-client", package = "cortex-memory-client", version = "0.3.2" } +cortex-proto = { path = "../cortex-proto", package = "cortex-memory-proto", version = "0.3.2" } # gRPC/HTTP tonic.workspace = true diff --git a/crates/cortex-server/src/http/selection.rs b/crates/cortex-server/src/http/selection.rs index 97d9d52c..78fa3a47 100644 --- a/crates/cortex-server/src/http/selection.rs +++ b/crates/cortex-server/src/http/selection.rs @@ -209,7 +209,7 @@ pub async fn variant_history( .filter_map(|e| state.storage.get_node(e.to).ok().flatten()) .collect(); - raw_nodes.sort_by(|a, b| b.created_at.cmp(&a.created_at)); + raw_nodes.sort_by_key(|node| std::cmp::Reverse(node.created_at)); raw_nodes.truncate(q.limit); let observations: Vec = raw_nodes @@ -953,7 +953,7 @@ pub async fn prompt_performance( }) .collect(); - all_obs.sort_by(|a, b| b.created_at.cmp(&a.created_at)); + all_obs.sort_by_key(|observation| std::cmp::Reverse(observation.created_at)); let agg = aggregate_observations(&all_obs); @@ -1026,7 +1026,7 @@ pub async fn version_performance( }) .collect(); - all_obs.sort_by(|a, b| b.created_at.cmp(&a.created_at)); + all_obs.sort_by_key(|observation| std::cmp::Reverse(observation.created_at)); let agg = aggregate_observations(&all_obs); diff --git a/crates/cortex-server/src/mcp/mod.rs b/crates/cortex-server/src/mcp/mod.rs index 636428f9..ab24cc92 100644 --- a/crates/cortex-server/src/mcp/mod.rs +++ b/crates/cortex-server/src/mcp/mod.rs @@ -93,10 +93,7 @@ fn dispatch(cortex: &Cortex, line: &str) -> Option { }; // Notifications have no "id" field — must not respond - let id = match msg.get("id") { - Some(id) => id.clone(), - None => return None, - }; + let id = msg.get("id")?.clone(); let method = msg["method"].as_str().unwrap_or("").to_string(); let params = msg @@ -1372,8 +1369,15 @@ async fn remote_resource_read(http: &reqwest::Client, base_url: &str, uri: &str) #[cfg(test)] mod tests { use super::*; + use std::sync::Mutex; + + // FastEmbed populates a shared model cache on first use. Serializing test + // construction prevents parallel tests from racing while that cache is + // downloaded and unpacked on a clean CI runner. + static EMBEDDING_MODEL_INIT: Mutex<()> = Mutex::new(()); fn make_cortex() -> Cortex { + let _guard = EMBEDDING_MODEL_INIT.lock().unwrap(); let dir = tempfile::tempdir().unwrap(); Cortex::open(dir.path().join("test.redb"), LibraryConfig::default()).unwrap() } diff --git a/docs/getting-started/first-agent.md b/docs/getting-started/first-agent.md index 008299b0..42dccfa5 100644 --- a/docs/getting-started/first-agent.md +++ b/docs/getting-started/first-agent.md @@ -11,7 +11,7 @@ This guide builds a simple question-answering agent that remembers facts across ## Install ```bash -pip install cortex-memory openai +pip install cortex-memory-client openai ``` ## The Agent diff --git a/docs/guides/crewai.md b/docs/guides/crewai.md index 48122333..f18bf918 100644 --- a/docs/guides/crewai.md +++ b/docs/guides/crewai.md @@ -5,7 +5,7 @@ Share memory across a CrewAI multi-agent team using Cortex. ## Install ```bash -pip install cortex-memory crewai crewai-tools +pip install cortex-memory-client crewai crewai-tools ``` ## Shared Memory Tool diff --git a/docs/guides/langchain.md b/docs/guides/langchain.md index 93a8f92c..a3b7e253 100644 --- a/docs/guides/langchain.md +++ b/docs/guides/langchain.md @@ -5,7 +5,7 @@ Use Cortex as the memory backend for a LangChain agent. ## Install ```bash -pip install cortex-memory langchain langchain-openai +pip install cortex-memory-client langchain langchain-openai ``` ## Memory Class diff --git a/docs/reference/metadata-conventions.md b/docs/reference/metadata-conventions.md index f09e391c..4b6b9c0c 100644 --- a/docs/reference/metadata-conventions.md +++ b/docs/reference/metadata-conventions.md @@ -6,24 +6,24 @@ This document defines **well-known metadata keys**: documented conventions that ## Node metadata -| Key | Type | Description | Used by | -|-----|------|-------------|---------| -| `entity_type` | string | What kind of entity this is: `agent`, `company`, `person`, `technology`, `project`, `location`, `product` | Entity layer, briefing engine | -| `aliases` | array of strings | Alternative names for an entity node. Used for entity resolution. | Auto-linker entity matching | -| `parent_agent` | string | Agent ID that spawned the agent that created this node. Provenance chain. | Trust scoring (source reliability), audit | -| `task_id` | string | Orchestrator task ID that prompted this node's creation. | Audit, task-scoped queries | -| `source_url` | string | External URL where this knowledge originated. | Provenance, citation | -| `content_type` | string | MIME-like type of the body content: `text/plain`, `text/markdown`, `application/json`, `code/rust`, `code/python` | Embedding strategy, display | -| `language` | string | ISO 639-1 language code of the content: `en`, `zh`, `ja` | Embedding model selection | -| `expires_reason` | string | Why this node has an `expires_at`. `working-memory`, `ttl-policy`, `gdpr-request` | Audit | +| Key | Type | Description | Used by | +| ---------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | +| `entity_type` | string | What kind of entity this is: `agent`, `company`, `person`, `technology`, `project`, `location`, `product` | Entity layer, briefing engine | +| `aliases` | array of strings | Alternative names for an entity node. Used for entity resolution. | Auto-linker entity matching | +| `parent_agent` | string | Agent ID that spawned the agent that created this node. Provenance chain. | Trust scoring (source reliability), audit | +| `task_id` | string | Orchestrator task ID that prompted this node's creation. | Audit, task-scoped queries | +| `source_url` | string | External URL where this knowledge originated. | Provenance, citation | +| `content_type` | string | MIME-like type of the body content: `text/plain`, `text/markdown`, `application/json`, `code/rust`, `code/python` | Embedding strategy, display | +| `language` | string | ISO 639-1 language code of the content: `en`, `zh`, `ja` | Embedding model selection | +| `expires_reason` | string | Why this node has an `expires_at`. `working-memory`, `ttl-policy`, `gdpr-request` | Audit | ## Edge metadata -| Key | Type | Description | Used by | -|-----|------|-------------|---------| -| `entity` | string | Normalised entity name that links these two nodes. | Entity co-occurrence rule, cross-agent discovery | -| `similarity_context` | string | What the similarity was about (title match, body match, tag overlap). | Debugging, trust scoring | -| `rule_version` | string | Version of the rule that created this edge. | Migration, debugging | +| Key | Type | Description | Used by | +| -------------------- | ------ | --------------------------------------------------------------------- | ------------------------------------------------ | +| `entity` | string | Normalised entity name that links these two nodes. | Entity co-occurrence rule, cross-agent discovery | +| `similarity_context` | string | What the similarity was about (title match, body match, tag overlap). | Debugging, trust scoring | +| `rule_version` | string | Version of the rule that created this edge. | Migration, debugging | ## Entity type @@ -39,15 +39,15 @@ The briefing engine uses `entity_type` to group entities in cross-agent sections Well-known entity types: -| Value | Description | -|-------|-------------| -| `agent` | An AI agent or bot | -| `company` | A company or organisation | -| `person` | A human individual | -| `technology` | A language, framework, or tool | -| `project` | A named project or initiative | -| `location` | A place (city, region, address) | -| `product` | A product or service | +| Value | Description | +| ------------ | ------------------------------- | +| `agent` | An AI agent or bot | +| `company` | A company or organisation | +| `person` | A human individual | +| `technology` | A language, framework, or tool | +| `project` | A named project or initiative | +| `location` | A place (city, region, address) | +| `product` | A product or service | Custom entity types are allowed — these are conventions, not constraints. @@ -111,13 +111,13 @@ cx.store("entity", "Company X", metadata={ ### TypeScript ```typescript -import { Cortex, EntityType } from '@cortex-memory/client'; +import { Cortex, EntityType } from "cortex-memory-client"; -const cx = new Cortex('localhost:9090'); +const cx = new Cortex("localhost:9090"); -await cx.storeEntity('Company X', { - entityType: EntityType.Company, - aliases: ['CompanyX'], +await cx.storeEntity("Company X", { + entityType: EntityType.Company, + aliases: ["CompanyX"], }); ``` diff --git a/docs/reference/python-sdk.md b/docs/reference/python-sdk.md index c285b385..b904673e 100644 --- a/docs/reference/python-sdk.md +++ b/docs/reference/python-sdk.md @@ -3,7 +3,7 @@ ## Install ```bash -pip install cortex-memory +pip install cortex-memory-client ``` ## Quick Start @@ -20,7 +20,7 @@ Connect to a Cortex server. - `addr` — gRPC address, e.g. `"localhost:9090"` -## cx.store(kind, title, *, body="", importance=0.5, tags=None, source_agent="", metadata=None) → str +## cx.store(kind, title, \*, body="", importance=0.5, tags=None, source_agent="", metadata=None) → str Store a new node. Returns the node ID. @@ -35,7 +35,7 @@ node_id = cx.store("fact", "JWT is used for auth", Get a node by ID. -## cx.search(query, limit=10, *, kind=None, hybrid=False, alpha=0.7) → List[SearchResult] +## cx.search(query, limit=10, \*, kind=None, hybrid=False, alpha=0.7) → List[SearchResult] Search nodes semantically. @@ -45,7 +45,7 @@ for r in results: print(r.score, r.title, r.id) ``` -## cx.briefing(agent_id, *, max_tokens=2000) → str +## cx.briefing(agent_id, \*, max_tokens=2000) → str Get a context briefing for an agent. @@ -54,7 +54,7 @@ briefing = cx.briefing("my-agent") # Use as system prompt context ``` -## cx.edge(from_id, to_id, relation, *, weight=0.8) → str +## cx.edge(from_id, to_id, relation, \*, weight=0.8) → str Create an edge between two nodes. @@ -66,31 +66,31 @@ cx.edge(node_a, node_b, "supports", weight=0.9) Delete a node. -## cx.traverse(node_id, *, depth=2, direction="both") → Subgraph +## cx.traverse(node_id, \*, depth=2, direction="both") → Subgraph Traverse the graph from a node. ## SearchResult -| Field | Type | Description | -|-------|------|-------------| -| `id` | str | Node ID | -| `title` | str | Node title | -| `body` | str | Node body | -| `kind` | str | Node kind | -| `score` | float | Similarity score | +| Field | Type | Description | +| ------------ | ----- | ---------------- | +| `id` | str | Node ID | +| `title` | str | Node title | +| `body` | str | Node body | +| `kind` | str | Node kind | +| `score` | float | Similarity score | | `importance` | float | Importance score | ## Node -| Field | Type | Description | -|-------|------|-------------| -| `id` | str | Node ID | -| `kind` | str | Node kind | -| `title` | str | Title | -| `body` | str | Body | -| `importance` | float | Importance score | -| `tags` | List[str] | Tags | -| `source_agent` | str | Source agent ID | -| `created_at` | datetime | Creation timestamp | -| `metadata` | Dict[str, str] | Metadata | +| Field | Type | Description | +| -------------- | -------------- | ------------------ | +| `id` | str | Node ID | +| `kind` | str | Node kind | +| `title` | str | Title | +| `body` | str | Body | +| `importance` | float | Importance score | +| `tags` | List[str] | Tags | +| `source_agent` | str | Source agent ID | +| `created_at` | datetime | Creation timestamp | +| `metadata` | Dict[str, str] | Metadata | diff --git a/docs/reference/typescript-sdk.md b/docs/reference/typescript-sdk.md index 302f47f9..cb558c7d 100644 --- a/docs/reference/typescript-sdk.md +++ b/docs/reference/typescript-sdk.md @@ -3,26 +3,26 @@ ## Install ```bash -npm install @cortex-memory/client +npm install cortex-memory-client # or -yarn add @cortex-memory/client +yarn add cortex-memory-client ``` ## Quick Start ```typescript -import { Cortex } from '@cortex-memory/client'; +import { Cortex } from "cortex-memory-client"; -const cx = new Cortex('localhost:9090'); +const cx = new Cortex("localhost:9090"); await cx.store({ - kind: 'fact', - title: 'The API uses JWT authentication', + kind: "fact", + title: "The API uses JWT authentication", importance: 0.8, }); -const results = await cx.search('authentication', { limit: 5 }); -const briefing = await cx.briefing('my-agent'); +const results = await cx.search("authentication", { limit: 5 }); +const briefing = await cx.briefing("my-agent"); ``` ## new Cortex(addr) @@ -40,18 +40,18 @@ interface StoreOptions { kind: string; title: string; body?: string; - importance?: number; // 0.0–1.0, default 0.5 + importance?: number; // 0.0–1.0, default 0.5 tags?: string[]; sourceAgent?: string; metadata?: Record; } const id = await cx.store({ - kind: 'decision', - title: 'Use TypeScript for the frontend', - body: 'Strong typing reduces bugs in large codebases.', + kind: "decision", + title: "Use TypeScript for the frontend", + body: "Strong typing reduces bugs in large codebases.", importance: 0.9, - tags: ['architecture', 'frontend'], + tags: ["architecture", "frontend"], }); ``` @@ -61,8 +61,8 @@ Search nodes semantically. ```typescript interface SearchOptions { - limit?: number; // default 10 - kind?: string; // filter by kind + limit?: number; // default 10 + kind?: string; // filter by kind } interface SearchResult { @@ -74,7 +74,7 @@ interface SearchResult { importance: number; } -const results = await cx.search('authentication', { limit: 5, kind: 'fact' }); +const results = await cx.search("authentication", { limit: 5, kind: "fact" }); for (const r of results) { console.log(`${r.score.toFixed(2)} ${r.title}`); } @@ -86,10 +86,10 @@ Get a context briefing for an agent. ```typescript interface BriefingOptions { - maxTokens?: number; // default 2000 + maxTokens?: number; // default 2000 } -const context = await cx.briefing('my-agent'); +const context = await cx.briefing("my-agent"); // Inject into LLM system prompt ``` @@ -106,7 +106,7 @@ Delete a node. Create an edge between two nodes. Returns the edge ID. ```typescript -await cx.edge(nodeA, nodeB, 'supports', { weight: 0.9 }); +await cx.edge(nodeA, nodeB, "supports", { weight: 0.9 }); ``` ## MockCortex @@ -114,11 +114,11 @@ await cx.edge(nodeA, nodeB, 'supports', { weight: 0.9 }); For testing — in-memory implementation of the Cortex interface: ```typescript -import { MockCortex } from '@cortex-memory/client/testing'; +import { MockCortex } from "cortex-memory-client"; const cx = new MockCortex(); -await cx.store({ kind: 'fact', title: 'Test fact' }); -const results = await cx.search('test'); +await cx.store({ kind: "fact", title: "Test fact" }); +const results = await cx.search("test"); ``` ## Source diff --git a/examples/crewai-team/requirements.txt b/examples/crewai-team/requirements.txt index 95f48c4c..d11420d6 100644 --- a/examples/crewai-team/requirements.txt +++ b/examples/crewai-team/requirements.txt @@ -1,4 +1,4 @@ -cortex-memory>=0.1.0 +cortex-memory-client>=0.3.2 crewai>=0.28.0 crewai-tools>=0.4.0 openai>=1.0.0 diff --git a/examples/langchain-agent/requirements.txt b/examples/langchain-agent/requirements.txt index 5eb1386c..59c48dfc 100644 --- a/examples/langchain-agent/requirements.txt +++ b/examples/langchain-agent/requirements.txt @@ -1,4 +1,4 @@ -cortex-memory>=0.1.0 +cortex-memory-client>=0.3.2 langchain>=0.2.0 langchain-openai>=0.1.0 openai>=1.0.0 diff --git a/examples/personal-assistant/requirements.txt b/examples/personal-assistant/requirements.txt index 376dfb96..6ac9d0b3 100644 --- a/examples/personal-assistant/requirements.txt +++ b/examples/personal-assistant/requirements.txt @@ -1,2 +1,2 @@ -cortex-memory>=0.1.0 +cortex-memory-client>=0.3.2 openai>=1.0.0 diff --git a/examples/rag-pipeline/requirements.txt b/examples/rag-pipeline/requirements.txt index 376dfb96..6ac9d0b3 100644 --- a/examples/rag-pipeline/requirements.txt +++ b/examples/rag-pipeline/requirements.txt @@ -1,2 +1,2 @@ -cortex-memory>=0.1.0 +cortex-memory-client>=0.3.2 openai>=1.0.0 diff --git a/mcp-bridge/LICENSE b/mcp-bridge/LICENSE new file mode 100644 index 00000000..2f7e3e01 --- /dev/null +++ b/mcp-bridge/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Mike Darlington + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/mcp-bridge/README.md b/mcp-bridge/README.md new file mode 100644 index 00000000..869ceb03 --- /dev/null +++ b/mcp-bridge/README.md @@ -0,0 +1,63 @@ +# cortex-mcp-bridge + +Node.js MCP bridge for the [Cortex](https://github.com/MikeSquared-Agency/cortex) +self-organizing graph-memory engine. + +The bridge runs locally over stdio and proxies its tools to a running Cortex +HTTP server. It does not bundle the Cortex engine: run Cortex locally, or set +`CORTEX_URL` to a remote deployment. + +## Requirements + +- Node.js 18 or newer +- A Cortex HTTP server, available at `http://localhost:9091` by default + +## Run + +Start Cortex: + +```bash +cortex serve +``` + +Then start the MCP bridge: + +```bash +npx cortex-mcp-bridge +``` + +To use a remote server or bearer-token authentication: + +```bash +CORTEX_URL=https://cortex.example.com \ +CORTEX_AUTH_TOKEN=your-token \ +npx cortex-mcp-bridge +``` + +## MCP client configuration + +```json +{ + "mcpServers": { + "cortex": { + "command": "npx", + "args": ["-y", "cortex-mcp-bridge"], + "env": { + "CORTEX_URL": "http://localhost:9091" + } + } + } +} +``` + +`CORTEX_AUTH_TOKEN` is optional. When set, the bridge sends it to Cortex as a +bearer token. + +## Tools + +The bridge exposes `cortex_store`, `cortex_search`, `cortex_recall`, +`cortex_briefing`, `cortex_traverse`, `cortex_relate`, and `cortex_observe`. + +## License + +MIT diff --git a/mcp-bridge/cortex-mcp-bridge.js b/mcp-bridge/cortex-mcp-bridge.js index 8022d0fd..578d8b5f 100755 --- a/mcp-bridge/cortex-mcp-bridge.js +++ b/mcp-bridge/cortex-mcp-bridge.js @@ -1,7 +1,8 @@ #!/usr/bin/env node /** - * Cortex MCP Bridge — lightweight MCP server that proxies to Cortex REST API. - * No Rust binary needed. Just Node.js. + * Cortex MCP Bridge — lightweight MCP server that proxies to a running Cortex + * REST API. The bridge itself needs only Node.js; Cortex may run locally or on + * a remote host. * * Usage in Claude Desktop config: * { @@ -20,9 +21,10 @@ * CORTEX_AUTH_TOKEN is optional — omit it for local servers with auth disabled. */ -const BASE = process.env.CORTEX_URL || "http://localhost:19091"; +const BASE = process.env.CORTEX_URL || "http://localhost:9091"; const TOKEN = process.env.CORTEX_AUTH_TOKEN || null; const readline = require("readline"); +const { version: BRIDGE_VERSION } = require("./package.json"); const TOOLS = [ { @@ -226,7 +228,7 @@ rl.on("line", async (line) => { respond(id, { protocolVersion: "2024-11-05", capabilities: { tools: {} }, - serverInfo: { name: "cortex", version: "0.1.0" }, + serverInfo: { name: "cortex-mcp-bridge", version: BRIDGE_VERSION }, }); break; diff --git a/mcp-bridge/package.json b/mcp-bridge/package.json index e4f56f5d..88be81ba 100644 --- a/mcp-bridge/package.json +++ b/mcp-bridge/package.json @@ -1,14 +1,37 @@ { "name": "cortex-mcp-bridge", - "version": "0.3.1", - "description": "MCP bridge for Cortex graph memory (no Rust needed)", + "version": "0.3.2", + "description": "Node.js MCP bridge for a local or remote Cortex graph-memory server", "bin": { "cortex-mcp-bridge": "./cortex-mcp-bridge.js" }, + "scripts": { + "test": "node --test test.mjs" + }, "license": "MIT", + "author": "MikeSquared Agency ", + "homepage": "https://github.com/MikeSquared-Agency/cortex#use-with-ai-agents-mcp", + "bugs": { + "url": "https://github.com/MikeSquared-Agency/cortex/issues" + }, "repository": { "type": "git", - "url": "https://github.com/MikeSquared-Agency/cortex" + "url": "git+https://github.com/MikeSquared-Agency/cortex.git", + "directory": "mcp-bridge" + }, + "keywords": [ + "mcp", + "cortex", + "memory", + "ai-agents", + "model-context-protocol" + ], + "engines": { + "node": ">=18" }, - "keywords": ["mcp", "cortex", "memory", "ai-agents", "model-context-protocol"] + "files": [ + "cortex-mcp-bridge.js", + "README.md", + "LICENSE" + ] } diff --git a/mcp-bridge/test.mjs b/mcp-bridge/test.mjs new file mode 100644 index 00000000..b3df105a --- /dev/null +++ b/mcp-bridge/test.mjs @@ -0,0 +1,58 @@ +import assert from "node:assert/strict"; +import { spawn } from "node:child_process"; +import { once } from "node:events"; +import test from "node:test"; + +function request(child, message) { + return new Promise((resolve, reject) => { + const onData = (chunk) => { + try { + resolve(JSON.parse(chunk.toString().trim())); + } catch (error) { + reject(error); + } + }; + child.stdout.once("data", onData); + child.stdin.write(`${JSON.stringify(message)}\n`); + }); +} + +test("initializes and exposes the Cortex tools", async (t) => { + const child = spawn(process.execPath, ["cortex-mcp-bridge.js"], { + cwd: import.meta.dirname, + stdio: ["pipe", "pipe", "pipe"], + }); + + t.after(async () => { + child.kill(); + await once(child, "exit"); + }); + + const initialized = await request(child, { + jsonrpc: "2.0", + id: 1, + method: "initialize", + params: {}, + }); + assert.equal(initialized.result.serverInfo.name, "cortex-mcp-bridge"); + assert.equal(initialized.result.serverInfo.version, "0.3.2"); + + const tools = await request(child, { + jsonrpc: "2.0", + id: 2, + method: "tools/list", + params: {}, + }); + assert.deepEqual( + tools.result.tools.map((tool) => tool.name), + [ + "cortex_store", + "cortex_search", + "cortex_recall", + "cortex_briefing", + "cortex_traverse", + "cortex_relate", + "cortex_observe", + ], + ); +}); diff --git a/sdks/python/LICENSE b/sdks/python/LICENSE new file mode 100644 index 00000000..2f7e3e01 --- /dev/null +++ b/sdks/python/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Mike Darlington + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sdks/python/README.md b/sdks/python/README.md index 17609692..35b31315 100644 --- a/sdks/python/README.md +++ b/sdks/python/README.md @@ -1,11 +1,11 @@ -# cortex-memory +# cortex-memory-client -Python client SDK for the [Cortex](https://github.com/MikeSquared-Agency/cortex) graph memory engine. +Python client SDK for the [Cortex](https://github.com/MikeSquared-Agency/cortex) graph memory engine. The distribution is named `cortex-memory-client`; the import package remains `cortex_memory`. ## Installation ```bash -pip install cortex-memory +pip install cortex-memory-client ``` ## Quick start diff --git a/sdks/python/pyproject.toml b/sdks/python/pyproject.toml index a08ebc4e..2eeb8a98 100644 --- a/sdks/python/pyproject.toml +++ b/sdks/python/pyproject.toml @@ -3,12 +3,28 @@ requires = ["hatchling"] build-backend = "hatchling.build" [project] -name = "cortex-memory" -version = "0.3.1" +name = "cortex-memory-client" +version = "0.3.2" description = "Self-organizing graph memory for AI agents — Python SDK" -license = { text = "MIT" } +license = "MIT" requires-python = ">=3.9" readme = "README.md" +authors = [ + { name = "MikeSquared Agency", email = "mike@darlington.dev" }, +] +keywords = ["ai-agents", "cortex", "graph-memory", "memory", "sdk"] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Developers", + "License :: OSI Approved :: MIT License", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + "Topic :: Software Development :: Libraries :: Python Modules", +] dependencies = [ "grpcio>=1.60", "grpcio-tools>=1.60", @@ -18,5 +34,11 @@ dependencies = [ [project.optional-dependencies] dev = ["pytest", "pytest-asyncio"] +[project.urls] +Homepage = "https://github.com/MikeSquared-Agency/cortex" +Documentation = "https://github.com/MikeSquared-Agency/cortex/tree/main/docs" +Repository = "https://github.com/MikeSquared-Agency/cortex.git" +Issues = "https://github.com/MikeSquared-Agency/cortex/issues" + [tool.hatch.build.targets.wheel] packages = ["cortex_memory"] diff --git a/sdks/typescript/LICENSE b/sdks/typescript/LICENSE new file mode 100644 index 00000000..2f7e3e01 --- /dev/null +++ b/sdks/typescript/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Mike Darlington + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/sdks/typescript/README.md b/sdks/typescript/README.md index 1b07f168..2f469e12 100644 --- a/sdks/typescript/README.md +++ b/sdks/typescript/README.md @@ -1,50 +1,50 @@ -# @cortex-memory/client +# cortex-memory-client TypeScript/Node.js client SDK for the [Cortex](https://github.com/MikeSquared-Agency/cortex) graph memory engine. ## Installation ```bash -npm install @cortex-memory/client +npm install cortex-memory-client ``` ## Quick start ```typescript -import { Cortex } from '@cortex-memory/client'; +import { Cortex } from "cortex-memory-client"; -const cx = new Cortex('localhost:9090'); +const cx = new Cortex("localhost:9090"); // Store knowledge const id = await cx.store({ - kind: 'fact', - title: 'API rate limit is 1000/min', - tags: ['api', 'limits'], + kind: "fact", + title: "API rate limit is 1000/min", + tags: ["api", "limits"], }); // Semantic search -const results = await cx.search('rate limits'); +const results = await cx.search("rate limits"); for (const r of results) { console.log(`${r.score.toFixed(2)} — ${r.title}`); } // Get briefing -const briefing = await cx.briefing('my-agent'); +const briefing = await cx.briefing("my-agent"); console.log(briefing); ``` ## Testing ```typescript -import { MockCortex } from '@cortex-memory/client'; +import { MockCortex } from "cortex-memory-client"; -describe('my agent', () => { - it('stores knowledge', async () => { +describe("my agent", () => { + it("stores knowledge", async () => { const cx = new MockCortex(); - await cx.store({ kind: 'fact', title: 'test fact' }); - const results = await cx.search('test'); + await cx.store({ kind: "fact", title: "test fact" }); + const results = await cx.search("test"); expect(results).toHaveLength(1); - cx.assertStored('fact', 'test fact'); + cx.assertStored("fact", "test fact"); }); }); ``` diff --git a/sdks/typescript/package-lock.json b/sdks/typescript/package-lock.json index 54f5be87..52b38e7e 100644 --- a/sdks/typescript/package-lock.json +++ b/sdks/typescript/package-lock.json @@ -1,27 +1,29 @@ { - "name": "@cortex-memory/client", - "version": "0.3.0", + "name": "cortex-memory-client", + "version": "0.3.2", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "@cortex-memory/client", - "version": "0.3.0", + "name": "cortex-memory-client", + "version": "0.3.2", "license": "MIT", "dependencies": { - "@grpc/grpc-js": "^1.14.3", - "@grpc/proto-loader": "^0.7.15" + "@grpc/grpc-js": "^1.14.4", + "@grpc/proto-loader": "^0.8.1" }, "devDependencies": { "@types/node": "^20.19.33", "jest": "^29", "ts-jest": "^29", "typescript": "^5.9.3" + }, + "engines": { + "node": ">=18" } }, "node_modules/@babel/code-frame": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", @@ -36,7 +38,6 @@ }, "node_modules/@babel/compat-data": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", "dev": true, "license": "MIT", @@ -46,7 +47,6 @@ }, "node_modules/@babel/core": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "dev": true, "license": "MIT", @@ -77,7 +77,6 @@ }, "node_modules/@babel/generator": { "version": "7.29.1", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", "dev": true, "license": "MIT", @@ -94,7 +93,6 @@ }, "node_modules/@babel/helper-compilation-targets": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, "license": "MIT", @@ -111,7 +109,6 @@ }, "node_modules/@babel/helper-globals": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, "license": "MIT", @@ -121,7 +118,6 @@ }, "node_modules/@babel/helper-module-imports": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, "license": "MIT", @@ -135,7 +131,6 @@ }, "node_modules/@babel/helper-module-transforms": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, "license": "MIT", @@ -153,7 +148,6 @@ }, "node_modules/@babel/helper-plugin-utils": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", "dev": true, "license": "MIT", @@ -163,7 +157,6 @@ }, "node_modules/@babel/helper-string-parser": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, "license": "MIT", @@ -173,7 +166,6 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", @@ -183,7 +175,6 @@ }, "node_modules/@babel/helper-validator-option": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, "license": "MIT", @@ -193,7 +184,6 @@ }, "node_modules/@babel/helpers": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, "license": "MIT", @@ -207,7 +197,6 @@ }, "node_modules/@babel/parser": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.0.tgz", "integrity": "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww==", "dev": true, "license": "MIT", @@ -223,7 +212,6 @@ }, "node_modules/@babel/plugin-syntax-async-generators": { "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, "license": "MIT", @@ -236,7 +224,6 @@ }, "node_modules/@babel/plugin-syntax-bigint": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, "license": "MIT", @@ -249,7 +236,6 @@ }, "node_modules/@babel/plugin-syntax-class-properties": { "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, "license": "MIT", @@ -262,7 +248,6 @@ }, "node_modules/@babel/plugin-syntax-class-static-block": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", "dev": true, "license": "MIT", @@ -278,7 +263,6 @@ }, "node_modules/@babel/plugin-syntax-import-attributes": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", "dev": true, "license": "MIT", @@ -294,7 +278,6 @@ }, "node_modules/@babel/plugin-syntax-import-meta": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, "license": "MIT", @@ -307,7 +290,6 @@ }, "node_modules/@babel/plugin-syntax-json-strings": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, "license": "MIT", @@ -320,7 +302,6 @@ }, "node_modules/@babel/plugin-syntax-jsx": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", "dev": true, "license": "MIT", @@ -336,7 +317,6 @@ }, "node_modules/@babel/plugin-syntax-logical-assignment-operators": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, "license": "MIT", @@ -349,7 +329,6 @@ }, "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, "license": "MIT", @@ -362,7 +341,6 @@ }, "node_modules/@babel/plugin-syntax-numeric-separator": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, "license": "MIT", @@ -375,7 +353,6 @@ }, "node_modules/@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, "license": "MIT", @@ -388,7 +365,6 @@ }, "node_modules/@babel/plugin-syntax-optional-catch-binding": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, "license": "MIT", @@ -401,7 +377,6 @@ }, "node_modules/@babel/plugin-syntax-optional-chaining": { "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, "license": "MIT", @@ -414,7 +389,6 @@ }, "node_modules/@babel/plugin-syntax-private-property-in-object": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", "dev": true, "license": "MIT", @@ -430,7 +404,6 @@ }, "node_modules/@babel/plugin-syntax-top-level-await": { "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, "license": "MIT", @@ -446,7 +419,6 @@ }, "node_modules/@babel/plugin-syntax-typescript": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", "dev": true, "license": "MIT", @@ -462,7 +434,6 @@ }, "node_modules/@babel/template": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, "license": "MIT", @@ -477,7 +448,6 @@ }, "node_modules/@babel/traverse": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", "dev": true, "license": "MIT", @@ -496,7 +466,6 @@ }, "node_modules/@babel/types": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", "dev": true, "license": "MIT", @@ -510,15 +479,13 @@ }, "node_modules/@bcoe/v8-coverage": { "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", "dev": true, "license": "MIT" }, "node_modules/@grpc/grpc-js": { - "version": "1.14.3", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", - "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", + "version": "1.14.4", + "integrity": "sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ==", "license": "Apache-2.0", "dependencies": { "@grpc/proto-loader": "^0.8.0", @@ -528,33 +495,14 @@ "node": ">=12.10.0" } }, - "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", - "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", - "license": "Apache-2.0", - "dependencies": { - "lodash.camelcase": "^4.3.0", - "long": "^5.0.0", - "protobufjs": "^7.5.3", - "yargs": "^17.7.2" - }, - "bin": { - "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/@grpc/proto-loader": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", - "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "version": "0.8.1", + "integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==", "license": "Apache-2.0", "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", - "protobufjs": "^7.2.5", + "protobufjs": "^7.5.5", "yargs": "^17.7.2" }, "bin": { @@ -566,7 +514,6 @@ }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "license": "ISC", @@ -583,7 +530,6 @@ }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, "license": "MIT", @@ -593,7 +539,6 @@ }, "node_modules/@jest/console": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, "license": "MIT", @@ -611,7 +556,6 @@ }, "node_modules/@jest/core": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, "license": "MIT", @@ -659,7 +603,6 @@ }, "node_modules/@jest/environment": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", "dev": true, "license": "MIT", @@ -675,7 +618,6 @@ }, "node_modules/@jest/expect": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, "license": "MIT", @@ -689,7 +631,6 @@ }, "node_modules/@jest/expect-utils": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, "license": "MIT", @@ -702,7 +643,6 @@ }, "node_modules/@jest/fake-timers": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, "license": "MIT", @@ -720,7 +660,6 @@ }, "node_modules/@jest/globals": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, "license": "MIT", @@ -736,7 +675,6 @@ }, "node_modules/@jest/reporters": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, "license": "MIT", @@ -780,7 +718,6 @@ }, "node_modules/@jest/schemas": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, "license": "MIT", @@ -793,7 +730,6 @@ }, "node_modules/@jest/source-map": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, "license": "MIT", @@ -808,7 +744,6 @@ }, "node_modules/@jest/test-result": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, "license": "MIT", @@ -824,7 +759,6 @@ }, "node_modules/@jest/test-sequencer": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, "license": "MIT", @@ -840,7 +774,6 @@ }, "node_modules/@jest/transform": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, "license": "MIT", @@ -867,7 +800,6 @@ }, "node_modules/@jest/types": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, "license": "MIT", @@ -885,7 +817,6 @@ }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", "dev": true, "license": "MIT", @@ -896,7 +827,6 @@ }, "node_modules/@jridgewell/remapping": { "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, "license": "MIT", @@ -907,7 +837,6 @@ }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, "license": "MIT", @@ -917,14 +846,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/@jridgewell/trace-mapping": { "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", @@ -935,7 +862,6 @@ }, "node_modules/@js-sdsl/ordered-map": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", "license": "MIT", "funding": { @@ -943,80 +869,14 @@ "url": "https://opencollective.com/js-sdsl" } }, - "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/@sinclair/typebox": { "version": "0.27.10", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", "dev": true, "license": "MIT" }, "node_modules/@sinonjs/commons": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, "license": "BSD-3-Clause", @@ -1026,7 +886,6 @@ }, "node_modules/@sinonjs/fake-timers": { "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, "license": "BSD-3-Clause", @@ -1036,7 +895,6 @@ }, "node_modules/@types/babel__core": { "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "dev": true, "license": "MIT", @@ -1050,7 +908,6 @@ }, "node_modules/@types/babel__generator": { "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "dev": true, "license": "MIT", @@ -1060,7 +917,6 @@ }, "node_modules/@types/babel__template": { "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "dev": true, "license": "MIT", @@ -1071,7 +927,6 @@ }, "node_modules/@types/babel__traverse": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", "dev": true, "license": "MIT", @@ -1081,7 +936,6 @@ }, "node_modules/@types/graceful-fs": { "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, "license": "MIT", @@ -1091,14 +945,12 @@ }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", "dev": true, "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, "license": "MIT", @@ -1108,7 +960,6 @@ }, "node_modules/@types/istanbul-reports": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, "license": "MIT", @@ -1118,8 +969,8 @@ }, "node_modules/@types/node": { "version": "20.19.33", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.33.tgz", "integrity": "sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==", + "dev": true, "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -1127,14 +978,12 @@ }, "node_modules/@types/stack-utils": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", "dev": true, "license": "MIT" }, "node_modules/@types/yargs": { "version": "17.0.35", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", "dev": true, "license": "MIT", @@ -1144,14 +993,12 @@ }, "node_modules/@types/yargs-parser": { "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true, "license": "MIT" }, "node_modules/ansi-escapes": { "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, "license": "MIT", @@ -1167,7 +1014,6 @@ }, "node_modules/ansi-regex": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", "license": "MIT", "engines": { @@ -1176,7 +1022,6 @@ }, "node_modules/ansi-styles": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "license": "MIT", "dependencies": { @@ -1191,7 +1036,6 @@ }, "node_modules/anymatch": { "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "license": "ISC", @@ -1205,7 +1049,6 @@ }, "node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", @@ -1215,7 +1058,6 @@ }, "node_modules/babel-jest": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, "license": "MIT", @@ -1237,7 +1079,6 @@ }, "node_modules/babel-plugin-istanbul": { "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, "license": "BSD-3-Clause", @@ -1254,7 +1095,6 @@ }, "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "license": "BSD-3-Clause", @@ -1271,7 +1111,6 @@ }, "node_modules/babel-plugin-jest-hoist": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, "license": "MIT", @@ -1287,7 +1126,6 @@ }, "node_modules/babel-preset-current-node-syntax": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", "dev": true, "license": "MIT", @@ -1314,7 +1152,6 @@ }, "node_modules/babel-preset-jest": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, "license": "MIT", @@ -1331,14 +1168,12 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true, "license": "MIT" }, "node_modules/baseline-browser-mapping": { "version": "2.10.0", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", "dev": true, "license": "Apache-2.0", @@ -1351,7 +1186,6 @@ }, "node_modules/brace-expansion": { "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", @@ -1362,7 +1196,6 @@ }, "node_modules/braces": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "license": "MIT", @@ -1375,7 +1208,6 @@ }, "node_modules/browserslist": { "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, "funding": [ @@ -1409,7 +1241,6 @@ }, "node_modules/bs-logger": { "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", "dev": true, "license": "MIT", @@ -1422,7 +1253,6 @@ }, "node_modules/bser": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, "license": "Apache-2.0", @@ -1432,14 +1262,12 @@ }, "node_modules/buffer-from": { "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true, "license": "MIT" }, "node_modules/callsites": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true, "license": "MIT", @@ -1449,7 +1277,6 @@ }, "node_modules/camelcase": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, "license": "MIT", @@ -1459,7 +1286,6 @@ }, "node_modules/caniuse-lite": { "version": "1.0.30001770", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001770.tgz", "integrity": "sha512-x/2CLQ1jHENRbHg5PSId2sXq1CIO1CISvwWAj027ltMVG2UNgW+w9oH2+HzgEIRFembL8bUlXtfbBHR1fCg2xw==", "dev": true, "funding": [ @@ -1480,7 +1306,6 @@ }, "node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", @@ -1497,7 +1322,6 @@ }, "node_modules/char-regex": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, "license": "MIT", @@ -1507,7 +1331,6 @@ }, "node_modules/ci-info": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, "funding": [ @@ -1523,14 +1346,12 @@ }, "node_modules/cjs-module-lexer": { "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", "dev": true, "license": "MIT" }, "node_modules/cliui": { "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "license": "ISC", "dependencies": { @@ -1544,7 +1365,6 @@ }, "node_modules/co": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, "license": "MIT", @@ -1555,14 +1375,12 @@ }, "node_modules/collect-v8-coverage": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", "dev": true, "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "license": "MIT", "dependencies": { @@ -1574,27 +1392,23 @@ }, "node_modules/color-name": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, "node_modules/concat-map": { "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true, "license": "MIT" }, "node_modules/convert-source-map": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true, "license": "MIT" }, "node_modules/create-jest": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", "dev": true, "license": "MIT", @@ -1616,7 +1430,6 @@ }, "node_modules/cross-spawn": { "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", "dev": true, "license": "MIT", @@ -1631,7 +1444,6 @@ }, "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", @@ -1649,7 +1461,6 @@ }, "node_modules/dedent": { "version": "1.7.1", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz", "integrity": "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg==", "dev": true, "license": "MIT", @@ -1664,7 +1475,6 @@ }, "node_modules/deepmerge": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "dev": true, "license": "MIT", @@ -1674,7 +1484,6 @@ }, "node_modules/detect-newline": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, "license": "MIT", @@ -1684,7 +1493,6 @@ }, "node_modules/diff-sequences": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, "license": "MIT", @@ -1694,14 +1502,12 @@ }, "node_modules/electron-to-chromium": { "version": "1.5.286", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz", "integrity": "sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==", "dev": true, "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, "license": "MIT", @@ -1714,13 +1520,11 @@ }, "node_modules/emoji-regex": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "license": "MIT" }, "node_modules/error-ex": { "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, "license": "MIT", @@ -1730,7 +1534,6 @@ }, "node_modules/escalade": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "license": "MIT", "engines": { @@ -1739,7 +1542,6 @@ }, "node_modules/escape-string-regexp": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, "license": "MIT", @@ -1749,7 +1551,6 @@ }, "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==", "dev": true, "license": "BSD-2-Clause", @@ -1763,7 +1564,6 @@ }, "node_modules/execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, "license": "MIT", @@ -1787,7 +1587,6 @@ }, "node_modules/exit": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", "dev": true, "engines": { @@ -1796,7 +1595,6 @@ }, "node_modules/expect": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, "license": "MIT", @@ -1813,14 +1611,12 @@ }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true, "license": "MIT" }, "node_modules/fb-watchman": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, "license": "Apache-2.0", @@ -1830,7 +1626,6 @@ }, "node_modules/fill-range": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "license": "MIT", @@ -1843,7 +1638,6 @@ }, "node_modules/find-up": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "license": "MIT", @@ -1857,14 +1651,12 @@ }, "node_modules/fs.realpath": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true, "license": "ISC" }, "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, @@ -1879,7 +1671,6 @@ }, "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==", "dev": true, "license": "MIT", @@ -1889,7 +1680,6 @@ }, "node_modules/gensync": { "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, "license": "MIT", @@ -1899,7 +1689,6 @@ }, "node_modules/get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "license": "ISC", "engines": { @@ -1908,7 +1697,6 @@ }, "node_modules/get-package-type": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, "license": "MIT", @@ -1918,7 +1706,6 @@ }, "node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, "license": "MIT", @@ -1931,7 +1718,6 @@ }, "node_modules/glob": { "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, @@ -1953,14 +1739,12 @@ }, "node_modules/graceful-fs": { "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, "license": "ISC" }, "node_modules/handlebars": { "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", "dev": true, "license": "MIT", @@ -1982,7 +1766,6 @@ }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", @@ -1992,7 +1775,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "license": "MIT", @@ -2005,14 +1787,12 @@ }, "node_modules/html-escaper": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "dev": true, "license": "MIT" }, "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, "license": "Apache-2.0", @@ -2022,7 +1802,6 @@ }, "node_modules/import-local": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", "dev": true, "license": "MIT", @@ -2042,7 +1821,6 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", @@ -2052,7 +1830,6 @@ }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, @@ -2064,21 +1841,18 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "license": "ISC" }, "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true, "license": "MIT" }, "node_modules/is-core-module": { "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, "license": "MIT", @@ -2094,7 +1868,6 @@ }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "license": "MIT", "engines": { @@ -2103,7 +1876,6 @@ }, "node_modules/is-generator-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, "license": "MIT", @@ -2113,7 +1885,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, "license": "MIT", @@ -2123,7 +1894,6 @@ }, "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "license": "MIT", @@ -2136,14 +1906,12 @@ }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, "license": "BSD-3-Clause", @@ -2153,7 +1921,6 @@ }, "node_modules/istanbul-lib-instrument": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, "license": "BSD-3-Clause", @@ -2170,7 +1937,6 @@ }, "node_modules/istanbul-lib-instrument/node_modules/semver": { "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", @@ -2183,7 +1949,6 @@ }, "node_modules/istanbul-lib-report": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, "license": "BSD-3-Clause", @@ -2198,7 +1963,6 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, "license": "BSD-3-Clause", @@ -2213,7 +1977,6 @@ }, "node_modules/istanbul-reports": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, "license": "BSD-3-Clause", @@ -2227,7 +1990,6 @@ }, "node_modules/jest": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, "license": "MIT", @@ -2254,7 +2016,6 @@ }, "node_modules/jest-changed-files": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, "license": "MIT", @@ -2269,7 +2030,6 @@ }, "node_modules/jest-circus": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, "license": "MIT", @@ -2301,7 +2061,6 @@ }, "node_modules/jest-cli": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, "license": "MIT", @@ -2335,7 +2094,6 @@ }, "node_modules/jest-config": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, "license": "MIT", @@ -2381,7 +2139,6 @@ }, "node_modules/jest-diff": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, "license": "MIT", @@ -2397,7 +2154,6 @@ }, "node_modules/jest-docblock": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, "license": "MIT", @@ -2410,7 +2166,6 @@ }, "node_modules/jest-each": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, "license": "MIT", @@ -2427,7 +2182,6 @@ }, "node_modules/jest-environment-node": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, "license": "MIT", @@ -2445,7 +2199,6 @@ }, "node_modules/jest-get-type": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, "license": "MIT", @@ -2455,7 +2208,6 @@ }, "node_modules/jest-haste-map": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, "license": "MIT", @@ -2481,7 +2233,6 @@ }, "node_modules/jest-leak-detector": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, "license": "MIT", @@ -2495,7 +2246,6 @@ }, "node_modules/jest-matcher-utils": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, "license": "MIT", @@ -2511,7 +2261,6 @@ }, "node_modules/jest-message-util": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, "license": "MIT", @@ -2532,7 +2281,6 @@ }, "node_modules/jest-mock": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, "license": "MIT", @@ -2547,7 +2295,6 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "license": "MIT", @@ -2565,7 +2312,6 @@ }, "node_modules/jest-regex-util": { "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, "license": "MIT", @@ -2575,7 +2321,6 @@ }, "node_modules/jest-resolve": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, "license": "MIT", @@ -2596,7 +2341,6 @@ }, "node_modules/jest-resolve-dependencies": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, "license": "MIT", @@ -2610,7 +2354,6 @@ }, "node_modules/jest-runner": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, "license": "MIT", @@ -2643,7 +2386,6 @@ }, "node_modules/jest-runtime": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", "dev": true, "license": "MIT", @@ -2677,7 +2419,6 @@ }, "node_modules/jest-snapshot": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, "license": "MIT", @@ -2709,7 +2450,6 @@ }, "node_modules/jest-snapshot/node_modules/semver": { "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", @@ -2722,7 +2462,6 @@ }, "node_modules/jest-util": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, "license": "MIT", @@ -2740,7 +2479,6 @@ }, "node_modules/jest-validate": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", "dev": true, "license": "MIT", @@ -2758,7 +2496,6 @@ }, "node_modules/jest-validate/node_modules/camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, "license": "MIT", @@ -2771,7 +2508,6 @@ }, "node_modules/jest-watcher": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, "license": "MIT", @@ -2791,7 +2527,6 @@ }, "node_modules/jest-worker": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, "license": "MIT", @@ -2807,7 +2542,6 @@ }, "node_modules/jest-worker/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", @@ -2823,14 +2557,12 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, "license": "MIT" }, "node_modules/js-yaml": { "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", @@ -2844,7 +2576,6 @@ }, "node_modules/jsesc": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, "license": "MIT", @@ -2857,14 +2588,12 @@ }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true, "license": "MIT" }, "node_modules/json5": { "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, "license": "MIT", @@ -2877,7 +2606,6 @@ }, "node_modules/kleur": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, "license": "MIT", @@ -2887,7 +2615,6 @@ }, "node_modules/leven": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "license": "MIT", @@ -2897,14 +2624,12 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, "license": "MIT" }, "node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", @@ -2917,26 +2642,22 @@ }, "node_modules/lodash.camelcase": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==", "license": "MIT" }, "node_modules/lodash.memoize": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", "dev": true, "license": "MIT" }, "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/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, "license": "ISC", @@ -2946,7 +2667,6 @@ }, "node_modules/make-dir": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, "license": "MIT", @@ -2962,7 +2682,6 @@ }, "node_modules/make-dir/node_modules/semver": { "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", @@ -2975,14 +2694,12 @@ }, "node_modules/make-error": { "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true, "license": "ISC" }, "node_modules/makeerror": { "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "license": "BSD-3-Clause", @@ -2992,14 +2709,12 @@ }, "node_modules/merge-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "dev": true, "license": "MIT" }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", @@ -3013,7 +2728,6 @@ }, "node_modules/mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true, "license": "MIT", @@ -3023,7 +2737,6 @@ }, "node_modules/minimatch": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "license": "ISC", @@ -3036,7 +2749,6 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "license": "MIT", @@ -3046,42 +2758,36 @@ }, "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/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true, "license": "MIT" }, "node_modules/neo-async": { "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true, "license": "MIT" }, "node_modules/node-int64": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true, "license": "MIT" }, "node_modules/node-releases": { "version": "2.0.27", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "license": "MIT", @@ -3091,7 +2797,6 @@ }, "node_modules/npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, "license": "MIT", @@ -3104,7 +2809,6 @@ }, "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==", "dev": true, "license": "ISC", @@ -3114,7 +2818,6 @@ }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, "license": "MIT", @@ -3130,7 +2833,6 @@ }, "node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", @@ -3146,7 +2848,6 @@ }, "node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", @@ -3159,7 +2860,6 @@ }, "node_modules/p-locate/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", @@ -3175,7 +2875,6 @@ }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "license": "MIT", @@ -3185,7 +2884,6 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "license": "MIT", @@ -3204,7 +2902,6 @@ }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", @@ -3214,7 +2911,6 @@ }, "node_modules/path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true, "license": "MIT", @@ -3224,7 +2920,6 @@ }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", @@ -3234,21 +2929,18 @@ }, "node_modules/path-parse": { "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true, "license": "MIT" }, "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/picomatch": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "license": "MIT", @@ -3261,7 +2953,6 @@ }, "node_modules/pirates": { "version": "4.0.7", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "dev": true, "license": "MIT", @@ -3271,7 +2962,6 @@ }, "node_modules/pkg-dir": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, "license": "MIT", @@ -3284,7 +2974,6 @@ }, "node_modules/pretty-format": { "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", "dev": true, "license": "MIT", @@ -3299,7 +2988,6 @@ }, "node_modules/pretty-format/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==", "dev": true, "license": "MIT", @@ -3312,7 +3000,6 @@ }, "node_modules/prompts": { "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", "dev": true, "license": "MIT", @@ -3325,24 +3012,11 @@ } }, "node_modules/protobufjs": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", - "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", - "hasInstallScript": true, + "version": "8.7.1", + "integrity": "sha512-agdGHrXNTv0IrYscJPDou/PlEJk1c/hBZ9o/B5NH2i/nSPtPqacNxzgwf1CebXxFMjMrZH5sqv9uQuw96aGt/A==", "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" + "long": "^5.3.2" }, "engines": { "node": ">=12.0.0" @@ -3350,7 +3024,6 @@ }, "node_modules/pure-rand": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, "funding": [ @@ -3367,14 +3040,12 @@ }, "node_modules/react-is": { "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, "license": "MIT" }, "node_modules/require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "license": "MIT", "engines": { @@ -3383,7 +3054,6 @@ }, "node_modules/resolve": { "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, "license": "MIT", @@ -3404,7 +3074,6 @@ }, "node_modules/resolve-cwd": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, "license": "MIT", @@ -3417,7 +3086,6 @@ }, "node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", @@ -3427,7 +3095,6 @@ }, "node_modules/resolve.exports": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", "dev": true, "license": "MIT", @@ -3437,7 +3104,6 @@ }, "node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "license": "ISC", @@ -3447,7 +3113,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", @@ -3460,7 +3125,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", "dev": true, "license": "MIT", @@ -3470,21 +3134,18 @@ }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, "license": "ISC" }, "node_modules/sisteransi": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", "dev": true, "license": "MIT" }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", @@ -3494,7 +3155,6 @@ }, "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==", "dev": true, "license": "BSD-3-Clause", @@ -3504,7 +3164,6 @@ }, "node_modules/source-map-support": { "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, "license": "MIT", @@ -3515,14 +3174,12 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/stack-utils": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "license": "MIT", @@ -3535,7 +3192,6 @@ }, "node_modules/string-length": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "dev": true, "license": "MIT", @@ -3549,7 +3205,6 @@ }, "node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "license": "MIT", "dependencies": { @@ -3563,7 +3218,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "license": "MIT", "dependencies": { @@ -3575,7 +3229,6 @@ }, "node_modules/strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, "license": "MIT", @@ -3585,7 +3238,6 @@ }, "node_modules/strip-final-newline": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, "license": "MIT", @@ -3595,7 +3247,6 @@ }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", @@ -3608,7 +3259,6 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", @@ -3621,7 +3271,6 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", "dev": true, "license": "MIT", @@ -3634,7 +3283,6 @@ }, "node_modules/test-exclude": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, "license": "ISC", @@ -3649,14 +3297,12 @@ }, "node_modules/tmpl": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true, "license": "BSD-3-Clause" }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", @@ -3669,7 +3315,6 @@ }, "node_modules/ts-jest": { "version": "29.4.6", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", "dev": true, "license": "MIT", @@ -3722,7 +3367,6 @@ }, "node_modules/ts-jest/node_modules/semver": { "version": "7.7.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", "dev": true, "license": "ISC", @@ -3735,7 +3379,6 @@ }, "node_modules/ts-jest/node_modules/type-fest": { "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "dev": true, "license": "(MIT OR CC0-1.0)", @@ -3748,7 +3391,6 @@ }, "node_modules/type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, "license": "MIT", @@ -3758,7 +3400,6 @@ }, "node_modules/type-fest": { "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, "license": "(MIT OR CC0-1.0)", @@ -3771,7 +3412,6 @@ }, "node_modules/typescript": { "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", @@ -3785,7 +3425,6 @@ }, "node_modules/uglify-js": { "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "dev": true, "license": "BSD-2-Clause", @@ -3799,13 +3438,12 @@ }, "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/update-browserslist-db": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", "dev": true, "funding": [ @@ -3836,7 +3474,6 @@ }, "node_modules/v8-to-istanbul": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "dev": true, "license": "ISC", @@ -3851,7 +3488,6 @@ }, "node_modules/walker": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "license": "Apache-2.0", @@ -3861,7 +3497,6 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", @@ -3877,14 +3512,12 @@ }, "node_modules/wordwrap": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true, "license": "MIT" }, "node_modules/wrap-ansi": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "license": "MIT", "dependencies": { @@ -3901,14 +3534,12 @@ }, "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==", "dev": true, "license": "ISC" }, "node_modules/write-file-atomic": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "license": "ISC", @@ -3922,7 +3553,6 @@ }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "license": "ISC", "engines": { @@ -3931,14 +3561,12 @@ }, "node_modules/yallist": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true, "license": "ISC" }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "license": "MIT", "dependencies": { @@ -3956,7 +3584,6 @@ }, "node_modules/yargs-parser": { "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "license": "ISC", "engines": { @@ -3965,7 +3592,6 @@ }, "node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", diff --git a/sdks/typescript/package.json b/sdks/typescript/package.json index bf85361c..ece63843 100644 --- a/sdks/typescript/package.json +++ b/sdks/typescript/package.json @@ -1,26 +1,48 @@ { - "name": "@cortex-memory/client", - "version": "0.3.1", + "name": "cortex-memory-client", + "version": "0.3.2", "description": "Self-organizing graph memory for AI agents — TypeScript SDK", "main": "dist/index.js", "types": "dist/index.d.ts", "license": "MIT", + "author": "MikeSquared Agency ", + "homepage": "https://github.com/MikeSquared-Agency/cortex#readme", + "bugs": { + "url": "https://github.com/MikeSquared-Agency/cortex/issues" + }, "repository": { "type": "git", - "url": "https://github.com/MikeSquared-Agency/cortex" + "url": "git+https://github.com/MikeSquared-Agency/cortex.git", + "directory": "sdks/typescript" + }, + "keywords": [ + "ai-agents", + "cortex", + "graph-memory", + "memory", + "sdk" + ], + "engines": { + "node": ">=18" }, "scripts": { - "build": "tsc", + "clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"", + "build": "npm run clean && tsc", "test": "jest", "prepublishOnly": "npm run build" }, "files": [ "dist", - "proto" + "proto", + "README.md", + "LICENSE" ], "dependencies": { - "@grpc/grpc-js": "^1.14.3", - "@grpc/proto-loader": "^0.7.15" + "@grpc/grpc-js": "^1.14.4", + "@grpc/proto-loader": "^0.8.1" + }, + "overrides": { + "protobufjs": "^8.7.1" }, "devDependencies": { "@types/node": "^20.19.33", diff --git a/sdks/typescript/src/__tests__/client.test.ts b/sdks/typescript/src/__tests__/client.test.ts index 27d38003..2baf3139 100644 --- a/sdks/typescript/src/__tests__/client.test.ts +++ b/sdks/typescript/src/__tests__/client.test.ts @@ -2,10 +2,17 @@ * Unit tests for the Cortex TypeScript SDK. * All tests use MockCortex — no real server or gRPC connection required. */ -import { describe, it, expect, beforeEach } from '@jest/globals'; -import { MockCortex } from '../testing'; -import { EntityType } from '../client'; -describe('MockCortex', () => { +import { describe, it, expect, beforeEach } from "@jest/globals"; +import { MockCortex } from "../testing"; +import { Cortex, EntityType } from "../client"; + +describe("Cortex client", () => { + it("loads the bundled protobuf definition", () => { + expect(() => new Cortex("127.0.0.1:9090")).not.toThrow(); + }); +}); + +describe("MockCortex", () => { let cx: MockCortex; beforeEach(() => { @@ -15,12 +22,12 @@ describe('MockCortex', () => { // ----------------------------------------------------------------------- // Constructor // ----------------------------------------------------------------------- - describe('constructor', () => { - it('creates an empty instance with zero nodes', () => { + describe("constructor", () => { + it("creates an empty instance with zero nodes", () => { expect(cx.nodeCount).toBe(0); }); - it('can create multiple independent instances', () => { + it("can create multiple independent instances", () => { const cx2 = new MockCortex(); expect(cx).not.toBe(cx2); expect(cx.nodeCount).toBe(0); @@ -31,89 +38,93 @@ describe('MockCortex', () => { // ----------------------------------------------------------------------- // store() // ----------------------------------------------------------------------- - describe('store()', () => { - it('returns a non-empty string ID', async () => { - const id = await cx.store({ kind: 'fact', title: 'Test fact' }); - expect(typeof id).toBe('string'); + describe("store()", () => { + it("returns a non-empty string ID", async () => { + const id = await cx.store({ kind: "fact", title: "Test fact" }); + expect(typeof id).toBe("string"); expect(id.length).toBeGreaterThan(0); }); - it('increments nodeCount on each call', async () => { - await cx.store({ kind: 'fact', title: 'First' }); + it("increments nodeCount on each call", async () => { + await cx.store({ kind: "fact", title: "First" }); expect(cx.nodeCount).toBe(1); - await cx.store({ kind: 'event', title: 'Second' }); + await cx.store({ kind: "event", title: "Second" }); expect(cx.nodeCount).toBe(2); }); - it('returns unique IDs for each call', async () => { - const id1 = await cx.store({ kind: 'fact', title: 'Node A' }); - const id2 = await cx.store({ kind: 'fact', title: 'Node B' }); + it("returns unique IDs for each call", async () => { + const id1 = await cx.store({ kind: "fact", title: "Node A" }); + const id2 = await cx.store({ kind: "fact", title: "Node B" }); expect(id1).not.toBe(id2); }); - it('accepts all optional fields without error', async () => { + it("accepts all optional fields without error", async () => { const id = await cx.store({ - kind: 'note', - title: 'Annotated note', - body: 'Extended body text', - tags: ['alpha', 'beta'], + kind: "note", + title: "Annotated note", + body: "Extended body text", + tags: ["alpha", "beta"], importance: 0.8, - metadata: { project: 'cortex', env: 'test' }, - source_agent: 'kai', + metadata: { project: "cortex", env: "test" }, + source_agent: "kai", }); - expect(typeof id).toBe('string'); + expect(typeof id).toBe("string"); }); - it('records the call in the call log (assertStored passes)', async () => { - await cx.store({ kind: 'fact', title: 'Logged fact' }); - expect(() => cx.assertStored('fact', 'Logged fact')).not.toThrow(); + it("records the call in the call log (assertStored passes)", async () => { + await cx.store({ kind: "fact", title: "Logged fact" }); + expect(() => cx.assertStored("fact", "Logged fact")).not.toThrow(); }); }); // ----------------------------------------------------------------------- // search() // ----------------------------------------------------------------------- - describe('search()', () => { - it('returns results that match the query string', async () => { - await cx.store({ kind: 'fact', title: 'Rate limit is 1000/min' }); - await cx.store({ kind: 'event', title: 'Deploy complete' }); + describe("search()", () => { + it("returns results that match the query string", async () => { + await cx.store({ kind: "fact", title: "Rate limit is 1000/min" }); + await cx.store({ kind: "event", title: "Deploy complete" }); - const results = await cx.search('rate limit'); + const results = await cx.search("rate limit"); expect(results).toHaveLength(1); - expect(results[0].title).toBe('Rate limit is 1000/min'); - expect(results[0].kind).toBe('fact'); + expect(results[0].title).toBe("Rate limit is 1000/min"); + expect(results[0].kind).toBe("fact"); expect(results[0].score).toBe(0.9); }); - it('returns an empty array when nothing matches', async () => { - await cx.store({ kind: 'fact', title: 'Totally unrelated' }); - const results = await cx.search('zyx-no-match-xyz'); + it("returns an empty array when nothing matches", async () => { + await cx.store({ kind: "fact", title: "Totally unrelated" }); + const results = await cx.search("zyx-no-match-xyz"); expect(results).toHaveLength(0); }); - it('matches on body text as well as title', async () => { - await cx.store({ kind: 'note', title: 'Short title', body: 'detailed body content here' }); - const results = await cx.search('detailed body'); + it("matches on body text as well as title", async () => { + await cx.store({ + kind: "note", + title: "Short title", + body: "detailed body content here", + }); + const results = await cx.search("detailed body"); expect(results).toHaveLength(1); }); - it('is case-insensitive', async () => { - await cx.store({ kind: 'fact', title: 'Important Discovery' }); - const results = await cx.search('important discovery'); + it("is case-insensitive", async () => { + await cx.store({ kind: "fact", title: "Important Discovery" }); + const results = await cx.search("important discovery"); expect(results).toHaveLength(1); }); - it('respects the limit option', async () => { + it("respects the limit option", async () => { for (let i = 0; i < 6; i++) { - await cx.store({ kind: 'fact', title: `Item number ${i}` }); + await cx.store({ kind: "fact", title: `Item number ${i}` }); } - const results = await cx.search('Item', { limit: 3 }); + const results = await cx.search("Item", { limit: 3 }); expect(results.length).toBeLessThanOrEqual(3); }); - it('returns all results when limit is higher than match count', async () => { - await cx.store({ kind: 'fact', title: 'Just one match' }); - const results = await cx.search('one match', { limit: 100 }); + it("returns all results when limit is higher than match count", async () => { + await cx.store({ kind: "fact", title: "Just one match" }); + const results = await cx.search("one match", { limit: 100 }); expect(results).toHaveLength(1); }); }); @@ -121,48 +132,52 @@ describe('MockCortex', () => { // ----------------------------------------------------------------------- // briefing() // ----------------------------------------------------------------------- - describe('briefing()', () => { - it('returns a non-empty string', async () => { - const text = await cx.briefing('kai'); - expect(typeof text).toBe('string'); + describe("briefing()", () => { + it("returns a non-empty string", async () => { + const text = await cx.briefing("kai"); + expect(typeof text).toBe("string"); expect(text.length).toBeGreaterThan(0); }); - it('includes the agent ID in the response', async () => { - const text = await cx.briefing('my-agent'); - expect(text).toContain('my-agent'); + it("includes the agent ID in the response", async () => { + const text = await cx.briefing("my-agent"); + expect(text).toContain("my-agent"); }); - it('accepts a compact flag without error', async () => { - const text = await cx.briefing('kai', true); - expect(typeof text).toBe('string'); + it("accepts a compact flag without error", async () => { + const text = await cx.briefing("kai", true); + expect(typeof text).toBe("string"); }); }); // ----------------------------------------------------------------------- // getNode() // ----------------------------------------------------------------------- - describe('getNode()', () => { - it('returns the node when found', async () => { - const id = await cx.store({ kind: 'fact', title: 'Findable node', importance: 0.7 }); + describe("getNode()", () => { + it("returns the node when found", async () => { + const id = await cx.store({ + kind: "fact", + title: "Findable node", + importance: 0.7, + }); const node = await cx.getNode(id); expect(node).not.toBeNull(); // eslint-disable-next-line @typescript-eslint/no-explicit-any const n = node as any; expect(n.id).toBe(id); - expect(n.kind).toBe('fact'); - expect(n.title).toBe('Findable node'); + expect(n.kind).toBe("fact"); + expect(n.title).toBe("Findable node"); expect(n.importance).toBe(0.7); }); - it('returns null when the node ID does not exist', async () => { - const node = await cx.getNode('nonexistent-node-id-99999'); + it("returns null when the node ID does not exist", async () => { + const node = await cx.getNode("nonexistent-node-id-99999"); expect(node).toBeNull(); }); - it('returns null for an empty string ID', async () => { - const node = await cx.getNode(''); + it("returns null for an empty string ID", async () => { + const node = await cx.getNode(""); expect(node).toBeNull(); }); }); @@ -170,33 +185,33 @@ describe('MockCortex', () => { // ----------------------------------------------------------------------- // traverse() // ----------------------------------------------------------------------- - describe('traverse()', () => { - it('returns an object with nodes, edges, and truncated fields', async () => { - const id = await cx.store({ kind: 'concept', title: 'Root node' }); + describe("traverse()", () => { + it("returns an object with nodes, edges, and truncated fields", async () => { + const id = await cx.store({ kind: "concept", title: "Root node" }); const subgraph = await cx.traverse(id, 2); - expect(subgraph).toHaveProperty('nodes'); - expect(subgraph).toHaveProperty('edges'); - expect(subgraph).toHaveProperty('truncated'); + expect(subgraph).toHaveProperty("nodes"); + expect(subgraph).toHaveProperty("edges"); + expect(subgraph).toHaveProperty("truncated"); }); - it('nodes and edges are arrays', async () => { - const id = await cx.store({ kind: 'concept', title: 'Graph start' }); + it("nodes and edges are arrays", async () => { + const id = await cx.store({ kind: "concept", title: "Graph start" }); const subgraph = await cx.traverse(id); expect(Array.isArray(subgraph.nodes)).toBe(true); expect(Array.isArray(subgraph.edges)).toBe(true); }); - it('truncated is a boolean', async () => { - const id = await cx.store({ kind: 'concept', title: 'Any node' }); + it("truncated is a boolean", async () => { + const id = await cx.store({ kind: "concept", title: "Any node" }); const subgraph = await cx.traverse(id, 1); - expect(typeof subgraph.truncated).toBe('boolean'); + expect(typeof subgraph.truncated).toBe("boolean"); }); - it('uses default depth when not specified', async () => { - const id = await cx.store({ kind: 'concept', title: 'Default depth' }); + it("uses default depth when not specified", async () => { + const id = await cx.store({ kind: "concept", title: "Default depth" }); // Should not throw const subgraph = await cx.traverse(id); expect(subgraph).toBeDefined(); @@ -206,94 +221,94 @@ describe('MockCortex', () => { // ----------------------------------------------------------------------- // assertStored() / assertNotStored() helpers // ----------------------------------------------------------------------- - describe('assertStored()', () => { - it('passes when the call was made', async () => { - await cx.store({ kind: 'fact', title: 'Known fact' }); - expect(() => cx.assertStored('fact', 'Known fact')).not.toThrow(); + describe("assertStored()", () => { + it("passes when the call was made", async () => { + await cx.store({ kind: "fact", title: "Known fact" }); + expect(() => cx.assertStored("fact", "Known fact")).not.toThrow(); }); - it('throws when the call was NOT made', () => { - expect(() => cx.assertStored('fact', 'Missing fact')).toThrow(); + it("throws when the call was NOT made", () => { + expect(() => cx.assertStored("fact", "Missing fact")).toThrow(); }); - it('is strict about kind', async () => { - await cx.store({ kind: 'event', title: 'Same title' }); - expect(() => cx.assertStored('fact', 'Same title')).toThrow(); + it("is strict about kind", async () => { + await cx.store({ kind: "event", title: "Same title" }); + expect(() => cx.assertStored("fact", "Same title")).toThrow(); }); }); - describe('assertNotStored()', () => { - it('passes when the call was NOT made', () => { - expect(() => cx.assertNotStored('fact', 'Never stored')).not.toThrow(); + describe("assertNotStored()", () => { + it("passes when the call was NOT made", () => { + expect(() => cx.assertNotStored("fact", "Never stored")).not.toThrow(); }); - it('throws when the call WAS made', async () => { - await cx.store({ kind: 'fact', title: 'Stored fact' }); - expect(() => cx.assertNotStored('fact', 'Stored fact')).toThrow(); + it("throws when the call WAS made", async () => { + await cx.store({ kind: "fact", title: "Stored fact" }); + expect(() => cx.assertNotStored("fact", "Stored fact")).toThrow(); }); }); // ----------------------------------------------------------------------- // EntityType enum // ----------------------------------------------------------------------- - describe('EntityType', () => { - it('has all well-known values', () => { - expect(EntityType.Agent).toBe('agent'); - expect(EntityType.Company).toBe('company'); - expect(EntityType.Person).toBe('person'); - expect(EntityType.Technology).toBe('technology'); - expect(EntityType.Project).toBe('project'); - expect(EntityType.Location).toBe('location'); - expect(EntityType.Product).toBe('product'); + describe("EntityType", () => { + it("has all well-known values", () => { + expect(EntityType.Agent).toBe("agent"); + expect(EntityType.Company).toBe("company"); + expect(EntityType.Person).toBe("person"); + expect(EntityType.Technology).toBe("technology"); + expect(EntityType.Project).toBe("project"); + expect(EntityType.Location).toBe("location"); + expect(EntityType.Product).toBe("product"); }); }); // ----------------------------------------------------------------------- // storeEntity() // ----------------------------------------------------------------------- - describe('storeEntity()', () => { - it('returns a non-empty string ID', async () => { + describe("storeEntity()", () => { + it("returns a non-empty string ID", async () => { const id = await cx.storeEntity({ - title: 'Anthropic', + title: "Anthropic", entityType: EntityType.Company, }); - expect(typeof id).toBe('string'); + expect(typeof id).toBe("string"); expect(id.length).toBeGreaterThan(0); }); it('creates a node with kind "entity"', async () => { await cx.storeEntity({ - title: 'Anthropic', + title: "Anthropic", entityType: EntityType.Company, }); - expect(() => cx.assertStored('entity', 'Anthropic')).not.toThrow(); + expect(() => cx.assertStored("entity", "Anthropic")).not.toThrow(); }); - it('sets entity_type in metadata', async () => { + it("sets entity_type in metadata", async () => { const id = await cx.storeEntity({ - title: 'Anthropic', + title: "Anthropic", entityType: EntityType.Company, }); const node = await cx.getNode(id); // eslint-disable-next-line @typescript-eslint/no-explicit-any - expect((node as any).metadata.entity_type).toBe('company'); + expect((node as any).metadata.entity_type).toBe("company"); }); - it('sets aliases in metadata as JSON string', async () => { + it("sets aliases in metadata as JSON string", async () => { const id = await cx.storeEntity({ - title: 'Anthropic', + title: "Anthropic", entityType: EntityType.Company, - aliases: ['anthropic-ai', 'Anthropic PBC'], + aliases: ["anthropic-ai", "Anthropic PBC"], }); const node = await cx.getNode(id); // eslint-disable-next-line @typescript-eslint/no-explicit-any const aliases = JSON.parse((node as any).metadata.aliases); - expect(aliases).toEqual(['anthropic-ai', 'Anthropic PBC']); + expect(aliases).toEqual(["anthropic-ai", "Anthropic PBC"]); }); - it('omits aliases when not provided', async () => { + it("omits aliases when not provided", async () => { const id = await cx.storeEntity({ - title: 'Anthropic', + title: "Anthropic", entityType: EntityType.Company, }); const node = await cx.getNode(id); @@ -301,45 +316,45 @@ describe('MockCortex', () => { expect((node as any).metadata.aliases).toBeUndefined(); }); - it('merges extra metadata with entity fields', async () => { + it("merges extra metadata with entity fields", async () => { const id = await cx.storeEntity({ - title: 'Anthropic', + title: "Anthropic", entityType: EntityType.Company, - metadata: { source_url: 'https://anthropic.com' }, + metadata: { source_url: "https://anthropic.com" }, }); const node = await cx.getNode(id); // eslint-disable-next-line @typescript-eslint/no-explicit-any const meta = (node as any).metadata; - expect(meta.entity_type).toBe('company'); - expect(meta.source_url).toBe('https://anthropic.com'); + expect(meta.entity_type).toBe("company"); + expect(meta.source_url).toBe("https://anthropic.com"); }); - it('accepts custom entity type strings', async () => { + it("accepts custom entity type strings", async () => { const id = await cx.storeEntity({ - title: 'Cortex', - entityType: 'framework', + title: "Cortex", + entityType: "framework", }); const node = await cx.getNode(id); // eslint-disable-next-line @typescript-eslint/no-explicit-any - expect((node as any).metadata.entity_type).toBe('framework'); + expect((node as any).metadata.entity_type).toBe("framework"); }); - it('passes through optional fields', async () => { + it("passes through optional fields", async () => { const id = await cx.storeEntity({ - title: 'Anthropic', + title: "Anthropic", entityType: EntityType.Company, - body: 'AI safety company', - tags: ['ai', 'safety'], + body: "AI safety company", + tags: ["ai", "safety"], importance: 0.9, - source_agent: 'kai', + source_agent: "kai", }); const node = await cx.getNode(id); // eslint-disable-next-line @typescript-eslint/no-explicit-any const n = node as any; - expect(n.body).toBe('AI safety company'); - expect(n.tags).toEqual(['ai', 'safety']); + expect(n.body).toBe("AI safety company"); + expect(n.tags).toEqual(["ai", "safety"]); expect(n.importance).toBe(0.9); - expect(n.source_agent).toBe('kai'); + expect(n.source_agent).toBe("kai"); }); }); }); diff --git a/sdks/typescript/src/client.ts b/sdks/typescript/src/client.ts index dd83db76..11b71af0 100644 --- a/sdks/typescript/src/client.ts +++ b/sdks/typescript/src/client.ts @@ -6,7 +6,7 @@ * * @example * ```typescript - * import { Cortex } from '@cortex-memory/client'; + * import { Cortex } from 'cortex-memory-client'; * * const cx = new Cortex('localhost:9090'); * @@ -17,12 +17,12 @@ * ``` */ -import * as grpc from '@grpc/grpc-js'; -import * as protoLoader from '@grpc/proto-loader'; -import path from 'path'; +import * as grpc from "@grpc/grpc-js"; +import * as protoLoader from "@grpc/proto-loader"; +import path from "path"; // Proto file is bundled inside the package at ../proto/cortex.proto -const PROTO_PATH = path.join(__dirname, '..', 'proto', 'cortex.proto'); +const PROTO_PATH = path.join(__dirname, "..", "proto", "cortex.proto"); const LOADER_OPTIONS: protoLoader.Options = { keepCase: true, @@ -30,18 +30,18 @@ const LOADER_OPTIONS: protoLoader.Options = { enums: String, defaults: true, oneofs: true, - includeDirs: [path.join(__dirname, '..', 'proto')], + includeDirs: [path.join(__dirname, "..", "proto")], }; /** Well-known entity type constants for metadata conventions. */ export enum EntityType { - Agent = 'agent', - Company = 'company', - Person = 'person', - Technology = 'technology', - Project = 'project', - Location = 'location', - Product = 'product', + Agent = "agent", + Company = "company", + Person = "person", + Technology = "technology", + Project = "project", + Location = "location", + Product = "product", } /** Options for storing an entity node. */ @@ -126,7 +126,7 @@ export class Cortex { metadata.aliases = JSON.stringify(options.aliases); } return this.store({ - kind: 'entity', + kind: "entity", title: options.title, body: options.body, tags: options.tags, @@ -138,14 +138,14 @@ export class Cortex { /** Store a knowledge node. Returns the new node ID. */ async store(options: StoreOptions): Promise { - return this._call('CreateNode', { + return this._call("CreateNode", { kind: options.kind, title: options.title, body: options.body ?? options.title, importance: options.importance ?? 0.5, tags: options.tags ?? [], metadata: options.metadata ?? {}, - source_agent: options.source_agent ?? '', + source_agent: options.source_agent ?? "", }).then((r: { id: string }) => r.id); } @@ -163,23 +163,31 @@ export class Cortex { query: string, opts: { limit?: number; kindFilter?: string[] } = {}, ): Promise { - const resp = await this._call('SimilaritySearch', { + const resp = await this._call("SimilaritySearch", { query, limit: opts.limit ?? 10, kind_filter: opts.kindFilter ?? [], }); // SearchResponse.results is SearchResultEntry[] where each has node + score - return (resp.results ?? []).map((r: { - score: number; - node: { id: string; title: string; kind: string; body: string; importance: number }; - }) => ({ - score: r.score, - nodeId: r.node?.id ?? '', - title: r.node?.title ?? '', - kind: r.node?.kind ?? '', - body: r.node?.body ?? '', - importance: r.node?.importance ?? 0, - })); + return (resp.results ?? []).map( + (r: { + score: number; + node: { + id: string; + title: string; + kind: string; + body: string; + importance: number; + }; + }) => ({ + score: r.score, + nodeId: r.node?.id ?? "", + title: r.node?.title ?? "", + kind: r.node?.kind ?? "", + body: r.node?.body ?? "", + importance: r.node?.importance ?? 0, + }), + ); } /** @@ -194,22 +202,30 @@ export class Cortex { anchorIds: string[] = [], opts: { limit?: number } = {}, ): Promise { - const resp = await this._call('HybridSearch', { + const resp = await this._call("HybridSearch", { query, anchor_ids: anchorIds, limit: opts.limit ?? 10, }); - return (resp.results ?? []).map((r: { - combined_score: number; - node: { id: string; title: string; kind: string; body: string; importance: number }; - }) => ({ - score: r.combined_score, - nodeId: r.node?.id ?? '', - title: r.node?.title ?? '', - kind: r.node?.kind ?? '', - body: r.node?.body ?? '', - importance: r.node?.importance ?? 0, - })); + return (resp.results ?? []).map( + (r: { + combined_score: number; + node: { + id: string; + title: string; + kind: string; + body: string; + importance: number; + }; + }) => ({ + score: r.combined_score, + nodeId: r.node?.id ?? "", + title: r.node?.title ?? "", + kind: r.node?.kind ?? "", + body: r.node?.body ?? "", + importance: r.node?.importance ?? 0, + }), + ); } /** @@ -220,18 +236,18 @@ export class Cortex { * @returns Rendered markdown string. */ async briefing(agentId: string, compact = false): Promise { - const resp = await this._call('GetBriefing', { + const resp = await this._call("GetBriefing", { agent_id: agentId, compact, }); - return resp.rendered ?? ''; + return resp.rendered ?? ""; } /** * Graph traversal from *nodeId* up to *depth* hops. */ async traverse(nodeId: string, depth = 2): Promise { - const resp = await this._call('Traverse', { + const resp = await this._call("Traverse", { start_ids: [nodeId], max_depth: depth, }); @@ -245,7 +261,7 @@ export class Cortex { /** Get a node by ID. Returns `null` if not found. */ async getNode(id: string): Promise { try { - return await this._call('GetNode', { id }); + return await this._call("GetNode", { id }); } catch (err: unknown) { if (_isGrpcError(err, grpc.status.NOT_FOUND)) return null; throw err; @@ -260,19 +276,22 @@ export class Cortex { private _call(method: string, req: unknown): Promise { return new Promise((resolve, reject) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any - (this.client[method] as any)(req, (err: Error | null, response: unknown) => { - if (err) reject(err); - else resolve(response); - }); + (this.client[method] as any)( + req, + (err: Error | null, response: unknown) => { + if (err) reject(err); + else resolve(response); + }, + ); }); } } function _isGrpcError(err: unknown, code: number): boolean { return ( - typeof err === 'object' && + typeof err === "object" && err !== null && - 'code' in err && + "code" in err && (err as { code: number }).code === code ); } diff --git a/sdks/typescript/src/testing.ts b/sdks/typescript/src/testing.ts index 5add0afc..41ab62ad 100644 --- a/sdks/typescript/src/testing.ts +++ b/sdks/typescript/src/testing.ts @@ -6,7 +6,7 @@ * * @example * ```typescript - * import { MockCortex } from '@cortex-memory/client'; + * import { MockCortex } from 'cortex-memory-client'; * * describe('my agent', () => { * it('stores and retrieves knowledge', async () => { @@ -20,7 +20,12 @@ * ``` */ -import type { SearchResult, StoreOptions, StoreEntityOptions, Subgraph } from './client'; +import type { + SearchResult, + StoreOptions, + StoreEntityOptions, + Subgraph, +} from "./client"; interface StoredNode { id: string; @@ -57,7 +62,7 @@ export class MockCortex { metadata.aliases = JSON.stringify(options.aliases); } return this.store({ - kind: 'entity', + kind: "entity", title: options.title, body: options.body, tags: options.tags, @@ -77,10 +82,10 @@ export class MockCortex { tags: options.tags ?? [], importance: options.importance ?? 0.5, metadata: options.metadata ?? {}, - source_agent: options.source_agent ?? '', + source_agent: options.source_agent ?? "", }; this.nodes.set(id, node); - this.callLog.push({ method: 'store', args: [options] }); + this.callLog.push({ method: "store", args: [options] }); return id; } @@ -96,7 +101,10 @@ export class MockCortex { const limit = opts.limit ?? 10; const results: SearchResult[] = []; for (const n of this.nodes.values()) { - if (n.title.toLowerCase().includes(q) || n.body.toLowerCase().includes(q)) { + if ( + n.title.toLowerCase().includes(q) || + n.body.toLowerCase().includes(q) + ) { results.push({ score: 0.9, nodeId: n.id, @@ -139,7 +147,7 @@ export class MockCortex { assertStored(kind: string, title: string): void { const found = this.callLog.some( (e) => - e.method === 'store' && + e.method === "store" && e.args[0].kind === kind && e.args[0].title === title, ); @@ -155,7 +163,7 @@ export class MockCortex { assertNotStored(kind: string, title: string): void { const found = this.callLog.some( (e) => - e.method === 'store' && + e.method === "store" && e.args[0].kind === kind && e.args[0].title === title, ); @@ -176,15 +184,17 @@ export class MockCortex { function _uuid(): string { // Prefer native crypto.randomUUID if available (Node ≥ 14.17) if ( - typeof globalThis !== 'undefined' && - typeof (globalThis as unknown as { crypto?: { randomUUID?: () => string } }).crypto - ?.randomUUID === 'function' + typeof globalThis !== "undefined" && + typeof (globalThis as unknown as { crypto?: { randomUUID?: () => string } }) + .crypto?.randomUUID === "function" ) { - return (globalThis as unknown as { crypto: { randomUUID: () => string } }).crypto.randomUUID(); + return ( + globalThis as unknown as { crypto: { randomUUID: () => string } } + ).crypto.randomUUID(); } // Fallback - return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { + return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => { const r = (Math.random() * 16) | 0; - return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16); + return (c === "x" ? r : (r & 0x3) | 0x8).toString(16); }); } diff --git a/sdks/typescript/tsconfig.json b/sdks/typescript/tsconfig.json index 6cb3bc7b..bd2a22f5 100644 --- a/sdks/typescript/tsconfig.json +++ b/sdks/typescript/tsconfig.json @@ -15,5 +15,5 @@ "resolveJsonModule": true }, "include": ["src"], - "exclude": ["node_modules", "dist"] + "exclude": ["node_modules", "dist", "src/__tests__"] }