diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..3a9393e --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,52 @@ +name: Deploy Docs + +on: + push: + branches: [main] + paths: + - 'website/**' + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: false + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - uses: oven-sh/setup-bun@v2 + with: + bun-version: 1.1.38 + + - name: Install dependencies + working-directory: website + run: bun install + + - name: Build docs + working-directory: website + run: bun run docs:build + + - uses: actions/upload-pages-artifact@v3 + with: + path: website/.vitepress/dist + + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + needs: build + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 1f3b03e..1619ba8 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ __pycache__/ .pytest_cache/ mempal.yaml .a5c/ +.claude/ +.codex/ +.codex # Environment .env diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 0000000..6ae81f6 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,7 @@ +[build] + base = "website" + command = "bun run docs:build" + publish = ".vitepress/dist" + +[build.environment] + DOCS_BASE = "/" diff --git a/website/.gitignore b/website/.gitignore new file mode 100644 index 0000000..519ac39 --- /dev/null +++ b/website/.gitignore @@ -0,0 +1,36 @@ +# dependencies (bun install) +node_modules + +# output +out +dist +.vitepress/dist +.vitepress/.temp +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +*.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/website/.vitepress/config.mts b/website/.vitepress/config.mts new file mode 100644 index 0000000..997a864 --- /dev/null +++ b/website/.vitepress/config.mts @@ -0,0 +1,103 @@ +import { defineConfig } from 'vitepress' +import { withMermaid } from 'vitepress-plugin-mermaid' + +const docsBase = process.env.DOCS_BASE || '/mempalace/' + +export default withMermaid( + defineConfig({ + title: 'MemPalace', + description: 'Give your AI a memory. Local-first storage and retrieval for AI workflows, with benchmark results and MCP tooling.', + base: docsBase, + + head: [ + ['link', { rel: 'icon', href: `${docsBase}mempalace_logo.png` }], + ['link', { rel: 'preconnect', href: 'https://fonts.googleapis.com' }], + ['link', { rel: 'preconnect', href: 'https://fonts.gstatic.com', crossorigin: '' }], + ['link', { href: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap', rel: 'stylesheet' }], + ['meta', { property: 'og:title', content: 'MemPalace — AI Memory System' }], + ['meta', { property: 'og:description', content: '96.6% LongMemEval recall. Zero API calls. Local, free, open source.' }], + ['meta', { property: 'og:image', content: `${docsBase}mempalace_logo.png` }], + ], + + themeConfig: { + logo: '/mempalace_logo.png', + siteTitle: 'MemPalace', + + nav: [ + { text: 'Guide', link: '/guide/getting-started' }, + { text: 'Concepts', link: '/concepts/the-palace' }, + { text: 'Reference', link: '/reference/cli' }, + ], + + sidebar: { + '/guide/': [ + { + text: 'Guide', + items: [ + { text: 'Getting Started', link: '/guide/getting-started' }, + { text: 'Mining Your Data', link: '/guide/mining' }, + { text: 'Searching Memories', link: '/guide/searching' }, + { text: 'MCP Integration', link: '/guide/mcp-integration' }, + { text: 'Claude Code Plugin', link: '/guide/claude-code' }, + { text: 'Gemini CLI', link: '/guide/gemini-cli' }, + { text: 'OpenClaw Skill', link: '/guide/openclaw' }, + { text: 'Local Models', link: '/guide/local-models' }, + { text: 'Auto-Save Hooks', link: '/guide/hooks' }, + { text: 'Configuration', link: '/guide/configuration' }, + ], + }, + ], + '/concepts/': [ + { + text: 'Concepts', + items: [ + { text: 'The Palace', link: '/concepts/the-palace' }, + { text: 'Memory Stack', link: '/concepts/memory-stack' }, + { text: 'AAAK Dialect', link: '/concepts/aaak-dialect' }, + { text: 'Knowledge Graph', link: '/concepts/knowledge-graph' }, + { text: 'Specialist Agents', link: '/concepts/agents' }, + { text: 'Contradiction Detection', link: '/concepts/contradiction-detection' }, + ], + }, + ], + '/reference/': [ + { + text: 'Reference', + items: [ + { text: 'CLI Commands', link: '/reference/cli' }, + { text: 'MCP Tools', link: '/reference/mcp-tools' }, + { text: 'Python API', link: '/reference/python-api' }, + { text: 'API Reference', link: '/reference/api-reference' }, + { text: 'Module Map', link: '/reference/modules' }, + { text: 'Benchmarks', link: '/reference/benchmarks' }, + { text: 'Contributing', link: '/reference/contributing' }, + ], + }, + ], + }, + + socialLinks: [ + { icon: 'github', link: 'https://github.com/milla-jovovich/mempalace' }, + { icon: 'discord', link: 'https://discord.com/invite/ycTQQCu6kn' }, + ], + + search: { + provider: 'local', + }, + + footer: { + message: 'Released under the MIT License.', + copyright: 'Copyright © 2026 MemPalace contributors', + }, + + editLink: { + pattern: 'https://github.com/milla-jovovich/mempalace/edit/main/website/:path', + text: 'Edit this page on GitHub', + }, + }, + + mermaid: { + theme: 'dark', + }, + }) +) diff --git a/website/.vitepress/theme/index.ts b/website/.vitepress/theme/index.ts new file mode 100644 index 0000000..48d1b25 --- /dev/null +++ b/website/.vitepress/theme/index.ts @@ -0,0 +1,6 @@ +import DefaultTheme from 'vitepress/theme' +import './style.css' + +export default { + extends: DefaultTheme, +} diff --git a/website/.vitepress/theme/style.css b/website/.vitepress/theme/style.css new file mode 100644 index 0000000..4aacc70 --- /dev/null +++ b/website/.vitepress/theme/style.css @@ -0,0 +1,215 @@ +/* ── MemPalace Custom Theme ──────────────────────────────────────────── */ +/* Deep indigo / cyan palette — evoking architectural grandeur */ + +:root { + /* Brand palette */ + --mp-indigo: #4f46e5; + --mp-indigo-light: #6366f1; + --mp-indigo-dark: #3730a3; + --mp-cyan: #06b6d4; + --mp-cyan-light: #22d3ee; + --mp-purple: #8b5cf6; + --mp-purple-light: #a78bfa; + --mp-emerald: #10b981; + --mp-amber: #f59e0b; + + /* VitePress overrides */ + --vp-c-brand-1: var(--mp-indigo); + --vp-c-brand-2: var(--mp-indigo-light); + --vp-c-brand-3: var(--mp-purple); + --vp-c-brand-soft: rgba(79, 70, 229, 0.14); + + --vp-font-family-base: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + --vp-font-family-mono: 'JetBrains Mono', 'Fira Code', monospace; + + /* Home hero gradient */ + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: linear-gradient(135deg, var(--mp-indigo) 0%, var(--mp-cyan) 50%, var(--mp-purple) 100%); + --vp-home-hero-image-background-image: linear-gradient(135deg, rgba(79, 70, 229, 0.25) 0%, rgba(6, 182, 212, 0.25) 50%, rgba(139, 92, 246, 0.15) 100%); + --vp-home-hero-image-filter: blur(56px); + + /* Button colors */ + --vp-button-brand-border: transparent; + --vp-button-brand-text: #ffffff; + --vp-button-brand-bg: var(--mp-indigo); + --vp-button-brand-hover-border: transparent; + --vp-button-brand-hover-text: #ffffff; + --vp-button-brand-hover-bg: var(--mp-indigo-light); + + --vp-button-alt-border: rgba(79, 70, 229, 0.25); + --vp-button-alt-text: var(--mp-indigo); + --vp-button-alt-bg: rgba(79, 70, 229, 0.08); + --vp-button-alt-hover-border: rgba(79, 70, 229, 0.4); + --vp-button-alt-hover-text: var(--mp-indigo-dark); + --vp-button-alt-hover-bg: rgba(79, 70, 229, 0.14); +} + +/* Dark mode overrides */ +.dark { + --vp-c-brand-1: var(--mp-cyan-light); + --vp-c-brand-2: var(--mp-cyan); + --vp-c-brand-3: var(--mp-purple-light); + --vp-c-brand-soft: rgba(6, 182, 212, 0.14); + + --vp-button-brand-bg: var(--mp-indigo-light); + --vp-button-brand-hover-bg: var(--mp-indigo); + + --vp-button-alt-border: rgba(34, 211, 238, 0.25); + --vp-button-alt-text: var(--mp-cyan-light); + --vp-button-alt-bg: rgba(34, 211, 238, 0.08); + --vp-button-alt-hover-border: rgba(34, 211, 238, 0.4); + --vp-button-alt-hover-text: var(--mp-cyan); + --vp-button-alt-hover-bg: rgba(34, 211, 238, 0.14); + + --vp-home-hero-image-background-image: linear-gradient(135deg, rgba(99, 102, 241, 0.3) 0%, rgba(6, 182, 212, 0.3) 50%, rgba(139, 92, 246, 0.2) 100%); +} + +/* ── Hero section ───────────────────────────────────────────────────── */ + +.VPHero .VPImage { + max-width: 180px; + border-radius: 20px; +} + +.VPHero .name { + font-weight: 700 !important; +} + +.VPHero .text { + font-weight: 500; + background: linear-gradient(135deg, var(--vp-c-text-1) 0%, var(--mp-indigo-light) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +.dark .VPHero .text { + background: linear-gradient(135deg, var(--vp-c-text-1) 0%, var(--mp-cyan-light) 100%); + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + background-clip: text; +} + +/* ── Feature cards ──────────────────────────────────────────────────── */ + +.VPFeature { + transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + border: 1px solid var(--vp-c-divider); +} + +.VPFeature:hover { + transform: translateY(-4px); + border-color: var(--mp-indigo); + box-shadow: 0 12px 40px rgba(79, 70, 229, 0.12); +} + +.dark .VPFeature:hover { + border-color: var(--mp-cyan); + box-shadow: 0 12px 40px rgba(6, 182, 212, 0.12); +} + +.VPFeature .title { + font-weight: 600; +} + +/* ── Sidebar ────────────────────────────────────────────────────────── */ + +.VPSidebar .VPSidebarItem .text { + transition: color 0.2s ease; +} + +.VPSidebar .VPSidebarItem.is-active .text { + color: var(--mp-indigo) !important; + font-weight: 600; +} + +.dark .VPSidebar .VPSidebarItem.is-active .text { + color: var(--mp-cyan-light) !important; +} + +/* ── Code blocks ────────────────────────────────────────────────────── */ + +.vp-doc div[class*='language-'] { + border: 1px solid var(--vp-c-divider); + border-radius: 8px; +} + +.dark .vp-doc div[class*='language-'] { + border-color: rgba(6, 182, 212, 0.15); +} + +/* ── Custom containers ──────────────────────────────────────────────── */ + +.vp-doc .custom-block.tip { + border-color: var(--mp-cyan); +} + +.vp-doc .custom-block.warning { + border-color: var(--mp-amber); +} + +.vp-doc .custom-block.info { + border-color: var(--mp-indigo); +} + +/* ── Tables ─────────────────────────────────────────────────────────── */ + +.vp-doc table { + border-radius: 8px; + overflow: hidden; +} + +.vp-doc th { + background: rgba(79, 70, 229, 0.06); + font-weight: 600; +} + +.dark .vp-doc th { + background: rgba(6, 182, 212, 0.08); +} + +/* ── Nav ────────────────────────────────────────────────────────────── */ + +.VPNavBar .VPNavBarTitle .title { + font-weight: 700; + letter-spacing: -0.01em; +} + +/* ── Footer ─────────────────────────────────────────────────────────── */ + +.VPFooter { + border-top: 1px solid var(--vp-c-divider); +} + +/* ── Scrollbar ──────────────────────────────────────────────────────── */ + +::-webkit-scrollbar { + width: 6px; +} + +::-webkit-scrollbar-thumb { + background: var(--vp-c-divider); + border-radius: 3px; +} + +::-webkit-scrollbar-thumb:hover { + background: var(--mp-indigo); +} + +.dark ::-webkit-scrollbar-thumb:hover { + background: var(--mp-cyan); +} + +/* ── Smooth transitions ─────────────────────────────────────────────── */ + +a, .VPLink { + transition: color 0.2s ease; +} + +.VPButton { + transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); +} + +.VPButton:hover { + transform: translateY(-1px); +} diff --git a/website/bun.lock b/website/bun.lock new file mode 100644 index 0000000..b362430 --- /dev/null +++ b/website/bun.lock @@ -0,0 +1,633 @@ +{ + "lockfileVersion": 1, + "configVersion": 1, + "workspaces": { + "": { + "name": "website", + "devDependencies": { + "@lucide/vue": "^1.8.0", + "mermaid": "^11.14.0", + "vitepress": "^1.6.4", + "vitepress-plugin-mermaid": "^2.0.17", + "vue": "^3.5.32", + }, + }, + }, + "packages": { + "@algolia/abtesting": ["@algolia/abtesting@1.16.1", "", { "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-Xxk4l00pYI+jE0PNw8y0MvsQWh5278WRtZQav8/BMMi3HKi2xmeuqe11WJ3y8/6nuBHdv39w76OpJb09TMfAVQ=="], + + "@algolia/autocomplete-core": ["@algolia/autocomplete-core@1.17.7", "", { "dependencies": { "@algolia/autocomplete-plugin-algolia-insights": "1.17.7", "@algolia/autocomplete-shared": "1.17.7" } }, "sha512-BjiPOW6ks90UKl7TwMv7oNQMnzU+t/wk9mgIDi6b1tXpUek7MW0lbNOUHpvam9pe3lVCf4xPFT+lK7s+e+fs7Q=="], + + "@algolia/autocomplete-plugin-algolia-insights": ["@algolia/autocomplete-plugin-algolia-insights@1.17.7", "", { "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "search-insights": ">= 1 < 3" } }, "sha512-Jca5Ude6yUOuyzjnz57og7Et3aXjbwCSDf/8onLHSQgw1qW3ALl9mrMWaXb5FmPVkV3EtkD2F/+NkT6VHyPu9A=="], + + "@algolia/autocomplete-preset-algolia": ["@algolia/autocomplete-preset-algolia@1.17.7", "", { "dependencies": { "@algolia/autocomplete-shared": "1.17.7" }, "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-ggOQ950+nwbWROq2MOCIL71RE0DdQZsceqrg32UqnhDz8FlO9rL8ONHNsI2R1MH0tkgVIDKI/D0sMiUchsFdWA=="], + + "@algolia/autocomplete-shared": ["@algolia/autocomplete-shared@1.17.7", "", { "peerDependencies": { "@algolia/client-search": ">= 4.9.1 < 6", "algoliasearch": ">= 4.9.1 < 6" } }, "sha512-o/1Vurr42U/qskRSuhBH+VKxMvkkUVTLU6WZQr+L5lGZZLYWyhdzWjW0iGXY7EkwRTjBqvN2EsR81yCTGV/kmg=="], + + "@algolia/client-abtesting": ["@algolia/client-abtesting@5.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-4peZlPXMwTOey9q1rQKMdCnwZb/E95/1e+7KujXpLLSh0FawJzg//U2NM+r4AiJy4+naT2MTBhj0K30yshnVTA=="], + + "@algolia/client-analytics": ["@algolia/client-analytics@5.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-i+aWHHG8NZvGFHtPeMZkxL2Loc6Fm7iaRo15lYSMx8gFL+at9vgdWxhka7mD1fqxkrxXsQstUBCIsSY8FvkEOw=="], + + "@algolia/client-common": ["@algolia/client-common@5.50.1", "", {}, "sha512-Hw52Fwapyk/7hMSV/fI4+s3H9MGZEUcRh4VphyXLAk2oLYdndVUkc6KBi0zwHSzwPAr+ZBwFPe2x6naUt9mZGw=="], + + "@algolia/client-insights": ["@algolia/client-insights@5.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-Bn/wtwhJ7p1OD/6pY+Zzn+zlu2N/SJnH46md/PAbvqIzmjVuwjNwD4y0vV5Ov8naeukXdd7UU9v550+v8+mtlg=="], + + "@algolia/client-personalization": ["@algolia/client-personalization@5.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-0V4Tu0RWR8YxkgI9EPVOZHGE4K5pEIhkLNN0CTkP/rnPsqaaSQpNMYW3/mGWdiKOWbX0iVmwLB9QESk3H0jS5g=="], + + "@algolia/client-query-suggestions": ["@algolia/client-query-suggestions@5.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-jofcWNYMXJDDr87Z2eivlWY6o71Zn7F7aOvQCXSDAo9QTlyf7BhXEsZymLUvF0O1yU9Q9wvrjAWn8uVHYnAvgw=="], + + "@algolia/client-search": ["@algolia/client-search@5.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-OteRb8WubcmEvU0YlMJwCXs3Q6xrdkb0v50/qZBJP1TF0CvujFZQM++9BjEkTER/Jr9wbPHvjSFKnbMta0b4dQ=="], + + "@algolia/ingestion": ["@algolia/ingestion@1.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-0GmfSgDQK6oiIVXnJvGxtNFOfosBspRTR7csCOYCTL1P8QtxX2vDCIKwTM7xdSAEbJaZ43QlWg25q0Qdsndz8Q=="], + + "@algolia/monitoring": ["@algolia/monitoring@1.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-ySuigKEe4YjYV3si8NVk9BHQpFj/1B+ON7DhhvTvbrZJseHQQloxzq0yHwKmznSdlO6C956fx4pcfOKkZClsyg=="], + + "@algolia/recommend": ["@algolia/recommend@5.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-Cp8T/B0gVmjFlzzp6eP47hwKh5FGyeqQp1N48/ANDdvdiQkPqLyFHQVDwLBH0LddfIPQE+yqmZIgmKc82haF4A=="], + + "@algolia/requester-browser-xhr": ["@algolia/requester-browser-xhr@5.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1" } }, "sha512-XKdGGLikfrlK66ZSXh/vWcXZZ8Vg3byDFbJD8pwEvN1FoBRGxhxya476IY2ohoTymLa4qB5LBRlIa+2TLHx3Uw=="], + + "@algolia/requester-fetch": ["@algolia/requester-fetch@5.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1" } }, "sha512-mBAU6WyVsDwhHyGM+nodt1/oebHxgvuLlOAoMGbj/1i6LygDHZWDgL1t5JEs37x9Aywv7ZGhqbM1GsfZ54sU6g=="], + + "@algolia/requester-node-http": ["@algolia/requester-node-http@5.50.1", "", { "dependencies": { "@algolia/client-common": "5.50.1" } }, "sha512-qmo1LXrNKLHvJE6mdQbLnsZAoZvj7VyF2ft4xmbSGWI2WWm87fx/CjUX4kEExt4y0a6T6nEts6ofpUfH5TEE1A=="], + + "@antfu/install-pkg": ["@antfu/install-pkg@1.1.0", "", { "dependencies": { "package-manager-detector": "^1.3.0", "tinyexec": "^1.0.1" } }, "sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ=="], + + "@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="], + + "@babel/parser": ["@babel/parser@7.29.2", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA=="], + + "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], + + "@braintree/sanitize-url": ["@braintree/sanitize-url@7.1.2", "", {}, "sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA=="], + + "@chevrotain/cst-dts-gen": ["@chevrotain/cst-dts-gen@12.0.0", "", { "dependencies": { "@chevrotain/gast": "12.0.0", "@chevrotain/types": "12.0.0" } }, "sha512-fSL4KXjTl7cDgf0B5Rip9Q05BOrYvkJV/RrBTE/bKDN096E4hN/ySpcBK5B24T76dlQ2i32Zc3PAE27jFnFrKg=="], + + "@chevrotain/gast": ["@chevrotain/gast@12.0.0", "", { "dependencies": { "@chevrotain/types": "12.0.0" } }, "sha512-1ne/m3XsIT8aEdrvT33so0GUC+wkctpUPK6zU9IlOyJLUbR0rg4G7ZiApiJbggpgPir9ERy3FRjT6T7lpgetnQ=="], + + "@chevrotain/regexp-to-ast": ["@chevrotain/regexp-to-ast@12.0.0", "", {}, "sha512-p+EW9MaJwgaHguhoqwOtx/FwuGr+DnNn857sXWOi/mClXIkPGl3rn7hGNWvo31HA3vyeQxjqe+H36yZJwYU8cA=="], + + "@chevrotain/types": ["@chevrotain/types@12.0.0", "", {}, "sha512-S+04vjFQKeuYw0/eW3U52LkAHQsB1ASxsPGsLPUyQgrZ2iNNibQrsidruDzjEX2JYfespXMG0eZmXlhA6z7nWA=="], + + "@chevrotain/utils": ["@chevrotain/utils@12.0.0", "", {}, "sha512-lB59uJoaGIfOOL9knQqQRfhl9g7x8/wqFkp13zTdkRu1huG9kg6IJs1O8hqj9rs6h7orGxHJUKb+mX3rPbWGhA=="], + + "@docsearch/css": ["@docsearch/css@3.8.2", "", {}, "sha512-y05ayQFyUmCXze79+56v/4HpycYF3uFqB78pLPrSV5ZKAlDuIAAJNhaRi8tTdRNXh05yxX/TyNnzD6LwSM89vQ=="], + + "@docsearch/js": ["@docsearch/js@3.8.2", "", { "dependencies": { "@docsearch/react": "3.8.2", "preact": "^10.0.0" } }, "sha512-Q5wY66qHn0SwA7Taa0aDbHiJvaFJLOJyHmooQ7y8hlwwQLQ/5WwCcoX0g7ii04Qi2DJlHsd0XXzJ8Ypw9+9YmQ=="], + + "@docsearch/react": ["@docsearch/react@3.8.2", "", { "dependencies": { "@algolia/autocomplete-core": "1.17.7", "@algolia/autocomplete-preset-algolia": "1.17.7", "@docsearch/css": "3.8.2", "algoliasearch": "^5.14.2" }, "peerDependencies": { "@types/react": ">= 16.8.0 < 19.0.0", "react": ">= 16.8.0 < 19.0.0", "react-dom": ">= 16.8.0 < 19.0.0", "search-insights": ">= 1 < 3" }, "optionalPeers": ["@types/react", "react", "react-dom", "search-insights"] }, "sha512-xCRrJQlTt8N9GU0DG4ptwHRkfnSnD/YpdeaXe02iKfqs97TkZJv60yE+1eq/tjPcVnTW8dP5qLP7itifFVV5eg=="], + + "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="], + + "@esbuild/android-arm": ["@esbuild/android-arm@0.21.5", "", { "os": "android", "cpu": "arm" }, "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg=="], + + "@esbuild/android-arm64": ["@esbuild/android-arm64@0.21.5", "", { "os": "android", "cpu": "arm64" }, "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A=="], + + "@esbuild/android-x64": ["@esbuild/android-x64@0.21.5", "", { "os": "android", "cpu": "x64" }, "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA=="], + + "@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.21.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ=="], + + "@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.21.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw=="], + + "@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.21.5", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g=="], + + "@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.21.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ=="], + + "@esbuild/linux-arm": ["@esbuild/linux-arm@0.21.5", "", { "os": "linux", "cpu": "arm" }, "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA=="], + + "@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.21.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q=="], + + "@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.21.5", "", { "os": "linux", "cpu": "ia32" }, "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg=="], + + "@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg=="], + + "@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg=="], + + "@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.21.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w=="], + + "@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.21.5", "", { "os": "linux", "cpu": "none" }, "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA=="], + + "@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.21.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A=="], + + "@esbuild/linux-x64": ["@esbuild/linux-x64@0.21.5", "", { "os": "linux", "cpu": "x64" }, "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ=="], + + "@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.21.5", "", { "os": "none", "cpu": "x64" }, "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg=="], + + "@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.21.5", "", { "os": "openbsd", "cpu": "x64" }, "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow=="], + + "@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.21.5", "", { "os": "sunos", "cpu": "x64" }, "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg=="], + + "@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.21.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A=="], + + "@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.21.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA=="], + + "@esbuild/win32-x64": ["@esbuild/win32-x64@0.21.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw=="], + + "@iconify-json/simple-icons": ["@iconify-json/simple-icons@1.2.77", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-oaENvo6C3BkAEWMlcQA3XemxU9v2SFOTlApSUCODAkIu1haeLCjzrmH3HgmGqjRnJjM+LevO8sA+MgdMHBFBDA=="], + + "@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="], + + "@iconify/utils": ["@iconify/utils@3.1.0", "", { "dependencies": { "@antfu/install-pkg": "^1.1.0", "@iconify/types": "^2.0.0", "mlly": "^1.8.0" } }, "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw=="], + + "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="], + + "@lucide/vue": ["@lucide/vue@1.8.0", "", { "peerDependencies": { "vue": ">=3.0.1" } }, "sha512-Rgy2rxfOx9yP6fWneE3QO6xwUbF2o7f9+MRbzGLRakee4tzUeVWHdX23uRH4ymwEzoq2+8vqRI9yGsxeZhYlWw=="], + + "@mermaid-js/mermaid-mindmap": ["@mermaid-js/mermaid-mindmap@9.3.0", "", { "dependencies": { "@braintree/sanitize-url": "^6.0.0", "cytoscape": "^3.23.0", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.1.0", "d3": "^7.0.0", "khroma": "^2.0.0", "non-layered-tidy-tree-layout": "^2.0.2" } }, "sha512-IhtYSVBBRYviH1Ehu8gk69pMDF8DSRqXBRDMWrEfHoaMruHeaP2DXA3PBnuwsMaCdPQhlUUcy/7DBLAEIXvCAw=="], + + "@mermaid-js/parser": ["@mermaid-js/parser@1.1.0", "", { "dependencies": { "langium": "^4.0.0" } }, "sha512-gxK9ZX2+Fex5zu8LhRQoMeMPEHbc73UKZ0FQ54YrQtUxE1VVhMwzeNtKRPAu5aXks4FasbMe4xB4bWrmq6Jlxw=="], + + "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.60.1", "", { "os": "android", "cpu": "arm" }, "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA=="], + + "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.60.1", "", { "os": "android", "cpu": "arm64" }, "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA=="], + + "@rollup/rollup-darwin-arm64": ["@rollup/rollup-darwin-arm64@4.60.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw=="], + + "@rollup/rollup-darwin-x64": ["@rollup/rollup-darwin-x64@4.60.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew=="], + + "@rollup/rollup-freebsd-arm64": ["@rollup/rollup-freebsd-arm64@4.60.1", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w=="], + + "@rollup/rollup-freebsd-x64": ["@rollup/rollup-freebsd-x64@4.60.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g=="], + + "@rollup/rollup-linux-arm-gnueabihf": ["@rollup/rollup-linux-arm-gnueabihf@4.60.1", "", { "os": "linux", "cpu": "arm" }, "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g=="], + + "@rollup/rollup-linux-arm-musleabihf": ["@rollup/rollup-linux-arm-musleabihf@4.60.1", "", { "os": "linux", "cpu": "arm" }, "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg=="], + + "@rollup/rollup-linux-arm64-gnu": ["@rollup/rollup-linux-arm64-gnu@4.60.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ=="], + + "@rollup/rollup-linux-arm64-musl": ["@rollup/rollup-linux-arm64-musl@4.60.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA=="], + + "@rollup/rollup-linux-loong64-gnu": ["@rollup/rollup-linux-loong64-gnu@4.60.1", "", { "os": "linux", "cpu": "none" }, "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ=="], + + "@rollup/rollup-linux-loong64-musl": ["@rollup/rollup-linux-loong64-musl@4.60.1", "", { "os": "linux", "cpu": "none" }, "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw=="], + + "@rollup/rollup-linux-ppc64-gnu": ["@rollup/rollup-linux-ppc64-gnu@4.60.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw=="], + + "@rollup/rollup-linux-ppc64-musl": ["@rollup/rollup-linux-ppc64-musl@4.60.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg=="], + + "@rollup/rollup-linux-riscv64-gnu": ["@rollup/rollup-linux-riscv64-gnu@4.60.1", "", { "os": "linux", "cpu": "none" }, "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg=="], + + "@rollup/rollup-linux-riscv64-musl": ["@rollup/rollup-linux-riscv64-musl@4.60.1", "", { "os": "linux", "cpu": "none" }, "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg=="], + + "@rollup/rollup-linux-s390x-gnu": ["@rollup/rollup-linux-s390x-gnu@4.60.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ=="], + + "@rollup/rollup-linux-x64-gnu": ["@rollup/rollup-linux-x64-gnu@4.60.1", "", { "os": "linux", "cpu": "x64" }, "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg=="], + + "@rollup/rollup-linux-x64-musl": ["@rollup/rollup-linux-x64-musl@4.60.1", "", { "os": "linux", "cpu": "x64" }, "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w=="], + + "@rollup/rollup-openbsd-x64": ["@rollup/rollup-openbsd-x64@4.60.1", "", { "os": "openbsd", "cpu": "x64" }, "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw=="], + + "@rollup/rollup-openharmony-arm64": ["@rollup/rollup-openharmony-arm64@4.60.1", "", { "os": "none", "cpu": "arm64" }, "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA=="], + + "@rollup/rollup-win32-arm64-msvc": ["@rollup/rollup-win32-arm64-msvc@4.60.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g=="], + + "@rollup/rollup-win32-ia32-msvc": ["@rollup/rollup-win32-ia32-msvc@4.60.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg=="], + + "@rollup/rollup-win32-x64-gnu": ["@rollup/rollup-win32-x64-gnu@4.60.1", "", { "os": "win32", "cpu": "x64" }, "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg=="], + + "@rollup/rollup-win32-x64-msvc": ["@rollup/rollup-win32-x64-msvc@4.60.1", "", { "os": "win32", "cpu": "x64" }, "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ=="], + + "@shikijs/core": ["@shikijs/core@2.5.0", "", { "dependencies": { "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.4" } }, "sha512-uu/8RExTKtavlpH7XqnVYBrfBkUc20ngXiX9NSrBhOVZYv/7XQRKUyhtkeflY5QsxC0GbJThCerruZfsUaSldg=="], + + "@shikijs/engine-javascript": ["@shikijs/engine-javascript@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "oniguruma-to-es": "^3.1.0" } }, "sha512-VjnOpnQf8WuCEZtNUdjjwGUbtAVKuZkVQ/5cHy/tojVVRIRtlWMYVjyWhxOmIq05AlSOv72z7hRNRGVBgQOl0w=="], + + "@shikijs/engine-oniguruma": ["@shikijs/engine-oniguruma@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2" } }, "sha512-pGd1wRATzbo/uatrCIILlAdFVKdxImWJGQ5rFiB5VZi2ve5xj3Ax9jny8QvkaV93btQEwR/rSz5ERFpC5mKNIw=="], + + "@shikijs/langs": ["@shikijs/langs@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-Qfrrt5OsNH5R+5tJ/3uYBBZv3SuGmnRPejV9IlIbFH3HTGLDlkqgHymAlzklVmKBjAaVmkPkyikAV/sQ1wSL+w=="], + + "@shikijs/themes": ["@shikijs/themes@2.5.0", "", { "dependencies": { "@shikijs/types": "2.5.0" } }, "sha512-wGrk+R8tJnO0VMzmUExHR+QdSaPUl/NKs+a4cQQRWyoc3YFbUzuLEi/KWK1hj+8BfHRKm2jNhhJck1dfstJpiw=="], + + "@shikijs/transformers": ["@shikijs/transformers@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/types": "2.5.0" } }, "sha512-SI494W5X60CaUwgi8u4q4m4s3YAFSxln3tzNjOSYqq54wlVgz0/NbbXEb3mdLbqMBztcmS7bVTaEd2w0qMmfeg=="], + + "@shikijs/types": ["@shikijs/types@2.5.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-ygl5yhxki9ZLNuNpPitBWvcy9fsSKKaRuO4BAlMyagszQidxcpLAr0qiW/q43DtSIDxO6hEbtYLiFZNXO/hdGw=="], + + "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.2", "", {}, "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg=="], + + "@types/d3": ["@types/d3@7.4.3", "", { "dependencies": { "@types/d3-array": "*", "@types/d3-axis": "*", "@types/d3-brush": "*", "@types/d3-chord": "*", "@types/d3-color": "*", "@types/d3-contour": "*", "@types/d3-delaunay": "*", "@types/d3-dispatch": "*", "@types/d3-drag": "*", "@types/d3-dsv": "*", "@types/d3-ease": "*", "@types/d3-fetch": "*", "@types/d3-force": "*", "@types/d3-format": "*", "@types/d3-geo": "*", "@types/d3-hierarchy": "*", "@types/d3-interpolate": "*", "@types/d3-path": "*", "@types/d3-polygon": "*", "@types/d3-quadtree": "*", "@types/d3-random": "*", "@types/d3-scale": "*", "@types/d3-scale-chromatic": "*", "@types/d3-selection": "*", "@types/d3-shape": "*", "@types/d3-time": "*", "@types/d3-time-format": "*", "@types/d3-timer": "*", "@types/d3-transition": "*", "@types/d3-zoom": "*" } }, "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww=="], + + "@types/d3-array": ["@types/d3-array@3.2.2", "", {}, "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw=="], + + "@types/d3-axis": ["@types/d3-axis@3.0.6", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw=="], + + "@types/d3-brush": ["@types/d3-brush@3.0.6", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A=="], + + "@types/d3-chord": ["@types/d3-chord@3.0.6", "", {}, "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg=="], + + "@types/d3-color": ["@types/d3-color@3.1.3", "", {}, "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A=="], + + "@types/d3-contour": ["@types/d3-contour@3.0.6", "", { "dependencies": { "@types/d3-array": "*", "@types/geojson": "*" } }, "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg=="], + + "@types/d3-delaunay": ["@types/d3-delaunay@6.0.4", "", {}, "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw=="], + + "@types/d3-dispatch": ["@types/d3-dispatch@3.0.7", "", {}, "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA=="], + + "@types/d3-drag": ["@types/d3-drag@3.0.7", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ=="], + + "@types/d3-dsv": ["@types/d3-dsv@3.0.7", "", {}, "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g=="], + + "@types/d3-ease": ["@types/d3-ease@3.0.2", "", {}, "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA=="], + + "@types/d3-fetch": ["@types/d3-fetch@3.0.7", "", { "dependencies": { "@types/d3-dsv": "*" } }, "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA=="], + + "@types/d3-force": ["@types/d3-force@3.0.10", "", {}, "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw=="], + + "@types/d3-format": ["@types/d3-format@3.0.4", "", {}, "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g=="], + + "@types/d3-geo": ["@types/d3-geo@3.1.0", "", { "dependencies": { "@types/geojson": "*" } }, "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ=="], + + "@types/d3-hierarchy": ["@types/d3-hierarchy@3.1.7", "", {}, "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg=="], + + "@types/d3-interpolate": ["@types/d3-interpolate@3.0.4", "", { "dependencies": { "@types/d3-color": "*" } }, "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA=="], + + "@types/d3-path": ["@types/d3-path@3.1.1", "", {}, "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg=="], + + "@types/d3-polygon": ["@types/d3-polygon@3.0.2", "", {}, "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA=="], + + "@types/d3-quadtree": ["@types/d3-quadtree@3.0.6", "", {}, "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg=="], + + "@types/d3-random": ["@types/d3-random@3.0.3", "", {}, "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ=="], + + "@types/d3-scale": ["@types/d3-scale@4.0.9", "", { "dependencies": { "@types/d3-time": "*" } }, "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw=="], + + "@types/d3-scale-chromatic": ["@types/d3-scale-chromatic@3.1.0", "", {}, "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ=="], + + "@types/d3-selection": ["@types/d3-selection@3.0.11", "", {}, "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w=="], + + "@types/d3-shape": ["@types/d3-shape@3.1.8", "", { "dependencies": { "@types/d3-path": "*" } }, "sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w=="], + + "@types/d3-time": ["@types/d3-time@3.0.4", "", {}, "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g=="], + + "@types/d3-time-format": ["@types/d3-time-format@4.0.3", "", {}, "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg=="], + + "@types/d3-timer": ["@types/d3-timer@3.0.2", "", {}, "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw=="], + + "@types/d3-transition": ["@types/d3-transition@3.0.9", "", { "dependencies": { "@types/d3-selection": "*" } }, "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg=="], + + "@types/d3-zoom": ["@types/d3-zoom@3.0.8", "", { "dependencies": { "@types/d3-interpolate": "*", "@types/d3-selection": "*" } }, "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw=="], + + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/geojson": ["@types/geojson@7946.0.16", "", {}, "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg=="], + + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + + "@types/linkify-it": ["@types/linkify-it@5.0.0", "", {}, "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="], + + "@types/markdown-it": ["@types/markdown-it@14.1.2", "", { "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" } }, "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="], + + "@types/node": ["@types/node@25.5.2", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-tO4ZIRKNC+MDWV4qKVZe3Ql/woTnmHDr5JD8UI5hn2pwBrHEwOEMZK7WlNb5RKB6EoJ02gwmQS9OrjuFnZYdpg=="], + + "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], + + "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "@types/web-bluetooth": ["@types/web-bluetooth@0.0.21", "", {}, "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + + "@upsetjs/venn.js": ["@upsetjs/venn.js@2.0.0", "", { "optionalDependencies": { "d3-selection": "^3.0.0", "d3-transition": "^3.0.1" } }, "sha512-WbBhLrooyePuQ1VZxrJjtLvTc4NVfpOyKx0sKqioq9bX1C1m7Jgykkn8gLrtwumBioXIqam8DLxp88Adbue6Hw=="], + + "@vitejs/plugin-vue": ["@vitejs/plugin-vue@5.2.4", "", { "peerDependencies": { "vite": "^5.0.0 || ^6.0.0", "vue": "^3.2.25" } }, "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA=="], + + "@vue/compiler-core": ["@vue/compiler-core@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/shared": "3.5.32", "entities": "^7.0.1", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } }, "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ=="], + + "@vue/compiler-dom": ["@vue/compiler-dom@3.5.32", "", { "dependencies": { "@vue/compiler-core": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q=="], + + "@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.32", "", { "dependencies": { "@babel/parser": "^7.29.2", "@vue/compiler-core": "3.5.32", "@vue/compiler-dom": "3.5.32", "@vue/compiler-ssr": "3.5.32", "@vue/shared": "3.5.32", "estree-walker": "^2.0.2", "magic-string": "^0.30.21", "postcss": "^8.5.8", "source-map-js": "^1.2.1" } }, "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg=="], + + "@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.32", "", { "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw=="], + + "@vue/devtools-api": ["@vue/devtools-api@7.7.9", "", { "dependencies": { "@vue/devtools-kit": "^7.7.9" } }, "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g=="], + + "@vue/devtools-kit": ["@vue/devtools-kit@7.7.9", "", { "dependencies": { "@vue/devtools-shared": "^7.7.9", "birpc": "^2.3.0", "hookable": "^5.5.3", "mitt": "^3.0.1", "perfect-debounce": "^1.0.0", "speakingurl": "^14.0.1", "superjson": "^2.2.2" } }, "sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA=="], + + "@vue/devtools-shared": ["@vue/devtools-shared@7.7.9", "", { "dependencies": { "rfdc": "^1.4.1" } }, "sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA=="], + + "@vue/reactivity": ["@vue/reactivity@3.5.32", "", { "dependencies": { "@vue/shared": "3.5.32" } }, "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ=="], + + "@vue/runtime-core": ["@vue/runtime-core@3.5.32", "", { "dependencies": { "@vue/reactivity": "3.5.32", "@vue/shared": "3.5.32" } }, "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ=="], + + "@vue/runtime-dom": ["@vue/runtime-dom@3.5.32", "", { "dependencies": { "@vue/reactivity": "3.5.32", "@vue/runtime-core": "3.5.32", "@vue/shared": "3.5.32", "csstype": "^3.2.3" } }, "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ=="], + + "@vue/server-renderer": ["@vue/server-renderer@3.5.32", "", { "dependencies": { "@vue/compiler-ssr": "3.5.32", "@vue/shared": "3.5.32" }, "peerDependencies": { "vue": "3.5.32" } }, "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ=="], + + "@vue/shared": ["@vue/shared@3.5.32", "", {}, "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg=="], + + "@vueuse/core": ["@vueuse/core@12.8.2", "", { "dependencies": { "@types/web-bluetooth": "^0.0.21", "@vueuse/metadata": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" } }, "sha512-HbvCmZdzAu3VGi/pWYm5Ut+Kd9mn1ZHnn4L5G8kOQTPs/IwIAmJoBrmYk2ckLArgMXZj0AW3n5CAejLUO+PhdQ=="], + + "@vueuse/integrations": ["@vueuse/integrations@12.8.2", "", { "dependencies": { "@vueuse/core": "12.8.2", "@vueuse/shared": "12.8.2", "vue": "^3.5.13" }, "peerDependencies": { "async-validator": "^4", "axios": "^1", "change-case": "^5", "drauu": "^0.4", "focus-trap": "^7", "fuse.js": "^7", "idb-keyval": "^6", "jwt-decode": "^4", "nprogress": "^0.2", "qrcode": "^1.5", "sortablejs": "^1", "universal-cookie": "^7" }, "optionalPeers": ["async-validator", "axios", "change-case", "drauu", "focus-trap", "fuse.js", "idb-keyval", "jwt-decode", "nprogress", "qrcode", "sortablejs", "universal-cookie"] }, "sha512-fbGYivgK5uBTRt7p5F3zy6VrETlV9RtZjBqd1/HxGdjdckBgBM4ugP8LHpjolqTj14TXTxSK1ZfgPbHYyGuH7g=="], + + "@vueuse/metadata": ["@vueuse/metadata@12.8.2", "", {}, "sha512-rAyLGEuoBJ/Il5AmFHiziCPdQzRt88VxR+Y/A/QhJ1EWtWqPBBAxTAFaSkviwEuOEZNtW8pvkPgoCZQ+HxqW1A=="], + + "@vueuse/shared": ["@vueuse/shared@12.8.2", "", { "dependencies": { "vue": "^3.5.13" } }, "sha512-dznP38YzxZoNloI0qpEfpkms8knDtaoQ6Y/sfS0L7Yki4zh40LFHEhur0odJC6xTHG5dxWVPiUWBXn+wCG2s5w=="], + + "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], + + "algoliasearch": ["algoliasearch@5.50.1", "", { "dependencies": { "@algolia/abtesting": "1.16.1", "@algolia/client-abtesting": "5.50.1", "@algolia/client-analytics": "5.50.1", "@algolia/client-common": "5.50.1", "@algolia/client-insights": "5.50.1", "@algolia/client-personalization": "5.50.1", "@algolia/client-query-suggestions": "5.50.1", "@algolia/client-search": "5.50.1", "@algolia/ingestion": "1.50.1", "@algolia/monitoring": "1.50.1", "@algolia/recommend": "5.50.1", "@algolia/requester-browser-xhr": "5.50.1", "@algolia/requester-fetch": "5.50.1", "@algolia/requester-node-http": "5.50.1" } }, "sha512-/bwdue1/8LWELn/DBalGRfuLsXBLXULJo/yOeavJtDu8rBwxIzC6/Rz9Jg19S21VkJvRuZO1k8CZXBMS73mYbA=="], + + "birpc": ["birpc@2.9.0", "", {}, "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw=="], + + "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + + "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], + + "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="], + + "chevrotain": ["chevrotain@12.0.0", "", { "dependencies": { "@chevrotain/cst-dts-gen": "12.0.0", "@chevrotain/gast": "12.0.0", "@chevrotain/regexp-to-ast": "12.0.0", "@chevrotain/types": "12.0.0", "@chevrotain/utils": "12.0.0" } }, "sha512-csJvb+6kEiQaqo1woTdSAuOWdN0WTLIydkKrBnS+V5gZz0oqBrp4kQ35519QgK6TpBThiG3V1vNSHlIkv4AglQ=="], + + "chevrotain-allstar": ["chevrotain-allstar@0.4.1", "", { "dependencies": { "lodash-es": "^4.17.21" }, "peerDependencies": { "chevrotain": "^12.0.0" } }, "sha512-PvVJm3oGqrveUVW2Vt/eZGeiAIsJszYweUcYwcskg9e+IubNYKKD+rHHem7A6XVO22eDAL+inxNIGAzZ/VIWlA=="], + + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + + "commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="], + + "confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], + + "copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="], + + "cose-base": ["cose-base@1.0.3", "", { "dependencies": { "layout-base": "^1.0.0" } }, "sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg=="], + + "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], + + "cytoscape": ["cytoscape@3.33.2", "", {}, "sha512-sj4HXd3DokGhzZAdjDejGvTPLqlt84vNFN8m7bGsOzDY5DyVcxIb2ejIXat2Iy7HxWhdT/N1oKyheJ5YdpsGuw=="], + + "cytoscape-cose-bilkent": ["cytoscape-cose-bilkent@4.1.0", "", { "dependencies": { "cose-base": "^1.0.0" }, "peerDependencies": { "cytoscape": "^3.2.0" } }, "sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ=="], + + "cytoscape-fcose": ["cytoscape-fcose@2.2.0", "", { "dependencies": { "cose-base": "^2.2.0" }, "peerDependencies": { "cytoscape": "^3.2.0" } }, "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ=="], + + "d3": ["d3@7.9.0", "", { "dependencies": { "d3-array": "3", "d3-axis": "3", "d3-brush": "3", "d3-chord": "3", "d3-color": "3", "d3-contour": "4", "d3-delaunay": "6", "d3-dispatch": "3", "d3-drag": "3", "d3-dsv": "3", "d3-ease": "3", "d3-fetch": "3", "d3-force": "3", "d3-format": "3", "d3-geo": "3", "d3-hierarchy": "3", "d3-interpolate": "3", "d3-path": "3", "d3-polygon": "3", "d3-quadtree": "3", "d3-random": "3", "d3-scale": "4", "d3-scale-chromatic": "3", "d3-selection": "3", "d3-shape": "3", "d3-time": "3", "d3-time-format": "4", "d3-timer": "3", "d3-transition": "3", "d3-zoom": "3" } }, "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA=="], + + "d3-array": ["d3-array@3.2.4", "", { "dependencies": { "internmap": "1 - 2" } }, "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg=="], + + "d3-axis": ["d3-axis@3.0.0", "", {}, "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw=="], + + "d3-brush": ["d3-brush@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "3", "d3-transition": "3" } }, "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ=="], + + "d3-chord": ["d3-chord@3.0.1", "", { "dependencies": { "d3-path": "1 - 3" } }, "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g=="], + + "d3-color": ["d3-color@3.1.0", "", {}, "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA=="], + + "d3-contour": ["d3-contour@4.0.2", "", { "dependencies": { "d3-array": "^3.2.0" } }, "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA=="], + + "d3-delaunay": ["d3-delaunay@6.0.4", "", { "dependencies": { "delaunator": "5" } }, "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A=="], + + "d3-dispatch": ["d3-dispatch@3.0.1", "", {}, "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg=="], + + "d3-drag": ["d3-drag@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-selection": "3" } }, "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg=="], + + "d3-dsv": ["d3-dsv@3.0.1", "", { "dependencies": { "commander": "7", "iconv-lite": "0.6", "rw": "1" }, "bin": { "csv2json": "bin/dsv2json.js", "csv2tsv": "bin/dsv2dsv.js", "dsv2dsv": "bin/dsv2dsv.js", "dsv2json": "bin/dsv2json.js", "json2csv": "bin/json2dsv.js", "json2dsv": "bin/json2dsv.js", "json2tsv": "bin/json2dsv.js", "tsv2csv": "bin/dsv2dsv.js", "tsv2json": "bin/dsv2json.js" } }, "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q=="], + + "d3-ease": ["d3-ease@3.0.1", "", {}, "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w=="], + + "d3-fetch": ["d3-fetch@3.0.1", "", { "dependencies": { "d3-dsv": "1 - 3" } }, "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw=="], + + "d3-force": ["d3-force@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-quadtree": "1 - 3", "d3-timer": "1 - 3" } }, "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg=="], + + "d3-format": ["d3-format@3.1.2", "", {}, "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg=="], + + "d3-geo": ["d3-geo@3.1.1", "", { "dependencies": { "d3-array": "2.5.0 - 3" } }, "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q=="], + + "d3-hierarchy": ["d3-hierarchy@3.1.2", "", {}, "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA=="], + + "d3-interpolate": ["d3-interpolate@3.0.1", "", { "dependencies": { "d3-color": "1 - 3" } }, "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g=="], + + "d3-path": ["d3-path@3.1.0", "", {}, "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ=="], + + "d3-polygon": ["d3-polygon@3.0.1", "", {}, "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg=="], + + "d3-quadtree": ["d3-quadtree@3.0.1", "", {}, "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw=="], + + "d3-random": ["d3-random@3.0.1", "", {}, "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ=="], + + "d3-sankey": ["d3-sankey@0.12.3", "", { "dependencies": { "d3-array": "1 - 2", "d3-shape": "^1.2.0" } }, "sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ=="], + + "d3-scale": ["d3-scale@4.0.2", "", { "dependencies": { "d3-array": "2.10.0 - 3", "d3-format": "1 - 3", "d3-interpolate": "1.2.0 - 3", "d3-time": "2.1.1 - 3", "d3-time-format": "2 - 4" } }, "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ=="], + + "d3-scale-chromatic": ["d3-scale-chromatic@3.1.0", "", { "dependencies": { "d3-color": "1 - 3", "d3-interpolate": "1 - 3" } }, "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ=="], + + "d3-selection": ["d3-selection@3.0.0", "", {}, "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ=="], + + "d3-shape": ["d3-shape@3.2.0", "", { "dependencies": { "d3-path": "^3.1.0" } }, "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA=="], + + "d3-time": ["d3-time@3.1.0", "", { "dependencies": { "d3-array": "2 - 3" } }, "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q=="], + + "d3-time-format": ["d3-time-format@4.1.0", "", { "dependencies": { "d3-time": "1 - 3" } }, "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg=="], + + "d3-timer": ["d3-timer@3.0.1", "", {}, "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA=="], + + "d3-transition": ["d3-transition@3.0.1", "", { "dependencies": { "d3-color": "1 - 3", "d3-dispatch": "1 - 3", "d3-ease": "1 - 3", "d3-interpolate": "1 - 3", "d3-timer": "1 - 3" }, "peerDependencies": { "d3-selection": "2 - 3" } }, "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w=="], + + "d3-zoom": ["d3-zoom@3.0.0", "", { "dependencies": { "d3-dispatch": "1 - 3", "d3-drag": "2 - 3", "d3-interpolate": "1 - 3", "d3-selection": "2 - 3", "d3-transition": "2 - 3" } }, "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw=="], + + "dagre-d3-es": ["dagre-d3-es@7.0.14", "", { "dependencies": { "d3": "^7.9.0", "lodash-es": "^4.17.21" } }, "sha512-P4rFMVq9ESWqmOgK+dlXvOtLwYg0i7u0HBGJER0LZDJT2VHIPAMZ/riPxqJceWMStH5+E61QxFra9kIS3AqdMg=="], + + "dayjs": ["dayjs@1.11.20", "", {}, "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ=="], + + "delaunator": ["delaunator@5.1.0", "", { "dependencies": { "robust-predicates": "^3.0.2" } }, "sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + + "dompurify": ["dompurify@3.3.3", "", { "optionalDependencies": { "@types/trusted-types": "^2.0.7" } }, "sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA=="], + + "emoji-regex-xs": ["emoji-regex-xs@1.0.0", "", {}, "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg=="], + + "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], + + "esbuild": ["esbuild@0.21.5", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.21.5", "@esbuild/android-arm": "0.21.5", "@esbuild/android-arm64": "0.21.5", "@esbuild/android-x64": "0.21.5", "@esbuild/darwin-arm64": "0.21.5", "@esbuild/darwin-x64": "0.21.5", "@esbuild/freebsd-arm64": "0.21.5", "@esbuild/freebsd-x64": "0.21.5", "@esbuild/linux-arm": "0.21.5", "@esbuild/linux-arm64": "0.21.5", "@esbuild/linux-ia32": "0.21.5", "@esbuild/linux-loong64": "0.21.5", "@esbuild/linux-mips64el": "0.21.5", "@esbuild/linux-ppc64": "0.21.5", "@esbuild/linux-riscv64": "0.21.5", "@esbuild/linux-s390x": "0.21.5", "@esbuild/linux-x64": "0.21.5", "@esbuild/netbsd-x64": "0.21.5", "@esbuild/openbsd-x64": "0.21.5", "@esbuild/sunos-x64": "0.21.5", "@esbuild/win32-arm64": "0.21.5", "@esbuild/win32-ia32": "0.21.5", "@esbuild/win32-x64": "0.21.5" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw=="], + + "estree-walker": ["estree-walker@2.0.2", "", {}, "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="], + + "focus-trap": ["focus-trap@7.8.0", "", { "dependencies": { "tabbable": "^6.4.0" } }, "sha512-/yNdlIkpWbM0ptxno3ONTuf+2g318kh2ez3KSeZN5dZ8YC6AAmgeWz+GasYYiBJPFaYcSAPeu4GfhUaChzIJXA=="], + + "fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="], + + "hachure-fill": ["hachure-fill@0.5.2", "", {}, "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg=="], + + "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], + + "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + + "hookable": ["hookable@5.5.3", "", {}, "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="], + + "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], + + "iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], + + "internmap": ["internmap@2.0.3", "", {}, "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg=="], + + "is-what": ["is-what@5.5.0", "", {}, "sha512-oG7cgbmg5kLYae2N5IVd3jm2s+vldjxJzK1pcu9LfpGuQ93MQSzo0okvRna+7y5ifrD+20FE8FvjusyGaz14fw=="], + + "katex": ["katex@0.16.45", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA=="], + + "khroma": ["khroma@2.1.0", "", {}, "sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw=="], + + "langium": ["langium@4.2.2", "", { "dependencies": { "@chevrotain/regexp-to-ast": "~12.0.0", "chevrotain": "~12.0.0", "chevrotain-allstar": "~0.4.1", "vscode-languageserver": "~9.0.1", "vscode-languageserver-textdocument": "~1.0.11", "vscode-uri": "~3.1.0" } }, "sha512-JUshTRAfHI4/MF9dH2WupvjSXyn8JBuUEWazB8ZVJUtXutT0doDlAv1XKbZ1Pb5sMexa8FF4CFBc0iiul7gbUQ=="], + + "layout-base": ["layout-base@1.0.2", "", {}, "sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg=="], + + "lodash-es": ["lodash-es@4.18.1", "", {}, "sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A=="], + + "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + + "mark.js": ["mark.js@8.11.1", "", {}, "sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ=="], + + "marked": ["marked@16.4.2", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA=="], + + "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="], + + "mermaid": ["mermaid@11.14.0", "", { "dependencies": { "@braintree/sanitize-url": "^7.1.1", "@iconify/utils": "^3.0.2", "@mermaid-js/parser": "^1.1.0", "@types/d3": "^7.4.3", "@upsetjs/venn.js": "^2.0.0", "cytoscape": "^3.33.1", "cytoscape-cose-bilkent": "^4.1.0", "cytoscape-fcose": "^2.2.0", "d3": "^7.9.0", "d3-sankey": "^0.12.3", "dagre-d3-es": "7.0.14", "dayjs": "^1.11.19", "dompurify": "^3.3.1", "katex": "^0.16.25", "khroma": "^2.1.0", "lodash-es": "^4.17.23", "marked": "^16.3.0", "roughjs": "^4.6.6", "stylis": "^4.3.6", "ts-dedent": "^2.2.0", "uuid": "^11.1.0" } }, "sha512-GSGloRsBs+JINmmhl0JDwjpuezCsHB4WGI4NASHxL3fHo3o/BRXTxhDLKnln8/Q0lRFRyDdEjmk1/d5Sn1Xz8g=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + + "minisearch": ["minisearch@7.2.0", "", {}, "sha512-dqT2XBYUOZOiC5t2HRnwADjhNS2cecp9u+TJRiJ1Qp/f5qjkeT5APcGPjHw+bz89Ms8Jp+cG4AlE+QZ/QnDglg=="], + + "mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="], + + "mlly": ["mlly@1.8.2", "", { "dependencies": { "acorn": "^8.16.0", "pathe": "^2.0.3", "pkg-types": "^1.3.1", "ufo": "^1.6.3" } }, "sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA=="], + + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], + + "non-layered-tidy-tree-layout": ["non-layered-tidy-tree-layout@2.0.2", "", {}, "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw=="], + + "oniguruma-to-es": ["oniguruma-to-es@3.1.1", "", { "dependencies": { "emoji-regex-xs": "^1.0.0", "regex": "^6.0.1", "regex-recursion": "^6.0.2" } }, "sha512-bUH8SDvPkH3ho3dvwJwfonjlQ4R80vjyvrU8YpxuROddv55vAEJrTuCuCVUhhsHbtlD9tGGbaNApGQckXhS8iQ=="], + + "package-manager-detector": ["package-manager-detector@1.6.0", "", {}, "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA=="], + + "path-data-parser": ["path-data-parser@0.1.0", "", {}, "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w=="], + + "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], + + "perfect-debounce": ["perfect-debounce@1.0.0", "", {}, "sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA=="], + + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], + + "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], + + "points-on-curve": ["points-on-curve@0.2.0", "", {}, "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A=="], + + "points-on-path": ["points-on-path@0.2.1", "", { "dependencies": { "path-data-parser": "0.1.0", "points-on-curve": "0.2.0" } }, "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g=="], + + "postcss": ["postcss@8.5.9", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw=="], + + "preact": ["preact@10.29.1", "", {}, "sha512-gQCLc/vWroE8lIpleXtdJhTFDogTdZG9AjMUpVkDf2iTCNwYNWA+u16dL41TqUDJO4gm2IgrcMv3uTpjd4Pwmg=="], + + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], + + "regex": ["regex@6.1.0", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg=="], + + "regex-recursion": ["regex-recursion@6.0.2", "", { "dependencies": { "regex-utilities": "^2.3.0" } }, "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg=="], + + "regex-utilities": ["regex-utilities@2.3.0", "", {}, "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng=="], + + "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + + "robust-predicates": ["robust-predicates@3.0.3", "", {}, "sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA=="], + + "rollup": ["rollup@4.60.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.60.1", "@rollup/rollup-android-arm64": "4.60.1", "@rollup/rollup-darwin-arm64": "4.60.1", "@rollup/rollup-darwin-x64": "4.60.1", "@rollup/rollup-freebsd-arm64": "4.60.1", "@rollup/rollup-freebsd-x64": "4.60.1", "@rollup/rollup-linux-arm-gnueabihf": "4.60.1", "@rollup/rollup-linux-arm-musleabihf": "4.60.1", "@rollup/rollup-linux-arm64-gnu": "4.60.1", "@rollup/rollup-linux-arm64-musl": "4.60.1", "@rollup/rollup-linux-loong64-gnu": "4.60.1", "@rollup/rollup-linux-loong64-musl": "4.60.1", "@rollup/rollup-linux-ppc64-gnu": "4.60.1", "@rollup/rollup-linux-ppc64-musl": "4.60.1", "@rollup/rollup-linux-riscv64-gnu": "4.60.1", "@rollup/rollup-linux-riscv64-musl": "4.60.1", "@rollup/rollup-linux-s390x-gnu": "4.60.1", "@rollup/rollup-linux-x64-gnu": "4.60.1", "@rollup/rollup-linux-x64-musl": "4.60.1", "@rollup/rollup-openbsd-x64": "4.60.1", "@rollup/rollup-openharmony-arm64": "4.60.1", "@rollup/rollup-win32-arm64-msvc": "4.60.1", "@rollup/rollup-win32-ia32-msvc": "4.60.1", "@rollup/rollup-win32-x64-gnu": "4.60.1", "@rollup/rollup-win32-x64-msvc": "4.60.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w=="], + + "roughjs": ["roughjs@4.6.6", "", { "dependencies": { "hachure-fill": "^0.5.2", "path-data-parser": "^0.1.0", "points-on-curve": "^0.2.0", "points-on-path": "^0.2.1" } }, "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ=="], + + "rw": ["rw@1.3.3", "", {}, "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="], + + "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], + + "search-insights": ["search-insights@2.17.3", "", {}, "sha512-RQPdCYTa8A68uM2jwxoY842xDhvx3E5LFL1LxvxCNMev4o5mLuokczhzjAgGwUZBAmOKZknArSxLKmXtIi2AxQ=="], + + "shiki": ["shiki@2.5.0", "", { "dependencies": { "@shikijs/core": "2.5.0", "@shikijs/engine-javascript": "2.5.0", "@shikijs/engine-oniguruma": "2.5.0", "@shikijs/langs": "2.5.0", "@shikijs/themes": "2.5.0", "@shikijs/types": "2.5.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-mI//trrsaiCIPsja5CNfsyNOqgAZUb6VpJA+340toL42UpzQlXpwRV9nch69X6gaUxrr9kaOOa6e3y3uAkGFxQ=="], + + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + + "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + + "speakingurl": ["speakingurl@14.0.1", "", {}, "sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ=="], + + "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="], + + "stylis": ["stylis@4.3.6", "", {}, "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ=="], + + "superjson": ["superjson@2.2.6", "", { "dependencies": { "copy-anything": "^4" } }, "sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA=="], + + "tabbable": ["tabbable@6.4.0", "", {}, "sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg=="], + + "tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="], + + "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], + + "ts-dedent": ["ts-dedent@2.2.0", "", {}, "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], + + "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], + + "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="], + + "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], + + "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="], + + "unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + + "uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + + "vite": ["vite@5.4.21", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": { "vite": "bin/vite.js" } }, "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw=="], + + "vitepress": ["vitepress@1.6.4", "", { "dependencies": { "@docsearch/css": "3.8.2", "@docsearch/js": "3.8.2", "@iconify-json/simple-icons": "^1.2.21", "@shikijs/core": "^2.1.0", "@shikijs/transformers": "^2.1.0", "@shikijs/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.2.1", "@vue/devtools-api": "^7.7.0", "@vue/shared": "^3.5.13", "@vueuse/core": "^12.4.0", "@vueuse/integrations": "^12.4.0", "focus-trap": "^7.6.4", "mark.js": "8.11.1", "minisearch": "^7.1.1", "shiki": "^2.1.0", "vite": "^5.4.14", "vue": "^3.5.13" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3", "postcss"], "bin": { "vitepress": "bin/vitepress.js" } }, "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg=="], + + "vitepress-plugin-mermaid": ["vitepress-plugin-mermaid@2.0.17", "", { "optionalDependencies": { "@mermaid-js/mermaid-mindmap": "^9.3.0" }, "peerDependencies": { "mermaid": "10 || 11", "vitepress": "^1.0.0 || ^1.0.0-alpha" } }, "sha512-IUzYpwf61GC6k0XzfmAmNrLvMi9TRrVRMsUyCA8KNXhg/mQ1VqWnO0/tBVPiX5UoKF1mDUwqn5QV4qAJl6JnUg=="], + + "vscode-jsonrpc": ["vscode-jsonrpc@8.2.0", "", {}, "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA=="], + + "vscode-languageserver": ["vscode-languageserver@9.0.1", "", { "dependencies": { "vscode-languageserver-protocol": "3.17.5" }, "bin": { "installServerIntoExtension": "bin/installServerIntoExtension" } }, "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g=="], + + "vscode-languageserver-protocol": ["vscode-languageserver-protocol@3.17.5", "", { "dependencies": { "vscode-jsonrpc": "8.2.0", "vscode-languageserver-types": "3.17.5" } }, "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg=="], + + "vscode-languageserver-textdocument": ["vscode-languageserver-textdocument@1.0.12", "", {}, "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA=="], + + "vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="], + + "vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="], + + "vue": ["vue@3.5.32", "", { "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/compiler-sfc": "3.5.32", "@vue/runtime-dom": "3.5.32", "@vue/server-renderer": "3.5.32", "@vue/shared": "3.5.32" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + + "@mermaid-js/mermaid-mindmap/@braintree/sanitize-url": ["@braintree/sanitize-url@6.0.4", "", {}, "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A=="], + + "cytoscape-fcose/cose-base": ["cose-base@2.2.0", "", { "dependencies": { "layout-base": "^2.0.0" } }, "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g=="], + + "d3-dsv/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], + + "d3-sankey/d3-array": ["d3-array@2.12.1", "", { "dependencies": { "internmap": "^1.0.0" } }, "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ=="], + + "d3-sankey/d3-shape": ["d3-shape@1.3.7", "", { "dependencies": { "d3-path": "1" } }, "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw=="], + + "cytoscape-fcose/cose-base/layout-base": ["layout-base@2.0.1", "", {}, "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg=="], + + "d3-sankey/d3-array/internmap": ["internmap@1.0.1", "", {}, "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw=="], + + "d3-sankey/d3-shape/d3-path": ["d3-path@1.0.9", "", {}, "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="], + } +} diff --git a/website/concepts/aaak-dialect.md b/website/concepts/aaak-dialect.md new file mode 100644 index 0000000..3c2e49f --- /dev/null +++ b/website/concepts/aaak-dialect.md @@ -0,0 +1,125 @@ +# AAAK Dialect + +AAAK is an experimental lossy abbreviation system designed to pack repeated entities and relationships into fewer tokens at scale. It is readable by any LLM — Claude, GPT, Gemini, Llama, Mistral — without a decoder. + +::: warning Experimental +AAAK is a separate compression layer, **not the storage default**. The 96.6% benchmark score comes from raw verbatim mode. AAAK mode currently scores 84.2% R@5 — a 12.4 point regression. We're iterating. +::: + +## What AAAK Is + +- **Lossy, not lossless.** Uses regex-based abbreviation, not reversible compression. +- **A structured summary format.** Extracts entities, topics, key sentences, emotions, and flags from plain text. +- **Readable by any LLM.** No decoder needed — models read it naturally. +- **Designed for scale.** Saves tokens when the same entities appear hundreds of times. + +## What AAAK Is Not + +- **Not lossless compression.** The original text cannot be reconstructed. +- **Not efficient at small scale.** Short text already tokenizes efficiently — AAAK overhead costs more than it saves. +- **Not the default storage format.** MemPalace stores raw verbatim text in ChromaDB. + +## Format + +``` +Header: FILE_NUM|PRIMARY_ENTITY|DATE|TITLE +Zettel: ZID:ENTITIES|topic_keywords|"key_quote"|WEIGHT|EMOTIONS|FLAGS +Tunnel: T:ZID<->ZID|label +Arc: ARC:emotion->emotion->emotion +``` + +### Entity Codes + +Three-letter uppercase codes: `ALC=Alice`, `KAI=Kai`, `MAX=Max`. + +### Emotion Codes + +| Code | Meaning | Code | Meaning | +|------|---------|------|---------| +| `vul` | vulnerability | `joy` | joy | +| `fear` | fear | `trust` | trust | +| `grief` | grief | `wonder` | wonder | +| `rage` | rage | `love` | love | +| `hope` | hope | `despair` | despair | +| `peace` | peace | `humor` | humor | +| `tender` | tenderness | `raw` | raw honesty | +| `doubt` | self-doubt | `relief` | relief | +| `anx` | anxiety | `exhaust` | exhaustion | + +### Flags + +| Flag | Meaning | +|------|---------| +| `ORIGIN` | Origin moment (birth of something) | +| `CORE` | Core belief or identity pillar | +| `SENSITIVE` | Handle with absolute care | +| `PIVOT` | Emotional turning point | +| `GENESIS` | Led directly to something existing | +| `DECISION` | Explicit decision or choice | +| `TECHNICAL` | Technical architecture detail | + +## Example + +**Input:** +``` +We decided to use GraphQL instead of REST because the frontend team needs +flexible queries. Kai recommended it after researching both options. The team +was excited about the schema-first approach. +``` + +**AAAK output:** +``` +0:KAI|graphql_rest_decided|"decided to use GraphQL instead of REST"|determ+excite|DECISION+TECHNICAL +``` + +## Usage + +### Compress drawers + +```bash +# Preview compression +mempalace compress --wing myapp --dry-run + +# Compress and store +mempalace compress --wing myapp +``` + +### With entity config + +```bash +mempalace compress --wing myapp --config entities.json +``` + +Entity config format: +```json +{ + "entities": {"Alice": "ALC", "Bob": "BOB"}, + "skip_names": ["Gandalf", "Sherlock"] +} +``` + +### Python API + +```python +from mempalace.dialect import Dialect + +# Basic compression +dialect = Dialect() +compressed = dialect.compress("We decided to use GraphQL...") + +# With entity mappings +dialect = Dialect(entities={"Alice": "ALC", "Kai": "KAI"}) +compressed = dialect.compress(text, metadata={"wing": "myapp", "room": "arch"}) + +# From config file +dialect = Dialect.from_config("entities.json") +``` + +## When to Use AAAK + +AAAK is most useful when: +- You have **many repeated entities** across thousands of sessions +- You need to **compress context** for local models with small windows +- You want **structured summaries** pointing back to verbatim drawers + +For most users, raw verbatim mode is the better default. diff --git a/website/concepts/agents.md b/website/concepts/agents.md new file mode 100644 index 0000000..94c6321 --- /dev/null +++ b/website/concepts/agents.md @@ -0,0 +1,61 @@ +# Specialist Agents + +MemPalace currently supports **agent diaries** through MCP tools. The practical model is simple: give an agent a stable name, and write/read diary entries under that agent's wing. + +::: warning Current Scope +This page documents the diary workflow that exists today. MemPalace does **not** currently ship an agent registry, `~/.mempalace/agents/*.json`, or a `mempalace_list_agents` tool. +::: + +## What Agents Do + +Each agent: + +- **Has a focus** — what it pays attention to +- **Keeps a diary** — entries persist across sessions +- **Can read recent history** — useful for patterns, continuity, and follow-up work + +## Agent Diary + +The diary is a lightweight memory stream for one named agent: observations, findings, decisions, and recurring patterns. + +### Writing Entries + +```text +MCP tool: mempalace_diary_write + arguments: { + "agent_name": "reviewer", + "entry": "PR#42|auth.bypass.found|missing.middleware.check|pattern:3rd.time.this.quarter|★★★★" + } +``` + +### Reading History + +```text +MCP tool: mempalace_diary_read + arguments: { "agent_name": "reviewer", "last_n": 10 } + → returns last 10 findings, compressed in AAAK +``` + +### MCP Tools + +| Tool | Description | +|------|-------------| +| `mempalace_diary_write` | Write an AAAK diary entry | +| `mempalace_diary_read` | Read recent diary entries | + +## How It Works + +Each named agent maps to its own wing in the palace: +- `wing_reviewer` — the reviewer's diary, findings, patterns +- `wing_architect` — the architect's decisions, tradeoffs +- `wing_ops` — the ops agent's incidents, deploys + +All entries go into a `diary` room within the wing, tagged with topic, timestamp, and agent name. + +## Specialization + +Separate diary streams let you keep different working contexts apart. A reviewer can keep bug patterns, an architect can keep decisions, and an ops agent can keep incident notes without mixing them into one shared log. + +::: tip +If you use multiple specialist prompts or toolchains, keep the agent names stable so each one writes back to the same diary wing over time. +::: diff --git a/website/concepts/contradiction-detection.md b/website/concepts/contradiction-detection.md new file mode 100644 index 0000000..ad3ebd9 --- /dev/null +++ b/website/concepts/contradiction-detection.md @@ -0,0 +1,33 @@ +# Contradiction Detection + +::: warning Experimental +Contradiction detection is a planned capability, not a shipped end-to-end feature in the current MCP workflow. The examples below show the intended behavior rather than a fully integrated command path. +::: + +## What It Does + +Checks assertions against entity facts in the knowledge graph. When enabled, it catches contradictions like: + +``` +Input: "Soren finished the auth migration" +Output: 🔴 AUTH-MIGRATION: attribution conflict — Maya was assigned, not Soren + +Input: "Kai has been here 2 years" +Output: 🟡 KAI: wrong_tenure — records show 3 years (started 2023-04) + +Input: "The sprint ends Friday" +Output: 🟡 SPRINT: stale_date — current sprint ends Thursday (updated 2 days ago) +``` + +## How It Works + +Facts are checked against the knowledge graph: +- **Attribution conflicts** — the wrong person credited for a task +- **Temporal errors** — wrong dates, tenures, or durations +- **Stale information** — facts that have been superseded + +Ages, dates, and tenures are calculated dynamically from the entity's recorded facts — not hardcoded. + +## Status + +The current codebase includes the temporal knowledge graph primitives needed for this direction, but not a complete contradiction-checking tool exposed through the CLI or MCP server. diff --git a/website/concepts/knowledge-graph.md b/website/concepts/knowledge-graph.md new file mode 100644 index 0000000..d7969b3 --- /dev/null +++ b/website/concepts/knowledge-graph.md @@ -0,0 +1,91 @@ +# Knowledge Graph + +MemPalace includes a temporal entity-relationship graph — like Zep's Graphiti, but SQLite instead of Neo4j. Local and free. + +## What It Stores + +Entity-relationship triples with temporal validity: + +``` +Subject → Predicate → Object [valid_from → valid_to] +``` + +Facts have time windows. When something stops being true, you invalidate it — and historical queries still find it. + +## Usage + +### Python API + +```python +from mempalace.knowledge_graph import KnowledgeGraph + +kg = KnowledgeGraph() + +# Add facts +kg.add_triple("Kai", "works_on", "Orion", valid_from="2025-06-01") +kg.add_triple("Maya", "assigned_to", "auth-migration", valid_from="2026-01-15") +kg.add_triple("Maya", "completed", "auth-migration", valid_from="2026-02-01") + +# Query: everything about Kai +kg.query_entity("Kai") +# → [Kai → works_on → Orion (current), Kai → recommended → Clerk (2026-01)] + +# Query: what was true in January? +kg.query_entity("Maya", as_of="2026-01-20") +# → [Maya → assigned_to → auth-migration (active)] + +# Timeline +kg.timeline("Orion") +# → chronological story of the project +``` + +### Invalidating Facts + +When something stops being true: + +```python +kg.invalidate("Kai", "works_on", "Orion", ended="2026-03-01") +``` + +Now queries for Kai's current work won't return Orion. Historical queries still will. + +### MCP Tools + +Through the MCP server, the knowledge graph is available as tools: + +| Tool | Description | +|------|-------------| +| `mempalace_kg_query` | Query entity relationships with time filtering | +| `mempalace_kg_add` | Add facts | +| `mempalace_kg_invalidate` | Mark facts as ended | +| `mempalace_kg_timeline` | Chronological entity story | +| `mempalace_kg_stats` | Graph overview | + +## Storage + +The knowledge graph uses SQLite with two tables: + +**`entities`** — people, projects, tools, concepts: +- `id` — lowercase normalized name +- `name` — display name +- `type` — person, project, tool, concept, etc. +- `properties` — JSON blob for extra metadata + +**`triples`** — relationships between entities: +- `subject` → `predicate` → `object` +- `valid_from` — when this became true +- `valid_to` — when it stopped being true (NULL = still current) +- `confidence` — 0.0 to 1.0 +- `source_closet` — link back to the verbatim memory + +Database location: `~/.mempalace/knowledge_graph.sqlite3` + +## Comparison + +| Feature | MemPalace | Zep (Graphiti) | +|---------|-----------|----------------| +| Storage | SQLite (local) | Neo4j (cloud) | +| Cost | Free | $25/mo+ | +| Temporal validity | Yes | Yes | +| Self-hosted | Always | Enterprise only | +| Privacy | Everything local | SOC 2, HIPAA | diff --git a/website/concepts/memory-stack.md b/website/concepts/memory-stack.md new file mode 100644 index 0000000..3442d48 --- /dev/null +++ b/website/concepts/memory-stack.md @@ -0,0 +1,104 @@ +# Memory Stack + +MemPalace uses a 4-layer memory stack. Each layer loads progressively more data only when needed. + +## The Layers + +| Layer | What | Size | When | +|-------|------|------|------| +| **L0** | Identity — who is this AI? | ~50-100 tokens | Always loaded | +| **L1** | Essential Story — top moments | ~500-800 tokens | Always loaded | +| **L2** | Room Recall — filtered retrieval | ~200–500 each | When topic comes up | +| **L3** | Deep Search — full semantic query | Variable | When explicitly asked | + +In the current implementation, a typical wake-up is roughly **~600-900 tokens** for L0 + L1. Searches only fire when needed. + +## Layer 0: Identity + +A plain text file at `~/.mempalace/identity.txt`. Always loaded as the AI's self-concept. + +```text +I am Atlas, a personal AI assistant for Alice. +Traits: warm, direct, remembers everything. +People: Alice (creator), Bob (Alice's partner). +Project: A journaling app that helps people process emotions. +``` + +~50 tokens. Tells the AI who it is and who it works with. + +## Layer 1: Essential Story + +Auto-generated from the highest-importance drawers in the palace. Groups by room, picks the top moments, and keeps the output bounded. + +The generation process: +1. Reads all drawers from ChromaDB +2. Scores each by importance/emotional weight +3. Takes the top 15 moments +4. Groups by room for readability +5. Truncates to fit within 3,200 characters + +``` +## L1 — ESSENTIAL STORY + +[auth-migration] + - Team decided to migrate from Auth0 to Clerk — pricing + DX (session_2026-01-15.md) + - Kai debugged the OAuth token refresh issue (session_2026-01-20.md) + +[deploy-process] + - Switched to blue-green deploys after the January outage (session_2026-02-01.md) +``` + +## Layer 2: On-Demand Recall + +Loaded when a specific topic or wing comes up in conversation. Retrieves drawers filtered by wing and/or room — typically ~200–500 tokens. + +```python +stack = MemoryStack() +stack.recall(wing="driftwood", room="auth") +# → returns recent drawers about auth in the driftwood project +``` + +## Layer 3: Deep Search + +Full semantic search against the entire palace. This is what fires when you or the AI explicitly asks a question. + +```python +stack.search("why did we switch to GraphQL") +# → returns top-5 matching drawers with similarity scores +``` + +## Wake-Up Budget + +The point of the stack is bounded startup context, not a fixed universal token count. The exact size depends on your identity file and what Layer 1 selects, but the implementation keeps wake-up meaningfully smaller than loading the full corpus into the prompt. + +## Using the Stack + +### CLI + +```bash +# Wake-up context (L0 + L1) +mempalace wake-up + +# Project-specific wake-up +mempalace wake-up --wing driftwood +``` + +### Python API + +```python +from mempalace.layers import MemoryStack + +stack = MemoryStack() + +# L0 + L1: wake-up (~600-900 tokens in typical use) +print(stack.wake_up()) + +# L2: on-demand recall +print(stack.recall(wing="myapp")) + +# L3: deep search +print(stack.search("pricing change")) + +# Status +print(stack.status()) +``` diff --git a/website/concepts/the-palace.md b/website/concepts/the-palace.md new file mode 100644 index 0000000..2ef01a4 --- /dev/null +++ b/website/concepts/the-palace.md @@ -0,0 +1,120 @@ +# The Palace + +Ancient Greek orators memorized entire speeches by placing ideas in rooms of an imaginary building. Walk through the building, find the idea. MemPalace applies the same principle to AI memory. + +## Structure + +Your conversations are organized into a navigable hierarchy: + +```mermaid +graph LR + classDef wingPerson fill:#1e1b4b,stroke:#4f46e5,color:#e0e7ff,stroke-width:2px,rx:8px,ry:8px; + classDef wingProject fill:#164e63,stroke:#06b6d4,color:#cffafe,stroke-width:2px,rx:8px,ry:8px; + classDef room fill:#312e81,stroke:#6366f1,color:#e0e7ff,stroke-width:1px,rx:4px,ry:4px; + classDef closet fill:#3b0764,stroke:#8b5cf6,color:#f3e8ff,stroke-width:1px,rx:4px,ry:4px; + classDef drawer fill:#0f766e,stroke:#14b8a6,color:#ccfbf1,stroke-width:1px,rx:4px,ry:4px; + classDef tunnel_link stroke:#8b5cf6,stroke-width:2px,stroke-dasharray: 5 5; + + subgraph W1 [WING: Person] + direction TB + RA["Room A"] + RB["Room B"] + CA["Closet"] + DA["Drawer (verbatim)"] + + RA -- "hall" --> RB + RA --> CA --> DA + end + + subgraph W2 [WING: Project] + direction TB + RA2["Room A"] + RC["Room C"] + CA2["Closet"] + DA2["Drawer (verbatim)"] + + RA2 -- "hall" --> RC + RA2 --> CA2 --> DA2 + end + + RA <==> |tunnel bridge| RA2 + + class W1 wingPerson; + class W2 wingProject; + class RA,RB,RA2,RC room; + class CA,CA2 closet; + class DA,DA2 drawer; +``` + +## Components + +### Wings + +A person or project. As many as you need. + +Every project, person, or topic gets its own wing in the palace. Wings are the top-level organizational unit. + +### Rooms + +Specific topics within a wing. Examples: `auth-migration`, `graphql-switch`, `ci-pipeline`. + +Rooms are named ideas. They're auto-detected from your folder structure during `mempalace init`, and you can create additional rooms manually. + +### Halls + +Halls are the conceptual categories that describe how related memories connect *within* a wing: + +- `hall_facts` — decisions made, choices locked in +- `hall_events` — sessions, milestones, debugging +- `hall_discoveries` — breakthroughs, new insights +- `hall_preferences` — habits, likes, opinions +- `hall_advice` — recommendations and solutions + +### Tunnels + +Connections *between* wings. When the same room appears in different wings, the graph layer can treat that as a cross-wing connection. + +``` +wing_kai / hall_events / auth-migration → "Kai debugged the OAuth token refresh" +wing_driftwood / hall_facts / auth-migration → "team decided to migrate auth to Clerk" +wing_priya / hall_advice / auth-migration → "Priya approved Clerk over Auth0" +``` + +Same room. Three wings. The graph can use that shared room name as a bridge. + +### Closets + +Closets are the summary layer in the broader MemPalace vocabulary: compact notes that point back to the original content. In the current implementation, the main persisted storage path is still the underlying drawer text plus metadata. + +### Drawers + +The original stored text chunks. This is the primary retrieval layer used by the current search and benchmark flows. + +## Why Structure Matters + +Tested on 22,000+ real conversation memories: + +| Search scope | R@10 | Improvement | +|-------------|------|-------------| +| All closets | 60.9% | baseline | +| Within wing | 73.1% | +12% | +| Wing + hall | 84.8% | +24% | +| Wing + room | 94.8% | +34% | + +The practical point is that structure improves retrieval. In the project benchmarks, narrowing the search scope by wing and room outperformed searching the entire corpus at once. + +## Navigation + +The palace supports graph traversal across wings: + +```text +MCP tool: mempalace_traverse + arguments: { "start_room": "auth-migration" } + → discovers rooms in wing_kai, wing_driftwood, wing_priya + +MCP tool: mempalace_find_tunnels + arguments: { "wing_a": "wing_code", "wing_b": "wing_team" } + → auth-migration, deploy-process, ci-pipeline +``` + +This is the navigation story: shared room structure gives the model more than one way to reach relevant context. diff --git a/website/guide/claude-code.md b/website/guide/claude-code.md new file mode 100644 index 0000000..8045fb7 --- /dev/null +++ b/website/guide/claude-code.md @@ -0,0 +1,38 @@ +# Claude Code Plugin + +The recommended way to use MemPalace with Claude Code — native marketplace install. + +## Installation + +```bash +claude plugin marketplace add milla-jovovich/mempalace +claude plugin install --scope user mempalace +``` + +Restart Claude Code, then type `/skills` to verify "mempalace" appears. + +## How It Works + +With the plugin installed, Claude Code automatically: +- Starts the MemPalace MCP server on launch +- Has access to all 19 tools +- Learns the AAAK dialect and memory protocol from the `mempalace_status` response +- Searches the palace before answering questions about past work + +No manual configuration needed. Just ask: + +> *"What did we decide about auth last month?"* + +## Alternative: Manual MCP + +If you prefer manual setup over the marketplace plugin: + +```bash +claude mcp add mempalace -- python -m mempalace.mcp_server +``` + +Both approaches give identical functionality. The plugin approach handles server lifecycle automatically. + +## Hooks + +Set up [auto-save hooks](/guide/hooks) to ensure memories are saved automatically during long conversations. diff --git a/website/guide/configuration.md b/website/guide/configuration.md new file mode 100644 index 0000000..f2efd3f --- /dev/null +++ b/website/guide/configuration.md @@ -0,0 +1,85 @@ +# Configuration + +## Global Config + +Located at `~/.mempalace/config.json`: + +```json +{ + "palace_path": "/custom/path/to/palace", + "collection_name": "mempalace_drawers", + "people_map": {"Kai": "KAI", "Priya": "PRI"} +} +``` + +| Key | Default | Description | +|-----|---------|-------------| +| `palace_path` | `~/.mempalace/palace` | Where ChromaDB stores your drawers | +| `collection_name` | `mempalace_drawers` | ChromaDB collection name | +| `people_map` | `{}` | Entity name → AAAK code mappings | + +## Project Config + +Generated by `mempalace init` in your project directory: + +### `mempalace.yaml` + +```yaml +wing: myproject +rooms: + - backend + - frontend + - decisions +palace_path: ~/.mempalace/palace +``` + +### `entities.json` + +```json +{ + "Kai": "KAI", + "Priya": "PRI" +} +``` + +Wings are auto-detected during `mempalace init` from: +- Directory names → project wings +- Detected people in file content → person wings +- Explicit `--wing` flag on mine commands + +## Identity + +Located at `~/.mempalace/identity.txt`. Plain text. Becomes Layer 0 — loaded every session. + +```text +I am Atlas, a personal AI assistant for Alice. +Traits: warm, direct, remembers everything. +People: Alice (creator), Bob (Alice's partner). +Project: A journaling app that helps people process emotions. +``` + +::: tip +Write your identity file in first person from the AI's perspective. This becomes the AI's self-concept on wake-up. +::: + +## Palace Path Override + +All commands accept `--palace ` to override the default location: + +```bash +mempalace search "query" --palace /tmp/test-palace +mempalace mine ~/data/ --palace /tmp/test-palace +``` + +The MCP server also accepts `--palace`: + +```bash +python -m mempalace.mcp_server --palace /custom/palace +``` + +## Environment Variables + +| Variable | Description | +|----------|-------------| +| `MEMPALACE_PALACE_PATH` | Override palace path (same as `--palace`) | +| `MEMPAL_DIR` | Directory for auto-mining in hooks | diff --git a/website/guide/gemini-cli.md b/website/guide/gemini-cli.md new file mode 100644 index 0000000..2534079 --- /dev/null +++ b/website/guide/gemini-cli.md @@ -0,0 +1,96 @@ +# Gemini CLI + +MemPalace works natively with [Gemini CLI](https://github.com/google/gemini-cli), which handles the MCP server and save hooks automatically. + +## Prerequisites + +- Python 3.9+ +- Gemini CLI installed and configured + +## Installation + +```bash +# Clone the repository +git clone https://github.com/milla-jovovich/mempalace.git +cd mempalace + +# Create a virtual environment +python3 -m venv .venv + +# Install dependencies +.venv/bin/pip install -e . +``` + +## Initialize the Palace + +```bash +.venv/bin/python3 -m mempalace init . +``` + +### Identity and Project Configuration (Optional) + +You can optionally create or edit: + +- **`~/.mempalace/identity.txt`** — plain text describing your role and focus +- **`./mempalace.yaml`** — per-project MemPalace configuration created by `mempalace init` +- **`./entities.json`** — per-project entity mappings used by AAAK compression + +## Connect to Gemini CLI + +Register MemPalace as an MCP server: + +```bash +gemini mcp add mempalace /absolute/path/to/mempalace/.venv/bin/python3 \ + -m mempalace.mcp_server --scope user +``` + +::: warning +Use the **absolute path** to the Python binary to ensure it works from any directory. +::: + +## Enable Auto-Saving + +Add a `PreCompress` hook to `~/.gemini/settings.json`: + +```json +{ + "hooks": { + "PreCompress": [ + { + "matcher": "*", + "hooks": [ + { + "type": "command", + "command": "/absolute/path/to/mempalace/hooks/mempal_precompact_hook.sh" + } + ] + } + ] + } +} +``` + +Make sure the hook scripts are executable: +```bash +chmod +x hooks/*.sh +``` + +## Usage + +Once connected, Gemini CLI will automatically: +- Start the MemPalace server on launch +- Use `mempalace_search` to find relevant past discussions +- Use the `PreCompress` hook to save memories before context compression + +### Manual Mining + +Mine existing code or docs: +```bash +.venv/bin/python3 -m mempalace mine /path/to/your/project +``` + +### Verification + +In a Gemini CLI session: +- `/mcp list` — verify `mempalace` is `CONNECTED` +- `/hooks panel` — verify the `PreCompress` hook is active diff --git a/website/guide/getting-started.md b/website/guide/getting-started.md new file mode 100644 index 0000000..5d32034 --- /dev/null +++ b/website/guide/getting-started.md @@ -0,0 +1,86 @@ +# Getting Started + +## Installation + +Install MemPalace from PyPI: + +```bash +pip install mempalace +``` + +::: danger Security Warning +The domain `mempalace.tech` is a **brand-squatting site** not affiliated with this project. It is known to run ad-redirects and potential malware. The official MemPalace distribution is only available via this [GitHub repository](https://github.com/milla-jovovich/mempalace) and [PyPI](https://pypi.org/project/mempalace/). Never install binaries or scripts from unofficial domains. +::: + +### Requirements + +- Python 3.9+ +- `chromadb>=0.5.0` (installed automatically) +- `pyyaml>=6.0` (installed automatically) + +No API key required for the core local workflow. After installation, the main storage and retrieval path runs locally. + +### From Source + +```bash +git clone https://github.com/milla-jovovich/mempalace.git +cd mempalace +pip install -e ".[dev]" +``` + +## Quick Start + +Three steps: **init**, **mine**, **search**. + +### 1. Initialize Your Palace + +```bash +mempalace init ~/projects/myapp +``` + +This scans your project directory and: +- Detects people and projects from file content +- Creates rooms from your folder structure +- Sets up `~/.mempalace/` config directory + +### 2. Mine Your Data + +```bash +# Mine project files (code, docs, notes) +mempalace mine ~/projects/myapp + +# Mine conversation exports (Claude, ChatGPT, Slack) +mempalace mine ~/chats/ --mode convos + +# Mine with auto-classification into memory types +mempalace mine ~/chats/ --mode convos --extract general +``` + +Two mining modes plus one extraction strategy: +- **projects** — code and docs, auto-detected rooms +- **convos** — conversation exports, chunked by exchange pair +- **general extraction** — an `--extract general` option for conversation mining that classifies content into decisions, preferences, milestones, problems, and emotional context + +### 3. Search + +```bash +mempalace search "why did we switch to GraphQL" +``` + +That gives you a working local memory index. + +## What Happens Next + +After the one-time setup, you don't run MemPalace commands manually. Your AI uses it for you through [MCP integration](/guide/mcp-integration) or a [Claude Code plugin](/guide/claude-code). + +Ask your AI anything: + +> *"What did we decide about auth last month?"* + +It calls `mempalace_search` automatically, gets verbatim results, and answers you. You never type `mempalace search` again. + +## Next Steps + +- [Mining Your Data](/guide/mining) — deep dive into mining modes +- [MCP Integration](/guide/mcp-integration) — connect to Claude, ChatGPT, Cursor, Gemini +- [The Palace](/concepts/the-palace) — understand wings, rooms, halls, and tunnels diff --git a/website/guide/hooks.md b/website/guide/hooks.md new file mode 100644 index 0000000..3345644 --- /dev/null +++ b/website/guide/hooks.md @@ -0,0 +1,116 @@ +# Auto-Save Hooks + +Two hooks for Claude Code and Codex that automatically save memories during work. No manual "save" commands needed. + +## What They Do + +| Hook | When It Fires | What Happens | +|------|--------------|-------------| +| **Save Hook** | Every 15 human messages | Blocks the AI, tells it to save key topics/decisions/quotes to the palace | +| **PreCompact Hook** | Right before context compaction | Emergency save — forces the AI to save everything before losing context | + +The AI does the actual filing — it knows the conversation context, so it classifies memories into the right wings/halls/closets. The hooks just tell it **when** to save. + +## Install — Claude Code + +Add to `.claude/settings.local.json`: + +```json +{ + "hooks": { + "Stop": [{ + "matcher": "*", + "hooks": [{ + "type": "command", + "command": "/absolute/path/to/hooks/mempal_save_hook.sh", + "timeout": 30 + }] + }], + "PreCompact": [{ + "hooks": [{ + "type": "command", + "command": "/absolute/path/to/hooks/mempal_precompact_hook.sh", + "timeout": 30 + }] + }] + } +} +``` + +Make them executable: +```bash +chmod +x hooks/mempal_save_hook.sh hooks/mempal_precompact_hook.sh +``` + +## Install — Codex CLI + +Add to `.codex/hooks.json`: + +```json +{ + "Stop": [{ + "type": "command", + "command": "/absolute/path/to/hooks/mempal_save_hook.sh", + "timeout": 30 + }], + "PreCompact": [{ + "type": "command", + "command": "/absolute/path/to/hooks/mempal_precompact_hook.sh", + "timeout": 30 + }] +} +``` + +## Configuration + +Edit `mempal_save_hook.sh` to change: + +- **`SAVE_INTERVAL=15`** — How many messages between saves. Lower = more frequent, higher = less interruption. +- **`STATE_DIR`** — Where hook state is stored (defaults to `~/.mempalace/hook_state/`) +- **`MEMPAL_DIR`** — Optional. Set to a conversations directory to auto-run `mempalace mine` on each save trigger. + +## How It Works + +### Save Hook (Stop event) + +``` +User sends message → AI responds → Stop hook fires + ↓ + Count human messages in transcript + ↓ + ┌── < 15 since last save → let AI stop + │ + └── ≥ 15 since last save → block + save + ↓ + AI saves to palace + ↓ + AI stops (flag set) +``` + +The `stop_hook_active` flag prevents infinite loops. + +### PreCompact Hook + +``` +Context window full → PreCompact fires → ALWAYS blocks → AI saves → Compaction proceeds +``` + +No counting needed — compaction always warrants a save. + +## Debugging + +```bash +cat ~/.mempalace/hook_state/hook.log +``` + +Example output: +``` +[14:30:15] Session abc123: 12 exchanges, 12 since last save +[14:35:22] Session abc123: 15 exchanges, 15 since last save +[14:35:22] TRIGGERING SAVE at exchange 15 +[14:40:01] Session abc123: 18 exchanges, 3 since last save +``` + +## Cost + +**Zero extra tokens.** The hooks are bash scripts that run locally. They don't call any API. The only "cost" is a few seconds of the AI organizing memories at each checkpoint. diff --git a/website/guide/local-models.md b/website/guide/local-models.md new file mode 100644 index 0000000..fc00283 --- /dev/null +++ b/website/guide/local-models.md @@ -0,0 +1,70 @@ +# Local Models + +MemPalace works with any local LLM — Llama, Mistral, or any offline model. Since local models generally don't speak MCP yet, there are two approaches. + +## Wake-Up Command + +Load your world into the model's context: + +```bash +mempalace wake-up > context.txt +# Paste context.txt into your local model's system prompt +``` + +This gives your local model a bounded wake-up context, typically around **~600-900 tokens** in the current implementation. It includes: +- **Layer 0**: Your identity — who you are, what you work on +- **Layer 1**: Top moments from the palace — key decisions, recent work + +For project-specific context: +```bash +mempalace wake-up --wing driftwood > context.txt +``` + +## CLI Search + +Query on demand, feed results into your prompt: + +```bash +mempalace search "auth decisions" > results.txt +# Include results.txt in your prompt +``` + +## Python API + +For programmatic integration with your local model pipeline: + +```python +from mempalace.searcher import search_memories + +results = search_memories( + "auth decisions", + palace_path="~/.mempalace/palace", +) + +# Format results for your model's context +context = "\n".join( + f"[{r['wing']}/{r['room']}] {r['text']}" + for r in results["results"] +) + +# Inject into your local model's prompt +prompt = f"Context from memory:\n{context}\n\nUser: What did we decide about auth?" +``` + +## AAAK for Compression + +Use [AAAK dialect](/concepts/aaak-dialect) to compress wake-up context further: + +```bash +mempalace compress --wing myapp --dry-run +``` + +AAAK is readable by any LLM that reads text — Claude, GPT, Gemini, Llama, Mistral — without a decoder. + +## Full Offline Stack + +The core memory stack can run offline: +- **ChromaDB** on your machine — vector storage and search +- **Local model** on your machine — reasoning and responses +- **AAAK** for compression — optional, no cloud dependency +- **Optional reranking or external model integrations** may introduce cloud calls, depending on how you configure the system diff --git a/website/guide/mcp-integration.md b/website/guide/mcp-integration.md new file mode 100644 index 0000000..0e00789 --- /dev/null +++ b/website/guide/mcp-integration.md @@ -0,0 +1,101 @@ +# MCP Integration + +MemPalace provides 19 tools through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io/), giving any MCP-compatible AI full read/write access to your palace. + +## Setup + +### Setup Helper + +MemPalace includes a setup helper that prints the exact configuration commands for your environment: + +```bash +mempalace mcp +``` + +### Manual Connection + +```bash +claude mcp add mempalace -- python -m mempalace.mcp_server +``` + +### With Custom Palace Path + +```bash +claude mcp add mempalace -- python -m mempalace.mcp_server --palace /path/to/palace +``` + +Now your AI has all 19 tools available. Ask it anything: + +> *"What did we decide about auth last month?"* + +Claude calls `mempalace_search` automatically, gets verbatim results, and answers you. + +## Compatible Tools + +MemPalace works with any tool that supports MCP: + +- **Claude Code** — native via plugin or manual MCP +- **OpenClaw** — via official skill, see [OpenClaw Skill](/guide/openclaw) +- **ChatGPT** — via MCP bridge +- **Cursor** — native MCP support +- **Gemini CLI** — see [Gemini CLI guide](/guide/gemini-cli) + +## Memory Protocol + +When the AI first calls `mempalace_status`, it receives the **Memory Protocol** — a behavior guide that teaches it to: + +1. **On wake-up**: Call `mempalace_status` to load the palace overview +2. **Before responding** about any person, project, or past event: search first, never guess +3. **If unsure**: Say "let me check" and query the palace +4. **After each session**: Write diary entries to record what happened +5. **When facts change**: Invalidate old facts, add new ones + +This protocol is what turns storage into memory — the AI knows to verify before speaking. + +## Tool Overview + +### Palace (read) + +| Tool | What | +|------|------| +| `mempalace_status` | Palace overview + AAAK spec + memory protocol | +| `mempalace_list_wings` | Wings with counts | +| `mempalace_list_rooms` | Rooms within a wing | +| `mempalace_get_taxonomy` | Full wing → room → count tree | +| `mempalace_search` | Semantic search with wing/room filters | +| `mempalace_check_duplicate` | Check before filing | +| `mempalace_get_aaak_spec` | AAAK dialect reference | + +### Palace (write) + +| Tool | What | +|------|------| +| `mempalace_add_drawer` | File verbatim content | +| `mempalace_delete_drawer` | Remove by ID | + +### Knowledge Graph + +| Tool | What | +|------|------| +| `mempalace_kg_query` | Entity relationships with time filtering | +| `mempalace_kg_add` | Add facts | +| `mempalace_kg_invalidate` | Mark facts as ended | +| `mempalace_kg_timeline` | Chronological entity story | +| `mempalace_kg_stats` | Graph overview | + +### Navigation + +| Tool | What | +|------|------| +| `mempalace_traverse` | Walk the graph from a room across wings | +| `mempalace_find_tunnels` | Find rooms bridging two wings | +| `mempalace_graph_stats` | Graph connectivity overview | + +### Agent Diary + +| Tool | What | +|------|------| +| `mempalace_diary_write` | Write AAAK diary entry | +| `mempalace_diary_read` | Read recent diary entries | + +For detailed schemas and parameters, see [MCP Tools Reference](/reference/mcp-tools). diff --git a/website/guide/mining.md b/website/guide/mining.md new file mode 100644 index 0000000..6040e52 --- /dev/null +++ b/website/guide/mining.md @@ -0,0 +1,134 @@ +# Mining Your Data + +MemPalace ingests your data by **mining** — scanning files and filing their content as verbatim drawers in the palace. + +## Mining Modes + +### Projects Mode (default) + +Scans code, docs, and notes. Respects `.gitignore` by default. + +```bash +mempalace mine ~/projects/myapp +``` + +Each file becomes a drawer, tagged with a wing (project name) and room (topic). Rooms are auto-detected from your folder structure during `mempalace init`. + +Options: +```bash +# Override wing name +mempalace mine ~/projects/myapp --wing myapp + +# Ignore .gitignore rules +mempalace mine ~/projects/myapp --no-gitignore + +# Include specific ignored paths +mempalace mine ~/projects/myapp --include-ignored dist,build + +# Limit number of files +mempalace mine ~/projects/myapp --limit 100 + +# Preview without filing +mempalace mine ~/projects/myapp --dry-run +``` + +### Conversations Mode + +Indexes conversation exports from Claude, ChatGPT, Slack, and other tools. Chunks by exchange pair (human + assistant turns). + +```bash +mempalace mine ~/chats/ --mode convos +``` + +Supports five chat formats automatically: +- Claude JSON exports +- ChatGPT exports +- Slack exports +- Markdown conversations +- Plain text transcripts + +### General Extraction + +Auto-classifies conversation content into five memory types: + +```bash +mempalace mine ~/chats/ --mode convos --extract general +``` + +Memory types: +- **Decisions** — choices made, options rejected +- **Preferences** — habits, likes, opinions +- **Milestones** — sessions completed, goals reached +- **Problems** — bugs, blockers, issues encountered +- **Emotional context** — reactions, concerns, excitement + +## Splitting Mega-Files + +Some transcript exports concatenate multiple sessions into one huge file. Split them first: + +```bash +# Preview what would be split +mempalace split ~/chats/ --dry-run + +# Split files with 2+ sessions (default) +mempalace split ~/chats/ + +# Only split files with 3+ sessions +mempalace split ~/chats/ --min-sessions 3 + +# Output to a different directory +mempalace split ~/chats/ --output-dir ~/chats-split/ +``` + +::: tip +Always run `mempalace split` before mining conversation files. It's a no-op if files don't need splitting. +::: + +## Multi-Project Setup + +Mine each project into its own wing: + +```bash +mempalace mine ~/chats/orion/ --mode convos --wing orion +mempalace mine ~/chats/nova/ --mode convos --wing nova +mempalace mine ~/chats/helios/ --mode convos --wing helios +``` + +Six months later: +```bash +# Project-specific search +mempalace search "database decision" --wing orion + +# Cross-project search +mempalace search "rate limiting approach" +# → finds your approach in Orion AND Nova, shows the differences +``` + +## Team Usage + +Mine Slack exports and AI conversations for team history: + +```bash +mempalace mine ~/exports/slack/ --mode convos --wing driftwood +mempalace mine ~/.claude/projects/ --mode convos +``` + +Then search across people and projects: +```bash +mempalace search "Soren sprint" --wing driftwood +# → 14 closets: OAuth refactor, dark mode, component library migration +``` + +## Agent Tag + +Every drawer is tagged with the agent that filed it: + +```bash +# Default agent name +mempalace mine ~/data/ --agent mempalace + +# Custom agent name +mempalace mine ~/data/ --agent reviewer +``` + +This is used by [Specialist Agents](/concepts/agents) to partition memories. diff --git a/website/guide/openclaw.md b/website/guide/openclaw.md new file mode 100644 index 0000000..b6bf421 --- /dev/null +++ b/website/guide/openclaw.md @@ -0,0 +1,35 @@ +# OpenClaw Skill + +MemPalace provides an official skill for [OpenClaw](https://github.com/openclaw/openclaw), making it trivial to give your ClawHub agents complete access to the palace's declarative memory and knowledge graph. + +## Installation + +The skill is built right into the `integrations/openclaw` directory of MemPalace. + +You can add MemPalace as an MCP server to OpenClaw via the CLI: + +```bash +openclaw mcp set mempalace '{"command":"python3","args":["-m","mempalace.mcp_server"]}' +``` + +Or by directly editing your OpenClaw configuration: + +```json +{ + "mcpServers": { + "mempalace": { + "command": "python3", + "args": ["-m", "mempalace.mcp_server"] + } + } +} +``` + +## How It Works + +Once connected, OpenClaw agents receive all 19 tools along with the **Memory Protocol**—a strict behavioral guide indicating they should: +1. **Never guess**: Query `mempalace_search` or `mempalace_kg_query` before confidently answering. +2. **Keep an agent diary**: Maintain continuity between sessions by writing to `mempalace_diary_write`. +3. **Manage the Knowledge Graph**: Update declarative facts when things change using `mempalace_kg_add` and `mempalace_kg_invalidate`. + +By connecting OpenClaw to MemPalace, you get both autonomous code execution and persistent, high-recall memory in the same workflow. diff --git a/website/guide/searching.md b/website/guide/searching.md new file mode 100644 index 0000000..e9c0bbb --- /dev/null +++ b/website/guide/searching.md @@ -0,0 +1,107 @@ +# Searching Memories + +MemPalace uses ChromaDB's semantic vector search to find relevant memories. When you search, you get **verbatim text** — the exact words, never summaries. + +## CLI Search + +```bash +# Search everything +mempalace search "why did we switch to GraphQL" + +# Filter by wing (project) +mempalace search "database decision" --wing myapp + +# Filter by room (topic) +mempalace search "auth decisions" --room auth-migration + +# Filter by both +mempalace search "pricing" --wing driftwood --room costs + +# More results +mempalace search "deploy process" --results 10 +``` + +## How Search Works + +1. Your query is embedded using ChromaDB's default model (`all-MiniLM-L6-v2`) +2. The embedding is compared against all drawers using cosine similarity +3. Optional wing/room filters narrow the search scope +4. Results are returned with similarity scores and source metadata + +### Why Structure Matters + +Tested on 22,000+ real conversation memories: + +``` +Search all closets: 60.9% R@10 +Search within wing: 73.1% (+12%) +Search wing + hall: 84.8% (+24%) +Search wing + room: 94.8% (+34%) +``` + +Wings and rooms aren't cosmetic — they're a **34% retrieval improvement**. + +## Programmatic Search + +Use the Python API for integration: + +```python +from mempalace.searcher import search_memories + +results = search_memories( + query="auth decisions", + palace_path="~/.mempalace/palace", + wing="myapp", + room="auth", + n_results=5, +) + +for hit in results["results"]: + print(f"[{hit['similarity']}] {hit['wing']}/{hit['room']}") + print(f" {hit['text'][:200]}") +``` + +The `search_memories()` function returns a dict: + +```python +{ + "query": "auth decisions", + "filters": {"wing": "myapp", "room": "auth"}, + "results": [ + { + "text": "We decided to migrate auth to Clerk because...", + "wing": "myapp", + "room": "auth-migration", + "source_file": "session_2026-01-15.md", + "similarity": 0.892, + }, + # ... + ], +} +``` + +## MCP Search + +When connected via MCP, your AI searches automatically: + +> *"What did we decide about auth last month?"* + +The AI calls `mempalace_search` behind the scenes. You never type a search command. + +See [MCP Integration](/guide/mcp-integration) for setup. + +## Wake-Up Context + +Instead of searching, you can load a compact context of your world: + +```bash +# Load identity + top memories (~600-900 tokens in typical use) +mempalace wake-up + +# Project-specific context +mempalace wake-up --wing driftwood +``` + +This loads Layer 0 (identity) and Layer 1 (essential story) as bounded startup context before the first retrieval call. + +See [Memory Stack](/concepts/memory-stack) for details on the 4-layer architecture. diff --git a/website/index.md b/website/index.md new file mode 100644 index 0000000..88bc694 --- /dev/null +++ b/website/index.md @@ -0,0 +1,87 @@ +--- +layout: home + +hero: + name: MemPalace + text: Give your AI a memory. + tagline: "96.6% recall on LongMemEval in raw mode. Local-first, open source, and usable without an API key." + image: + src: /mempalace_logo.png + alt: MemPalace + actions: + - theme: brand + text: Get Started + link: /guide/getting-started + - theme: alt + text: Architecture → + link: /concepts/the-palace + - theme: alt + text: GitHub ↗ + link: https://github.com/milla-jovovich/mempalace + +features: + - icon: + src: /icons/file-text.svg + alt: Verbatim Storage + title: Verbatim Storage + details: Store source text directly instead of extracting facts up front. The raw benchmark result comes from retrieving verbatim content. + - icon: + src: /icons/building-2.svg + alt: Palace Structure + title: Palace Structure + details: Wings and rooms give retrieval useful structure. In the project benchmarks, narrowing search scope outperformed flat search. + - icon: + src: /icons/search.svg + alt: Semantic Search + title: Semantic Search + details: ChromaDB-powered vector search lets the model retrieve past discussions by topic, project, or room. + - icon: + src: /icons/git-merge.svg + alt: Knowledge Graph + title: Knowledge Graph + details: Temporal entity-relationship triples in SQLite. Facts can be added, queried, and invalidated over time. + - icon: + src: /icons/wrench.svg + alt: 19 MCP Tools + title: 19 MCP Tools + details: MCP tools expose search, filing, knowledge graph, graph navigation, and diary operations to compatible clients. + - icon: + src: /icons/shield-check.svg + alt: Zero Cloud + title: Zero Cloud + details: Core storage and retrieval run locally on ChromaDB and SQLite. Optional reranking features can add an API dependency. +--- + + + +
+ +## Verbatim Retrieval First + +MemPalace starts from a simple premise: **store the source text and retrieve it well**. The benchmarked raw mode does not require an LLM extraction step. + +| System | LongMemEval R@5 | API Required | Cost | +|--------|----------------|--------------|------| +| **MemPalace (hybrid)** | **100%** | Optional | Free | +| Supermemory ASMR | ~99% | Yes | — | +| **MemPalace (raw)** | **96.6%** | **None** | **Free** | +| Mastra | 94.87% | Yes | API costs | +| Mem0 | ~85% | Yes | $19–249/mo | + +The raw 96.6% LongMemEval result is the baseline story: strong recall without requiring an API key or an LLM in the retrieval pipeline. + +
+ Full benchmark results → +
+ +
diff --git a/website/package.json b/website/package.json new file mode 100644 index 0000000..e4bcc28 --- /dev/null +++ b/website/package.json @@ -0,0 +1,17 @@ +{ + "name": "mempalace-docs", + "private": true, + "type": "module", + "scripts": { + "docs:dev": "vitepress dev", + "docs:build": "vitepress build", + "docs:preview": "vitepress preview" + }, + "devDependencies": { + "@lucide/vue": "^1.8.0", + "mermaid": "^11.14.0", + "vitepress": "^1.6.4", + "vitepress-plugin-mermaid": "^2.0.17", + "vue": "^3.5.32" + } +} diff --git a/website/public/icons/building-2.svg b/website/public/icons/building-2.svg new file mode 100644 index 0000000..9be8358 --- /dev/null +++ b/website/public/icons/building-2.svg @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/website/public/icons/file-text.svg b/website/public/icons/file-text.svg new file mode 100644 index 0000000..d927e0e --- /dev/null +++ b/website/public/icons/file-text.svg @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/website/public/icons/git-merge.svg b/website/public/icons/git-merge.svg new file mode 100644 index 0000000..31199c4 --- /dev/null +++ b/website/public/icons/git-merge.svg @@ -0,0 +1,17 @@ + + + + + + diff --git a/website/public/icons/search.svg b/website/public/icons/search.svg new file mode 100644 index 0000000..93ffc47 --- /dev/null +++ b/website/public/icons/search.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/website/public/icons/shield-check.svg b/website/public/icons/shield-check.svg new file mode 100644 index 0000000..36ee45c --- /dev/null +++ b/website/public/icons/shield-check.svg @@ -0,0 +1,16 @@ + + + + + diff --git a/website/public/icons/wrench.svg b/website/public/icons/wrench.svg new file mode 100644 index 0000000..741cd6a --- /dev/null +++ b/website/public/icons/wrench.svg @@ -0,0 +1,15 @@ + + + + diff --git a/website/public/mempalace_logo.png b/website/public/mempalace_logo.png new file mode 100644 index 0000000..7cd48d8 Binary files /dev/null and b/website/public/mempalace_logo.png differ diff --git a/website/reference/api-reference.md b/website/reference/api-reference.md new file mode 100644 index 0000000..da77a7c --- /dev/null +++ b/website/reference/api-reference.md @@ -0,0 +1,246 @@ +# API Reference + +Comprehensive parameter-level documentation for all public Python APIs. + +## `mempalace.searcher` + +### `search(query, palace_path, wing=None, room=None, n_results=5)` + +CLI-oriented search that prints results to stdout. + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `query` | `str` | — | Search query text | +| `palace_path` | `str` | — | Path to ChromaDB palace directory | +| `wing` | `str` | `None` | Filter by wing name | +| `room` | `str` | `None` | Filter by room name | +| `n_results` | `int` | `5` | Maximum number of results | + +**Raises:** `SearchError` if palace not found or query fails. + +--- + +### `search_memories(query, palace_path, wing=None, room=None, n_results=5) → dict` + +Programmatic search returning a dict. Used by the MCP server. + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `query` | `str` | — | Search query text | +| `palace_path` | `str` | — | Path to ChromaDB palace directory | +| `wing` | `str` | `None` | Filter by wing name | +| `room` | `str` | `None` | Filter by room name | +| `n_results` | `int` | `5` | Maximum number of results | + +**Returns:** +```python +{ + "query": str, + "filters": {"wing": str | None, "room": str | None}, + "results": [ + { + "text": str, # verbatim drawer content + "wing": str, # wing name + "room": str, # room name + "source_file": str, # original file basename + "similarity": float, # 0.0 to 1.0 + } + ] +} +``` + +On error: `{"error": str, "hint": str}` + +--- + +## `mempalace.layers` + +### `class Layer0(identity_path=None)` + +Identity layer (~50 tokens). Reads from `~/.mempalace/identity.txt`. + +| Method | Returns | Description | +|--------|---------|-------------| +| `render()` | `str` | Identity text or default message | +| `token_estimate()` | `int` | Approximate token count (`len(text) // 4`) | + +--- + +### `class Layer1(palace_path=None, wing=None)` + +Essential story layer (~500–800 tokens). Auto-generated from top drawers. + +| Attribute | Type | Description | +|-----------|------|-------------| +| `MAX_DRAWERS` | `int` | Max moments in wake-up (15) | +| `MAX_CHARS` | `int` | Hard cap on L1 text (3200) | + +| Method | Returns | Description | +|--------|---------|-------------| +| `generate()` | `str` | Compact L1 text grouped by room | + +--- + +### `class Layer2(palace_path=None)` + +On-demand retrieval layer (~200–500 tokens per call). + +| Method | Parameters | Returns | +|--------|-----------|---------| +| `retrieve(wing, room, n_results=10)` | Wing/room filters | Formatted drawer text | + +--- + +### `class Layer3(palace_path=None)` + +Deep semantic search layer (unlimited depth). + +| Method | Parameters | Returns | +|--------|-----------|---------| +| `search(query, wing=None, room=None, n_results=5)` | Query + optional filters | Formatted result text | +| `search_raw(query, wing=None, room=None, n_results=5)` | Query + optional filters | List of result dicts | + +--- + +### `class MemoryStack(palace_path=None, identity_path=None)` + +Unified 4-layer interface. + +| Method | Parameters | Returns | Description | +|--------|-----------|---------|-------------| +| `wake_up(wing=None)` | Optional wing | `str` | L0 + L1 context (~170–900 tokens) | +| `recall(wing, room, n_results=10)` | Filters | `str` | L2 on-demand retrieval | +| `search(query, wing, room, n_results=5)` | Query + filters | `str` | L3 deep search | +| `status()` | — | `dict` | All layer status info | + +--- + +## `mempalace.knowledge_graph` + +### `class KnowledgeGraph(db_path=None)` + +Default path: `~/.mempalace/knowledge_graph.sqlite3` + +#### Write Methods + +| Method | Parameters | Returns | Description | +|--------|-----------|---------|-------------| +| `add_entity(name, entity_type='unknown', properties=None)` | Name, type, props dict | `str` (entity ID) | Add or update entity node | +| `add_triple(subject, predicate, obj, valid_from, valid_to, confidence, source_closet, source_file)` | See below | `str` (triple ID) | Add relationship triple | +| `invalidate(subject, predicate, obj, ended=None)` | Entity names, end date | — | Mark relationship as ended | + +**`add_triple` parameters:** + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `subject` | `str` | — | Source entity name | +| `predicate` | `str` | — | Relationship type | +| `obj` | `str` | — | Target entity name | +| `valid_from` | `str` | `None` | Start date (YYYY-MM-DD) | +| `valid_to` | `str` | `None` | End date | +| `confidence` | `float` | `1.0` | Confidence score 0.0–1.0 | +| `source_closet` | `str` | `None` | Link to verbatim memory | +| `source_file` | `str` | `None` | Original source file | + +#### Query Methods + +| Method | Parameters | Returns | +|--------|-----------|---------| +| `query_entity(name, as_of=None, direction='outgoing')` | Entity name, date filter, direction | `list[dict]` | +| `query_relationship(predicate, as_of=None)` | Relationship type, date filter | `list[dict]` | +| `timeline(entity_name=None)` | Optional entity filter | `list[dict]` | +| `stats()` | — | `dict` with entities, triples, predicates | +| `seed_from_entity_facts(entity_facts)` | Dict of entity facts | — | + +**`query_entity` direction values:** `"outgoing"` (entity→?), `"incoming"` (?→entity), `"both"` + +--- + +## `mempalace.palace_graph` + +### `build_graph(col=None, config=None) → (nodes, edges)` + +Build the palace graph from ChromaDB metadata. + +**Returns:** +- `nodes`: `dict` of `{room: {wings: list, halls: list, count: int, dates: list}}` +- `edges`: `list` of `{room, wing_a, wing_b, hall, count}` + +--- + +### `traverse(start_room, col=None, config=None, max_hops=2) → list` + +BFS graph traversal from a room across wings. + +| Parameter | Type | Default | Description | +|-----------|------|---------|-------------| +| `start_room` | `str` | — | Room slug to start from | +| `max_hops` | `int` | `2` | Max connection depth | + +**Returns:** `[{room, wings, halls, count, hop, connected_via}]` (max 50) + +--- + +### `find_tunnels(wing_a=None, wing_b=None, col=None, config=None) → list` + +Find rooms spanning multiple wings. + +**Returns:** `[{room, wings, halls, count, recent}]` (max 50) + +--- + +### `graph_stats(col=None, config=None) → dict` + +**Returns:** `{total_rooms, tunnel_rooms, total_edges, rooms_per_wing, top_tunnels}` + +--- + +## `mempalace.dialect` + +### `class Dialect(entities=None, skip_names=None)` + +| Parameter | Type | Description | +|-----------|------|-------------| +| `entities` | `dict[str, str]` | Full name → 3-letter code mapping | +| `skip_names` | `list[str]` | Names to skip (fictional characters, etc.) | + +#### Class Methods + +| Method | Parameters | Returns | +|--------|-----------|---------| +| `from_config(config_path)` | JSON file path | `Dialect` instance | + +#### Instance Methods + +| Method | Parameters | Returns | Description | +|--------|-----------|---------|-------------| +| `compress(text, metadata=None)` | Plain text + optional metadata dict | `str` | AAAK-formatted summary | +| `encode_entity(name)` | Entity name | `str \| None` | 3-letter entity code | +| `encode_emotions(emotions)` | List of emotion strings | `str` | Compact emotion codes | +| `compress_file(path, output=None)` | Zettel JSON path | `str` | Compress zettel file | +| `compress_all(dir, output=None)` | Zettel directory | `str` | Compress all zettels | +| `save_config(path)` | Output path | — | Save entity mappings | +| `compression_stats(original, compressed)` | Both texts | `dict` | Compression ratio stats | + +#### Static Methods + +| Method | Parameters | Returns | +|--------|-----------|---------| +| `count_tokens(text)` | Any text | `int` | + +--- + +## `mempalace.config` + +### `class MempalaceConfig()` + +Reads from `~/.mempalace/config.json` and environment variables. + +| Property | Type | Default | Description | +|----------|------|---------|-------------| +| `palace_path` | `str` | `~/.mempalace/palace` | ChromaDB storage path | +| `collection_name` | `str` | `mempalace_drawers` | ChromaDB collection name | + +| Method | Description | +|--------|-------------| +| `init()` | Create config directory and default files | diff --git a/website/reference/benchmarks.md b/website/reference/benchmarks.md new file mode 100644 index 0000000..7a37916 --- /dev/null +++ b/website/reference/benchmarks.md @@ -0,0 +1,95 @@ +# Benchmarks + +Curated summary of MemPalace benchmark results. For the full 725-line progression with every experiment, see [`benchmarks/BENCHMARKS.md`](https://github.com/milla-jovovich/mempalace/blob/main/benchmarks/BENCHMARKS.md) in the repository. + +## The Core Finding + +MemPalace's benchmarked raw baseline stores the source text and searches it with ChromaDB's default embeddings. No extraction layer or summarization step is required for that baseline. + +**And it scores 96.6% on LongMemEval.** + +## LongMemEval Results + +| Mode | R@5 | LLM Required | Cost/query | +|------|-----|-------------|------------| +| Raw ChromaDB | **96.6%** | None | $0 | +| Hybrid v3 + rerank | 99.4% | Haiku | ~$0.001 | +| Palace + rerank | 99.4% | Haiku | ~$0.001 | +| **Hybrid v4 + rerank** | **100%** | Haiku | ~$0.001 | + +The 96.6% raw score requires no API key, no cloud, and no LLM at any stage. The 100% result uses optional Haiku reranking. + +### Per-Category Breakdown (Raw, 96.6%) + +| Question Type | R@5 | Count | +|---------------|-----|-------| +| Knowledge update | 99.0% | 78 | +| Multi-session | 98.5% | 133 | +| Temporal reasoning | 96.2% | 133 | +| Single-session user | 95.7% | 70 | +| Single-session preference | 93.3% | 30 | +| Single-session assistant | 92.9% | 56 | + +### Held-Out Validation + +**98.4% R@5** on 450 questions that hybrid_v4 was never tuned on — confirming the improvements generalize. + +## Comparison vs Published Systems + +| System | LongMemEval R@5 | API Required | Cost | +|--------|----------------|--------------|------| +| **MemPalace (hybrid)** | **100%** | Optional | Free | +| Supermemory ASMR | ~99% | Yes | — | +| **MemPalace (raw)** | **96.6%** | **None** | **Free** | +| Mastra | 94.87% | Yes | API costs | +| Hindsight | 91.4% | Yes | API costs | +| Mem0 | ~85% | Yes | $19–249/mo | + +## Other Benchmarks + +### ConvoMem (Salesforce, 75K+ QA pairs) + +| System | Score | +|--------|-------| +| **MemPalace** | **92.9%** | +| Gemini (long context) | 70–82% | +| Block extraction | 57–71% | +| Mem0 (RAG) | 30–45% | + +On this benchmark, MemPalace materially outperforms the Mem0 result cited in the comparison table. + +### LoCoMo (1,986 multi-hop QA pairs) + +| Mode | R@10 | LLM | +|------|------|-----| +| Hybrid v5 + Sonnet rerank (top-50) | **100%** | Sonnet | +| bge-large + Haiku rerank (top-15) | 96.3% | Haiku | +| Hybrid v5 (top-10, no rerank) | **88.9%** | None | +| Session, no rerank (top-10) | 60.3% | None | + +### MemBench (ACL 2025, 8,500 items) + +**80.3% R@5** overall. Strongest categories: aggregative (99.3%), comparative (98.4%), lowlevel_rec (99.8%). + +## Reproducing Results + +All benchmarks are reproducible with public datasets: + +```bash +git clone https://github.com/milla-jovovich/mempalace.git +cd mempalace +pip install chromadb pyyaml + +# Download LongMemEval data +curl -fsSL -o /tmp/longmemeval_s_cleaned.json \ + https://huggingface.co/datasets/xiaowu0162/longmemeval-cleaned/resolve/main/longmemeval_s_cleaned.json + +# Run raw baseline (96.6%, no API key needed) +python benchmarks/longmemeval_bench.py /tmp/longmemeval_s_cleaned.json +``` + +::: tip +Results are deterministic. Same data + same script = same result every time. Every result JSONL file contains every question, every retrieved document, every score. +::: + +For complete reproduction instructions, benchmark integrity notes, and the full score progression, see the [full benchmark documentation](https://github.com/milla-jovovich/mempalace/blob/main/benchmarks/BENCHMARKS.md). diff --git a/website/reference/cli.md b/website/reference/cli.md new file mode 100644 index 0000000..3bf054c --- /dev/null +++ b/website/reference/cli.md @@ -0,0 +1,165 @@ +# CLI Commands + +All commands accept `--palace ` to override the default palace location. + +## `mempalace init` + +Detect rooms from your folder structure and set up the palace. + +```bash +mempalace init +mempalace init --yes # non-interactive mode +``` + +| Option | Description | +|--------|-------------| +| `` | Project directory to scan | +| `--yes` | Auto-accept all detected entities | + +What it does: +1. Scans for people and projects in file content +2. Detects rooms from folder structure +3. Creates `~/.mempalace/` config directory +4. Saves detected entities to `/entities.json` + +## `mempalace mine` + +Mine files into the palace. + +```bash +mempalace mine +mempalace mine --mode convos +mempalace mine --mode convos --extract general +mempalace mine --wing myapp +``` + +| Option | Default | Description | +|--------|---------|-------------| +| `` | — | Directory to mine | +| `--mode` | `projects` | `projects` for code/docs, `convos` for chat exports | +| `--wing` | directory name | Wing name override | +| `--agent` | `mempalace` | Agent name tag | +| `--limit` | `0` (all) | Max files to process | +| `--dry-run` | — | Preview without filing | +| `--extract` | `exchange` | `exchange` or `general` (for convos mode) | +| `--no-gitignore` | — | Don't respect .gitignore | +| `--include-ignored` | — | Always scan these paths even if ignored | + +## `mempalace search` + +Find anything by semantic search. + +```bash +mempalace search "query" +mempalace search "query" --wing myapp +mempalace search "query" --wing myapp --room auth +mempalace search "query" --results 10 +``` + +| Option | Default | Description | +|--------|---------|-------------| +| `"query"` | — | What to search for | +| `--wing` | all | Filter by wing | +| `--room` | all | Filter by room | +| `--results` | `5` | Number of results | + +## `mempalace split` + +Split concatenated transcript mega-files into per-session files. + +```bash +mempalace split +mempalace split --dry-run +mempalace split --min-sessions 3 +mempalace split --output-dir ~/split-output/ +``` + +| Option | Default | Description | +|--------|---------|-------------| +| `` | — | Directory with transcript files | +| `--output-dir` | same dir | Write split files here | +| `--dry-run` | — | Preview without writing | +| `--min-sessions` | `2` | Only split files with N+ sessions | + +## `mempalace wake-up` + +Show L0 + L1 wake-up context (~170–900 tokens). + +```bash +mempalace wake-up +mempalace wake-up --wing driftwood +``` + +| Option | Description | +|--------|-------------| +| `--wing` | Project-specific wake-up | + +## `mempalace compress` + +Compress drawers using AAAK Dialect. + +```bash +mempalace compress --wing myapp +mempalace compress --wing myapp --dry-run +mempalace compress --config entities.json +``` + +| Option | Description | +|--------|-------------| +| `--wing` | Wing to compress (default: all) | +| `--dry-run` | Preview without storing | +| `--config` | Entity config JSON file | + +## `mempalace status` + +Show what's been filed — drawer count, wing/room breakdown. + +```bash +mempalace status +``` + +## `mempalace repair` + +Rebuild palace vector index from stored data. Fixes segfaults after database corruption. + +```bash +mempalace repair +``` + +Creates a backup at `.backup` before rebuilding. + +## `mempalace mcp` + +Helper command that outputs setup syntax (like `claude mcp add...`) to connect MemPalace to your AI client, automatically handling paths. + +```bash +mempalace mcp +mempalace mcp --palace ~/.custom-palace +``` + +## `mempalace hook` + +Run hook logic for Claude Code / Codex integration. + +```bash +mempalace hook run --hook stop --harness claude-code +mempalace hook run --hook precompact --harness claude-code +mempalace hook run --hook session-start --harness codex +``` + +| Option | Values | Description | +|--------|--------|-------------| +| `--hook` | `session-start`, `stop`, `precompact` | Hook name | +| `--harness` | `claude-code`, `codex` | Harness type | + +## `mempalace instructions` + +Output skill instructions to stdout. + +```bash +mempalace instructions init +mempalace instructions search +mempalace instructions mine +mempalace instructions help +mempalace instructions status +``` diff --git a/website/reference/contributing.md b/website/reference/contributing.md new file mode 100644 index 0000000..9a1364a --- /dev/null +++ b/website/reference/contributing.md @@ -0,0 +1,81 @@ +# Contributing + +PRs welcome. MemPalace is open source and we welcome contributions of all sizes — from typo fixes to new features. + +## Getting Started + +```bash +git clone https://github.com/milla-jovovich/mempalace.git +cd mempalace +pip install -e ".[dev]" +``` + +## Running Tests + +```bash +pytest tests/ -v +``` + +All tests must pass before submitting a PR. Tests should run without API keys or network access. + +## Running Benchmarks + +```bash +# Quick test (20 questions, ~30 seconds) +python benchmarks/longmemeval_bench.py /path/to/longmemeval_s_cleaned.json --limit 20 + +# Full benchmark (500 questions, ~5 minutes) +python benchmarks/longmemeval_bench.py /path/to/longmemeval_s_cleaned.json +``` + +See [Benchmarks](/reference/benchmarks) for data download instructions. + +## PR Guidelines + +1. Fork the repo and create a feature branch: `git checkout -b feat/my-thing` +2. Write your code +3. Add or update tests if applicable +4. Run `pytest tests/ -v` — everything must pass +5. Commit with clear [conventional commits](https://www.conventionalcommits.org/): + - `feat: add Notion export format` + - `fix: handle empty transcript files` + - `docs: update MCP tool descriptions` + - `bench: add LoCoMo turn-level metrics` +6. Push to your fork and open a PR against `main` + +## Code Style + +- **Formatting**: [Ruff](https://docs.astral.sh/ruff/) with 100-char line limit +- **Naming**: `snake_case` for functions/variables, `PascalCase` for classes +- **Docstrings**: on all modules and public functions +- **Type hints**: where they improve readability +- **Dependencies**: minimize — ChromaDB + PyYAML only. Don't add new deps without discussion. + +## Good First Issues + +Check the [Issues](https://github.com/milla-jovovich/mempalace/issues) tab: + +- **New chat formats** — add import support for Cursor, Copilot, or other AI tool exports +- **Room detection** — improve pattern matching in `room_detector_local.py` +- **Tests** — increase coverage, especially for `knowledge_graph.py` and `palace_graph.py` +- **Entity detection** — better name disambiguation in `entity_detector.py` +- **Docs** — improve examples, add tutorials + +## Architecture Decisions + +If you're planning a significant change, open an issue first. Key principles: + +- **Verbatim first** — never summarize user content. Store exact words. +- **Local first** — everything runs on the user's machine. No cloud dependencies. +- **Zero API by default** — core features must work without any API key. +- **Palace structure matters** — wings, halls, and rooms aren't cosmetic — they drive a 34% retrieval improvement. + +## Community + +- [Discord](https://discord.com/invite/ycTQQCu6kn) +- [GitHub Issues](https://github.com/milla-jovovich/mempalace/issues) — bug reports and feature requests +- [GitHub Discussions](https://github.com/milla-jovovich/mempalace/discussions) — questions and ideas + +## License + +MIT — your contributions will be released under the same license. diff --git a/website/reference/mcp-tools.md b/website/reference/mcp-tools.md new file mode 100644 index 0000000..d20d8f4 --- /dev/null +++ b/website/reference/mcp-tools.md @@ -0,0 +1,249 @@ +# MCP Tools Reference + +Detailed parameter schemas for all 19 MCP tools. + +## Palace — Read Tools + +### `mempalace_status` + +Palace overview: total drawers, wing and room counts, AAAK spec, and memory protocol. + +**Parameters:** None + +**Returns:** `{ total_drawers, wings, rooms, palace_path, protocol, aaak_dialect }` + +--- + +### `mempalace_list_wings` + +List all wings with drawer counts. + +**Parameters:** None + +**Returns:** `{ wings: { "wing_name": count } }` + +--- + +### `mempalace_list_rooms` + +List rooms within a wing (or all rooms if no wing given). + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `wing` | string | No | Wing to list rooms for | + +**Returns:** `{ wing, rooms: { "room_name": count } }` + +--- + +### `mempalace_get_taxonomy` + +Full wing → room → drawer count tree. + +**Parameters:** None + +**Returns:** `{ taxonomy: { "wing": { "room": count } } }` + +--- + +### `mempalace_search` + +Semantic search. Returns verbatim drawer content with similarity scores. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `query` | string | **Yes** | What to search for | +| `limit` | integer | No | Max results (default: 5) | +| `wing` | string | No | Filter by wing | +| `room` | string | No | Filter by room | + +**Returns:** `{ query, filters, results: [{ text, wing, room, source_file, similarity }] }` + +--- + +### `mempalace_check_duplicate` + +Check if content already exists in the palace before filing. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `content` | string | **Yes** | Content to check | +| `threshold` | number | No | Similarity threshold 0–1 (default: 0.85–0.87) | + +**Returns:** `{ is_duplicate, matches: [{ id, wing, room, similarity, content }] }` + +--- + +### `mempalace_get_aaak_spec` + +Returns the AAAK dialect specification. + +**Parameters:** None + +**Returns:** `{ aaak_spec: "..." }` + +--- + +## Palace — Write Tools + +### `mempalace_add_drawer` + +File verbatim content into the palace. Identical content (same deterministic drawer ID) is silently skipped. For similarity-based duplicate detection before filing, use `mempalace_check_duplicate`. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `wing` | string | **Yes** | Wing (project name) | +| `room` | string | **Yes** | Room (aspect: backend, decisions, etc.) | +| `content` | string | **Yes** | Verbatim content to store | +| `source_file` | string | No | Where this came from | +| `added_by` | string | No | Who is filing (default: "mcp") | + +**Returns:** `{ success, drawer_id, wing, room }` + +--- + +### `mempalace_delete_drawer` + +Delete a drawer by ID. Irreversible. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `drawer_id` | string | **Yes** | ID of the drawer to delete | + +**Returns:** `{ success, drawer_id }` + +--- + +## Knowledge Graph Tools + +### `mempalace_kg_query` + +Query entity relationships with time filtering. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `entity` | string | **Yes** | Entity to query (e.g. "Max", "MyProject") | +| `as_of` | string | No | Date filter — only facts valid at this date (YYYY-MM-DD) | +| `direction` | string | No | `outgoing`, `incoming`, or `both` (default: `both`) | + +**Returns:** `{ entity, as_of, facts: [{ direction, subject, predicate, object, valid_from, valid_to, current }], count }` + +--- + +### `mempalace_kg_add` + +Add a fact to the knowledge graph. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `subject` | string | **Yes** | The entity doing/being something | +| `predicate` | string | **Yes** | Relationship type (e.g. "loves", "works_on") | +| `object` | string | **Yes** | The entity being connected to | +| `valid_from` | string | No | When this became true (YYYY-MM-DD) | +| `source_closet` | string | No | Closet ID where this fact appears | + +**Returns:** `{ success, triple_id, fact }` + +--- + +### `mempalace_kg_invalidate` + +Mark a fact as no longer true. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `subject` | string | **Yes** | Entity | +| `predicate` | string | **Yes** | Relationship | +| `object` | string | **Yes** | Connected entity | +| `ended` | string | No | When it stopped being true (default: today) | + +**Returns:** `{ success, fact, ended }` + +--- + +### `mempalace_kg_timeline` + +Chronological timeline of facts. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `entity` | string | No | Entity to get timeline for (omit for full timeline) | + +**Returns:** `{ entity, timeline: [{ subject, predicate, object, valid_from, valid_to, current }], count }` + +--- + +### `mempalace_kg_stats` + +Knowledge graph overview. + +**Parameters:** None + +**Returns:** `{ entities, triples, current_facts, expired_facts, relationship_types }` + +--- + +## Navigation Tools + +### `mempalace_traverse` + +Walk the palace graph from a room. Find connected ideas across wings. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `start_room` | string | **Yes** | Room to start from | +| `max_hops` | integer | No | How many connections to follow (default: 2) | + +**Returns:** `[{ room, wings, halls, count, hop, connected_via }]` + +--- + +### `mempalace_find_tunnels` + +Find rooms that bridge two wings. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `wing_a` | string | No | First wing | +| `wing_b` | string | No | Second wing | + +**Returns:** `[{ room, wings, halls, count, recent }]` + +--- + +### `mempalace_graph_stats` + +Palace graph overview: nodes, tunnels, edges, connectivity. + +**Parameters:** None + +**Returns:** `{ total_rooms, tunnel_rooms, total_edges, rooms_per_wing, top_tunnels }` + +--- + +## Agent Diary Tools + +### `mempalace_diary_write` + +Write to your personal agent diary. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `agent_name` | string | **Yes** | Your name — each agent gets its own wing | +| `entry` | string | **Yes** | Diary entry (in AAAK format recommended) | +| `topic` | string | No | Topic tag (default: "general") | + +**Returns:** `{ success, entry_id, agent, topic, timestamp }` + +--- + +### `mempalace_diary_read` + +Read recent diary entries. + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `agent_name` | string | **Yes** | Your name | +| `last_n` | integer | No | Number of recent entries (default: 10) | + +**Returns:** `{ agent, entries: [{ date, timestamp, topic, content }], total, showing }` diff --git a/website/reference/modules.md b/website/reference/modules.md new file mode 100644 index 0000000..2de7816 --- /dev/null +++ b/website/reference/modules.md @@ -0,0 +1,129 @@ +# Module Map + +Complete source file reference for the MemPalace codebase. + +## Project Structure + +``` +mempalace/ +├── README.md ← project documentation +├── mempalace/ ← core package +│ ├── cli.py ← CLI entry point +│ ├── mcp_server.py ← MCP server (19 tools) +│ ├── knowledge_graph.py ← temporal entity graph +│ ├── palace_graph.py ← room navigation graph +│ ├── dialect.py ← AAAK compression +│ ├── miner.py ← project file ingest +│ ├── convo_miner.py ← conversation ingest +│ ├── searcher.py ← semantic search +│ ├── layers.py ← 4-layer memory stack +│ ├── onboarding.py ← guided setup +│ ├── config.py ← configuration loading +│ ├── normalize.py ← chat format converter +│ ├── entity_detector.py ← auto-detect people/projects +│ ├── entity_registry.py ← entity code registry +│ ├── room_detector_local.py ← room detection from directories +│ ├── general_extractor.py ← 5-type memory extraction +│ ├── split_mega_files.py ← transcript splitting +│ ├── spellcheck.py ← optional spell checking +│ ├── hooks_cli.py ← hook logic +│ ├── instructions_cli.py ← skill instructions +│ └── version.py ← version string +├── benchmarks/ ← reproducible benchmark runners +│ ├── BENCHMARKS.md ← full results + methodology +│ ├── longmemeval_bench.py ← LongMemEval runner +│ ├── locomo_bench.py ← LoCoMo runner +│ ├── membench_bench.py ← MemBench runner +│ └── convomem_bench.py ← ConvoMem runner +├── hooks/ ← Claude Code auto-save hooks +│ ├── mempal_save_hook.sh ← save every N messages +│ └── mempal_precompact_hook.sh ← emergency save +├── examples/ ← usage examples +│ ├── basic_mining.py +│ ├── convo_import.py +│ ├── mcp_setup.md +│ └── gemini_cli_setup.md +├── tests/ ← test suite +├── assets/ ← logo + brand +└── pyproject.toml ← package config +``` + +## Core Modules + +### `cli.py` — CLI Entry Point + +Argparse-based CLI with subcommands: `init`, `mine`, `split`, `search`, `compress`, `wake-up`, `repair`, `status`, `hook`, `instructions`. Dispatches to the corresponding module. + +### `mcp_server.py` — MCP Server + +JSON-RPC over stdin/stdout. Implements the MCP protocol with 19 tools covering palace read/write, knowledge graph, navigation, and agent diary operations. Includes the Memory Protocol and AAAK Spec in status responses. + +### `searcher.py` — Semantic Search + +Two functions: `search()` for CLI output and `search_memories()` for programmatic use. Both query ChromaDB with optional wing/room filters and return verbatim drawer content with similarity scores. + +### `layers.py` — Memory Stack + +Four classes (`Layer0` through `Layer3`) and the unified `MemoryStack`. Layer 0 reads identity, Layer 1 auto-generates from top drawers, Layer 2 does filtered retrieval, Layer 3 does semantic search. + +### `knowledge_graph.py` — Temporal KG + +SQLite-backed entity-relationship graph with temporal validity windows. Supports add, invalidate, query, timeline, and stats. Auto-creates entities on triple insertion. + +### `palace_graph.py` — Navigation Graph + +Builds a graph from ChromaDB metadata where nodes = rooms and edges = tunnels (rooms spanning multiple wings). Supports BFS traversal and tunnel finding. + +### `dialect.py` — AAAK Compression + +Lossy abbreviation system with entity encoding, emotion detection, topic extraction, and flag identification. Works on both plain text and structured zettel data. + +## Ingest Modules + +### `miner.py` — Project Ingest + +Scans project directories for code and doc files. Respects `.gitignore`. Files content as drawers tagged with wing/room metadata. + +### `convo_miner.py` — Conversation Ingest + +Imports conversation exports (Claude, ChatGPT, Slack, Markdown, plaintext). Chunks by exchange pair. Supports `exchange` and `general` extraction modes. + +### `normalize.py` — Format Converter + +Converts 5 chat formats to a standard transcript format before mining. + +### `general_extractor.py` — Memory Type Extraction + +Classifies conversation content into decisions, preferences, milestones, problems, and emotional context. + +## Detection Modules + +### `entity_detector.py` — Entity Detection + +Scans file content to auto-detect people and projects using regex patterns and heuristics. + +### `entity_registry.py` — Entity Registry + +Manages entity name → code mappings for AAAK dialect. + +### `room_detector_local.py` — Room Detection + +Detects rooms from folder structure during `mempalace init`. + +## Utility Modules + +### `config.py` — Configuration + +Loads settings from `~/.mempalace/config.json` and environment variables. + +### `split_mega_files.py` — Transcript Splitting + +Splits concatenated transcripts into per-session files based on session boundary detection. + +### `onboarding.py` — Guided Setup + +Interactive setup wizard for `mempalace init`. Generates AAAK bootstrap and wing config. + +### `spellcheck.py` — Spell Checking + +Optional spell checking utility (requires `autocorrect` package). diff --git a/website/reference/python-api.md b/website/reference/python-api.md new file mode 100644 index 0000000..472acd9 --- /dev/null +++ b/website/reference/python-api.md @@ -0,0 +1,121 @@ +# Python API + +High-level overview of the key Python interfaces you'd use to integrate MemPalace into your application. + +## Search + +The primary way to query the palace programmatically. + +```python +from mempalace.searcher import search_memories + +results = search_memories( + query="why did we switch to GraphQL", + wing="myapp", # optional filter + room="architecture", # optional filter + n_results=5, +) + +# Results structure: +# { +# "query": "...", +# "filters": {"wing": "myapp", "room": "architecture"}, +# "results": [ +# {"text": "...", "wing": "...", "room": "...", "source_file": "...", "similarity": 0.89} +# ] +# } +``` + +## Memory Stack + +The 4-layer memory system with a unified interface. + +```python +from mempalace.layers import MemoryStack + +stack = MemoryStack() # uses default paths from MempalaceConfig + +# Wake-up: L0 (identity) + L1 (essential story) +context = stack.wake_up(wing="myapp") # ~170-900 tokens + +# On-demand: L2 retrieval +recall = stack.recall(wing="myapp", room="auth", n_results=10) + +# Deep search: L3 semantic search +results = stack.search("pricing change", wing="myapp") + +# Status +status = stack.status() +``` + +## Knowledge Graph + +Temporal entity-relationship graph built on SQLite. + +```python +from mempalace.knowledge_graph import KnowledgeGraph + +kg = KnowledgeGraph() # uses default path: ~/.mempalace/knowledge_graph.sqlite3 + +# Write +kg.add_entity("Kai", entity_type="person") +kg.add_triple("Kai", "works_on", "Orion", valid_from="2025-06-01") +kg.invalidate("Kai", "works_on", "Orion", ended="2026-03-01") + +# Read +facts = kg.query_entity("Kai", as_of="2026-01-15", direction="both") +relationships = kg.query_relationship("works_on") +timeline = kg.timeline("Orion") +stats = kg.stats() +``` + +## Palace Graph + +Room-based navigation graph built from ChromaDB metadata. + +```python +from mempalace.palace_graph import build_graph, traverse, find_tunnels, graph_stats + +# Build the graph +nodes, edges = build_graph() + +# Navigate +path = traverse("auth-migration", max_hops=2) +tunnels = find_tunnels(wing_a="wing_code", wing_b="wing_team") +stats = graph_stats() +``` + +## AAAK Dialect + +Lossy compression for token density at scale. + +```python +from mempalace.dialect import Dialect + +# Basic +dialect = Dialect() +text = "We decided to use GraphQL because REST was too chatty for our dashboard." +compressed = dialect.compress(text) + +# With entity mappings +dialect = Dialect(entities={"Alice": "ALC", "Bob": "BOB"}) +compressed = dialect.compress(text, metadata={"wing": "myapp"}) + +# From config +dialect = Dialect.from_config("entities.json") + +# Stats +stats = dialect.compression_stats(text, compressed) +``` + +## Configuration + +```python +from mempalace.config import MempalaceConfig + +config = MempalaceConfig() +print(config.palace_path) # ~/.mempalace/palace +print(config.collection_name) # mempalace_drawers +``` + +For detailed parameter documentation, see [API Reference](/reference/api-reference).