Full Code of thedotmack/claude-mem for AI

main d06882126fe2 cached
589 files
67.4 MB
1.8M tokens
6898 symbols
2 requests
Download .txt
Showing preview only (7,481K chars total). Download the full file or copy to clipboard to get everything.
Repository: thedotmack/claude-mem
Branch: main
Commit: d06882126fe2
Files: 589
Total size: 67.4 MB

Directory structure:
gitextract_sw8zeb60/

├── .claude/
│   ├── commands/
│   │   └── anti-pattern-czar.md
│   ├── reports/
│   │   └── test-audit-2026-01-05.md
│   └── settings.json
├── .claude-plugin/
│   ├── CLAUDE.md
│   ├── marketplace.json
│   └── plugin.json
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows/
│       ├── claude-code-review.yml
│       ├── claude.yml
│       ├── convert-feature-requests.yml
│       ├── deploy-install-scripts.yml
│       ├── npm-publish.yml
│       └── summary.yml
├── .gitignore
├── .markdownlint.json
├── .plan/
│   └── npx-distribution.md
├── .translation-cache.json
├── CHANGELOG.md
├── CLAUDE.md
├── LICENSE
├── README.md
├── conductor.json
├── cursor-hooks/
│   ├── .gitignore
│   ├── CONTEXT-INJECTION.md
│   ├── INTEGRATION.md
│   ├── PARITY.md
│   ├── QUICKSTART.md
│   ├── README.md
│   ├── REVIEW.md
│   ├── STANDALONE-SETUP.md
│   ├── cursorrules-template.md
│   └── hooks.json
├── docs/
│   ├── CLAUDE.md
│   ├── PR-SHIPPING-REPORT.md
│   ├── SESSION_ID_ARCHITECTURE.md
│   ├── VERSION_FIX.md
│   ├── anti-pattern-cleanup-plan.md
│   ├── bug-fixes/
│   │   └── windows-spaces-issue.md
│   ├── context/
│   │   ├── agent-sdk-v2-examples.ts
│   │   ├── agent-sdk-v2-preview.md
│   │   ├── cursor-hooks-reference.md
│   │   └── hooks-reference-2026-01-07.md
│   ├── i18n/
│   │   ├── .translation-cache.json
│   │   ├── README.ar.md
│   │   ├── README.bn.md
│   │   ├── README.cs.md
│   │   ├── README.da.md
│   │   ├── README.de.md
│   │   ├── README.el.md
│   │   ├── README.es.md
│   │   ├── README.fi.md
│   │   ├── README.fr.md
│   │   ├── README.he.md
│   │   ├── README.hi.md
│   │   ├── README.hu.md
│   │   ├── README.id.md
│   │   ├── README.it.md
│   │   ├── README.ja.md
│   │   ├── README.ko.md
│   │   ├── README.nl.md
│   │   ├── README.no.md
│   │   ├── README.pl.md
│   │   ├── README.pt-br.md
│   │   ├── README.ro.md
│   │   ├── README.ru.md
│   │   ├── README.sv.md
│   │   ├── README.th.md
│   │   ├── README.tl.md
│   │   ├── README.tr.md
│   │   ├── README.uk.md
│   │   ├── README.ur.md
│   │   ├── README.vi.md
│   │   ├── README.zh-tw.md
│   │   ├── README.zh.md
│   │   └── pt.md
│   ├── public/
│   │   ├── CLAUDE.md
│   │   ├── architecture/
│   │   │   ├── database.mdx
│   │   │   ├── hooks.mdx
│   │   │   ├── overview.mdx
│   │   │   ├── pm2-to-bun-migration.mdx
│   │   │   ├── search-architecture.mdx
│   │   │   └── worker-service.mdx
│   │   ├── architecture-evolution.mdx
│   │   ├── beta-features.mdx
│   │   ├── configuration.mdx
│   │   ├── context-engineering.mdx
│   │   ├── cursor/
│   │   │   ├── gemini-setup.mdx
│   │   │   ├── index.mdx
│   │   │   └── openrouter-setup.mdx
│   │   ├── development.mdx
│   │   ├── docs.json
│   │   ├── endless-mode.mdx
│   │   ├── hooks-architecture.mdx
│   │   ├── installation.mdx
│   │   ├── introduction.mdx
│   │   ├── modes.mdx
│   │   ├── openclaw-integration.mdx
│   │   ├── platform-integration.mdx
│   │   ├── progressive-disclosure.mdx
│   │   ├── smart-explore-benchmark.mdx
│   │   ├── troubleshooting.mdx
│   │   └── usage/
│   │       ├── claude-desktop.mdx
│   │       ├── export-import.mdx
│   │       ├── folder-context.mdx
│   │       ├── gemini-provider.mdx
│   │       ├── getting-started.mdx
│   │       ├── manual-recovery.mdx
│   │       ├── openrouter-provider.mdx
│   │       ├── private-tags.mdx
│   │       └── search-tools.mdx
│   └── reports/
│       ├── 2026-01-02--generator-failure-investigation.md
│       ├── 2026-01-02--observation-duplication-regression.md
│       ├── 2026-01-02--stuck-observations.md
│       ├── 2026-01-03--observation-saving-failure.md
│       ├── 2026-01-04--gemini-agent-failures.md
│       ├── 2026-01-04--issue-511-gemini-model-missing.md
│       ├── 2026-01-04--issue-514-orphaned-sessions-analysis.md
│       ├── 2026-01-04--issue-517-windows-powershell-analysis.md
│       ├── 2026-01-04--issue-520-stuck-messages-analysis.md
│       ├── 2026-01-04--issue-527-uv-homebrew-analysis.md
│       ├── 2026-01-04--issue-531-export-type-duplication.md
│       ├── 2026-01-04--issue-532-memory-leak-analysis.md
│       ├── 2026-01-04--logger-coverage-failures.md
│       ├── 2026-01-04--logging-analysis-and-recommendations.md
│       ├── 2026-01-04--session-id-refactor-failures.md
│       ├── 2026-01-04--session-id-validation-failures.md
│       ├── 2026-01-04--session-store-failures.md
│       ├── 2026-01-04--test-suite-report.md
│       ├── 2026-01-05--PR-556-brainstorming-claude-md-distribution.md
│       ├── 2026-01-05--context-hook-investigation.md
│       ├── 2026-01-05--issue-543-slash-command-unavailable.md
│       ├── 2026-01-05--issue-544-mem-search-hint-claude-code.md
│       ├── 2026-01-05--issue-545-formattool-json-parse-crash.md
│       ├── 2026-01-05--issue-555-windows-hooks-ipc-false.md
│       ├── 2026-01-05--issue-557-settings-module-loader-error.md
│       ├── 2026-01-06--windows-woes-comprehensive-report.md
│       ├── 2026-01-07--all-open-issues-explained.md
│       ├── 2026-01-07--open-issues-summary.md
│       ├── 2026-01-10--anti-pattern-czar-generalization-analysis.md
│       ├── intentional-patterns-validation.md
│       ├── issue-586-feature-request-unknown.md
│       ├── issue-587-observations-not-stored.md
│       ├── issue-588-api-key-usage-warning.md
│       ├── issue-590-windows-chroma-terminal-popup.md
│       ├── issue-591-openrouter-memorysessionid-capture.md
│       ├── issue-596-processtransport-not-ready.md
│       ├── issue-597-too-many-bugs.md
│       ├── issue-598-conversation-history-pollution.md
│       ├── issue-599-windows-drive-root-400-error.md
│       ├── issue-600-documentation-audit-features-not-implemented.md
│       ├── issue-602-posttooluse-worker-service-failed.md
│       ├── issue-603-worker-daemon-leaks-child-processes.md
│       ├── log-level-audit.txt
│       └── nonsense-logic.md
├── install/
│   ├── .gitignore
│   ├── public/
│   │   ├── install.sh
│   │   └── installer.js
│   └── vercel.json
├── installer/
│   ├── build.mjs
│   ├── dist/
│   │   └── index.js
│   ├── package.json
│   ├── src/
│   │   ├── index.ts
│   │   ├── steps/
│   │   │   ├── complete.ts
│   │   │   ├── dependencies.ts
│   │   │   ├── ide-selection.ts
│   │   │   ├── install.ts
│   │   │   ├── provider.ts
│   │   │   ├── settings.ts
│   │   │   ├── welcome.ts
│   │   │   └── worker.ts
│   │   └── utils/
│   │       ├── dependencies.ts
│   │       ├── settings-writer.ts
│   │       └── system.ts
│   └── tsconfig.json
├── openclaw/
│   ├── .gitignore
│   ├── Dockerfile.e2e
│   ├── SKILL.md
│   ├── TESTING.md
│   ├── e2e-verify.sh
│   ├── install.sh
│   ├── openclaw.plugin.json
│   ├── package.json
│   ├── src/
│   │   ├── index.test.ts
│   │   └── index.ts
│   ├── test-e2e.sh
│   ├── test-install.sh
│   ├── test-sse-consumer.js
│   └── tsconfig.json
├── package.json
├── plugin/
│   ├── .claude-plugin/
│   │   ├── CLAUDE.md
│   │   └── plugin.json
│   ├── CLAUDE.md
│   ├── hooks/
│   │   ├── CLAUDE.md
│   │   ├── bugfixes-2026-01-10.md
│   │   └── hooks.json
│   ├── modes/
│   │   ├── code--ar.json
│   │   ├── code--bn.json
│   │   ├── code--chill.json
│   │   ├── code--cs.json
│   │   ├── code--da.json
│   │   ├── code--de.json
│   │   ├── code--el.json
│   │   ├── code--es.json
│   │   ├── code--fi.json
│   │   ├── code--fr.json
│   │   ├── code--he.json
│   │   ├── code--hi.json
│   │   ├── code--hu.json
│   │   ├── code--id.json
│   │   ├── code--it.json
│   │   ├── code--ja.json
│   │   ├── code--ko.json
│   │   ├── code--nl.json
│   │   ├── code--no.json
│   │   ├── code--pl.json
│   │   ├── code--pt-br.json
│   │   ├── code--ro.json
│   │   ├── code--ru.json
│   │   ├── code--sv.json
│   │   ├── code--th.json
│   │   ├── code--tr.json
│   │   ├── code--uk.json
│   │   ├── code--ur.json
│   │   ├── code--vi.json
│   │   ├── code--zh.json
│   │   ├── code.json
│   │   ├── email-investigation.json
│   │   ├── law-study--chill.json
│   │   ├── law-study-CLAUDE.md
│   │   └── law-study.json
│   ├── package.json
│   ├── scripts/
│   │   ├── CLAUDE.md
│   │   ├── bun-runner.js
│   │   ├── claude-mem
│   │   ├── context-generator.cjs
│   │   ├── mcp-server.cjs
│   │   ├── smart-install.js
│   │   ├── statusline-counts.js
│   │   ├── worker-cli.js
│   │   ├── worker-service.cjs
│   │   └── worker-wrapper.cjs
│   ├── skills/
│   │   ├── do/
│   │   │   └── SKILL.md
│   │   ├── make-plan/
│   │   │   └── SKILL.md
│   │   ├── mem-search/
│   │   │   └── SKILL.md
│   │   ├── smart-explore/
│   │   │   └── SKILL.md
│   │   └── timeline-report/
│   │       └── SKILL.md
│   └── ui/
│       ├── CLAUDE.md
│       ├── viewer-bundle.js
│       └── viewer.html
├── ragtime/
│   ├── CLAUDE.md
│   ├── LICENSE
│   ├── README.md
│   └── ragtime.ts
├── scripts/
│   ├── CLAUDE.md
│   ├── analyze-transformations-smart.js
│   ├── anti-pattern-test/
│   │   ├── CLAUDE.md
│   │   └── detect-error-handling-antipatterns.ts
│   ├── bug-report/
│   │   ├── cli.ts
│   │   ├── collector.ts
│   │   └── index.ts
│   ├── build-hooks.js
│   ├── build-viewer.js
│   ├── build-worker-binary.js
│   ├── check-pending-queue.ts
│   ├── cleanup-duplicates.ts
│   ├── clear-failed-queue.ts
│   ├── debug-transcript-structure.ts
│   ├── discord-release-notify.js
│   ├── dump-transcript-readable.ts
│   ├── endless-mode-token-calculator.js
│   ├── export-memories.ts
│   ├── extract-prompts-to-yaml.cjs
│   ├── extract-rich-context-examples.ts
│   ├── extraction/
│   │   ├── README.md
│   │   ├── extract-all-xml.py
│   │   └── filter-actual-xml.py
│   ├── find-silent-failures.sh
│   ├── fix-all-timestamps.ts
│   ├── fix-corrupted-timestamps.ts
│   ├── format-transcript-context.ts
│   ├── generate-changelog.js
│   ├── import-memories.ts
│   ├── investigate-timestamps.ts
│   ├── publish.js
│   ├── regenerate-claude-md.ts
│   ├── smart-install.js
│   ├── sync-marketplace.cjs
│   ├── sync-to-marketplace.sh
│   ├── test-transcript-parser.ts
│   ├── transcript-to-markdown.ts
│   ├── translate-readme/
│   │   ├── README.md
│   │   ├── cli.ts
│   │   ├── examples.ts
│   │   └── index.ts
│   ├── types/
│   │   └── export.ts
│   ├── validate-timestamp-logic.ts
│   ├── verify-timestamp-fix.ts
│   └── wipe-chroma.cjs
├── src/
│   ├── CLAUDE.md
│   ├── bin/
│   │   ├── cleanup-duplicates.ts
│   │   └── import-xml-observations.ts
│   ├── cli/
│   │   ├── CLAUDE.md
│   │   ├── adapters/
│   │   │   ├── CLAUDE.md
│   │   │   ├── claude-code.ts
│   │   │   ├── cursor.ts
│   │   │   ├── gemini-cli.ts
│   │   │   ├── index.ts
│   │   │   └── raw.ts
│   │   ├── claude-md-commands.ts
│   │   ├── handlers/
│   │   │   ├── CLAUDE.md
│   │   │   ├── context.ts
│   │   │   ├── file-edit.ts
│   │   │   ├── index.ts
│   │   │   ├── observation.ts
│   │   │   ├── session-complete.ts
│   │   │   ├── session-init.ts
│   │   │   ├── summarize.ts
│   │   │   └── user-message.ts
│   │   ├── hook-command.ts
│   │   ├── stdin-reader.ts
│   │   └── types.ts
│   ├── hooks/
│   │   └── hook-response.ts
│   ├── sdk/
│   │   ├── index.ts
│   │   ├── parser.ts
│   │   └── prompts.ts
│   ├── servers/
│   │   └── mcp-server.ts
│   ├── services/
│   │   ├── CLAUDE.md
│   │   ├── Context.ts
│   │   ├── context/
│   │   │   ├── ContextBuilder.ts
│   │   │   ├── ContextConfigLoader.ts
│   │   │   ├── ObservationCompiler.ts
│   │   │   ├── TokenCalculator.ts
│   │   │   ├── formatters/
│   │   │   │   ├── ColorFormatter.ts
│   │   │   │   └── MarkdownFormatter.ts
│   │   │   ├── index.ts
│   │   │   ├── sections/
│   │   │   │   ├── FooterRenderer.ts
│   │   │   │   ├── HeaderRenderer.ts
│   │   │   │   ├── SummaryRenderer.ts
│   │   │   │   └── TimelineRenderer.ts
│   │   │   └── types.ts
│   │   ├── context-generator.ts
│   │   ├── domain/
│   │   │   ├── CLAUDE.md
│   │   │   ├── ModeManager.ts
│   │   │   └── types.ts
│   │   ├── infrastructure/
│   │   │   ├── CLAUDE.md
│   │   │   ├── GracefulShutdown.ts
│   │   │   ├── HealthMonitor.ts
│   │   │   ├── ProcessManager.ts
│   │   │   └── index.ts
│   │   ├── integrations/
│   │   │   ├── CursorHooksInstaller.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── queue/
│   │   │   └── SessionQueueProcessor.ts
│   │   ├── server/
│   │   │   ├── ErrorHandler.ts
│   │   │   ├── Middleware.ts
│   │   │   ├── Server.ts
│   │   │   ├── allowed-constants.ts
│   │   │   └── index.ts
│   │   ├── smart-file-read/
│   │   │   ├── parser.ts
│   │   │   └── search.ts
│   │   ├── sqlite/
│   │   │   ├── CLAUDE.md
│   │   │   ├── Database.ts
│   │   │   ├── Import.ts
│   │   │   ├── Observations.ts
│   │   │   ├── PendingMessageStore.ts
│   │   │   ├── Prompts.ts
│   │   │   ├── SessionSearch.ts
│   │   │   ├── SessionStore.ts
│   │   │   ├── Sessions.ts
│   │   │   ├── Summaries.ts
│   │   │   ├── Timeline.ts
│   │   │   ├── import/
│   │   │   │   └── bulk.ts
│   │   │   ├── index.ts
│   │   │   ├── migrations/
│   │   │   │   └── runner.ts
│   │   │   ├── migrations.ts
│   │   │   ├── observations/
│   │   │   │   ├── files.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── recent.ts
│   │   │   │   ├── store.ts
│   │   │   │   └── types.ts
│   │   │   ├── prompts/
│   │   │   │   ├── get.ts
│   │   │   │   ├── store.ts
│   │   │   │   └── types.ts
│   │   │   ├── sessions/
│   │   │   │   ├── create.ts
│   │   │   │   ├── get.ts
│   │   │   │   └── types.ts
│   │   │   ├── summaries/
│   │   │   │   ├── get.ts
│   │   │   │   ├── recent.ts
│   │   │   │   ├── store.ts
│   │   │   │   └── types.ts
│   │   │   ├── timeline/
│   │   │   │   └── queries.ts
│   │   │   ├── transactions.ts
│   │   │   └── types.ts
│   │   ├── sync/
│   │   │   ├── ChromaMcpManager.ts
│   │   │   └── ChromaSync.ts
│   │   ├── transcripts/
│   │   │   ├── cli.ts
│   │   │   ├── config.ts
│   │   │   ├── field-utils.ts
│   │   │   ├── processor.ts
│   │   │   ├── state.ts
│   │   │   ├── types.ts
│   │   │   └── watcher.ts
│   │   ├── worker/
│   │   │   ├── BranchManager.ts
│   │   │   ├── CLAUDE.md
│   │   │   ├── DatabaseManager.ts
│   │   │   ├── FormattingService.ts
│   │   │   ├── GeminiAgent.ts
│   │   │   ├── OpenRouterAgent.ts
│   │   │   ├── PaginationHelper.ts
│   │   │   ├── ProcessRegistry.ts
│   │   │   ├── README.md
│   │   │   ├── SDKAgent.ts
│   │   │   ├── SSEBroadcaster.ts
│   │   │   ├── Search.ts
│   │   │   ├── SearchManager.ts
│   │   │   ├── SessionManager.ts
│   │   │   ├── SettingsManager.ts
│   │   │   ├── TimelineService.ts
│   │   │   ├── agents/
│   │   │   │   ├── FallbackErrorHandler.ts
│   │   │   │   ├── ObservationBroadcaster.ts
│   │   │   │   ├── ResponseProcessor.ts
│   │   │   │   ├── SessionCleanupHelper.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── events/
│   │   │   │   └── SessionEventBroadcaster.ts
│   │   │   ├── http/
│   │   │   │   ├── BaseRouteHandler.ts
│   │   │   │   ├── middleware.ts
│   │   │   │   └── routes/
│   │   │   │       ├── DataRoutes.ts
│   │   │   │       ├── LogsRoutes.ts
│   │   │   │       ├── MemoryRoutes.ts
│   │   │   │       ├── SearchRoutes.ts
│   │   │   │       ├── SessionRoutes.ts
│   │   │   │       ├── SettingsRoutes.ts
│   │   │   │       └── ViewerRoutes.ts
│   │   │   ├── search/
│   │   │   │   ├── ResultFormatter.ts
│   │   │   │   ├── SearchOrchestrator.ts
│   │   │   │   ├── TimelineBuilder.ts
│   │   │   │   ├── filters/
│   │   │   │   │   ├── DateFilter.ts
│   │   │   │   │   ├── ProjectFilter.ts
│   │   │   │   │   └── TypeFilter.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── strategies/
│   │   │   │   │   ├── ChromaSearchStrategy.ts
│   │   │   │   │   ├── HybridSearchStrategy.ts
│   │   │   │   │   ├── SQLiteSearchStrategy.ts
│   │   │   │   │   └── SearchStrategy.ts
│   │   │   │   └── types.ts
│   │   │   ├── session/
│   │   │   │   └── SessionCompletionHandler.ts
│   │   │   └── validation/
│   │   │       └── PrivacyCheckValidator.ts
│   │   ├── worker-service.ts
│   │   └── worker-types.ts
│   ├── shared/
│   │   ├── CLAUDE.md
│   │   ├── EnvManager.ts
│   │   ├── SettingsDefaultsManager.ts
│   │   ├── hook-constants.ts
│   │   ├── path-utils.ts
│   │   ├── paths.ts
│   │   ├── plugin-state.ts
│   │   ├── timeline-formatting.ts
│   │   ├── transcript-parser.ts
│   │   └── worker-utils.ts
│   ├── supervisor/
│   │   ├── env-sanitizer.ts
│   │   ├── health-checker.ts
│   │   ├── index.ts
│   │   ├── process-registry.ts
│   │   └── shutdown.ts
│   ├── types/
│   │   ├── database.ts
│   │   ├── transcript.ts
│   │   └── tree-kill.d.ts
│   ├── ui/
│   │   ├── viewer/
│   │   │   ├── App.tsx
│   │   │   ├── components/
│   │   │   │   ├── ContextSettingsModal.tsx
│   │   │   │   ├── ErrorBoundary.tsx
│   │   │   │   ├── Feed.tsx
│   │   │   │   ├── GitHubStarsButton.tsx
│   │   │   │   ├── Header.tsx
│   │   │   │   ├── LogsModal.tsx
│   │   │   │   ├── ObservationCard.tsx
│   │   │   │   ├── PromptCard.tsx
│   │   │   │   ├── ScrollToTop.tsx
│   │   │   │   ├── SummaryCard.tsx
│   │   │   │   ├── TerminalPreview.tsx
│   │   │   │   └── ThemeToggle.tsx
│   │   │   ├── constants/
│   │   │   │   ├── CLAUDE.md
│   │   │   │   ├── api.ts
│   │   │   │   ├── settings.ts
│   │   │   │   ├── timing.ts
│   │   │   │   └── ui.ts
│   │   │   ├── hooks/
│   │   │   │   ├── useContextPreview.ts
│   │   │   │   ├── useGitHubStars.ts
│   │   │   │   ├── usePagination.ts
│   │   │   │   ├── useSSE.ts
│   │   │   │   ├── useSettings.ts
│   │   │   │   ├── useSpinningFavicon.ts
│   │   │   │   ├── useStats.ts
│   │   │   │   └── useTheme.ts
│   │   │   ├── index.tsx
│   │   │   ├── types.ts
│   │   │   └── utils/
│   │   │       ├── data.ts
│   │   │       ├── formatNumber.ts
│   │   │       └── formatters.ts
│   │   └── viewer-template.html
│   └── utils/
│       ├── CLAUDE.md
│       ├── agents-md-utils.ts
│       ├── bun-path.ts
│       ├── claude-md-utils.ts
│       ├── cursor-utils.ts
│       ├── error-messages.ts
│       ├── logger.ts
│       ├── project-filter.ts
│       ├── project-name.ts
│       ├── tag-stripping.ts
│       ├── transcript-parser.ts
│       └── worktree.ts
├── tests/
│   ├── CLAUDE.md
│   ├── context/
│   │   ├── formatters/
│   │   │   └── markdown-formatter.test.ts
│   │   ├── observation-compiler.test.ts
│   │   └── token-calculator.test.ts
│   ├── cursor-context-update.test.ts
│   ├── cursor-hooks-json-utils.test.ts
│   ├── cursor-mcp-config.test.ts
│   ├── cursor-registry.test.ts
│   ├── fk-constraint-fix.test.ts
│   ├── gemini_agent.test.ts
│   ├── hook-command.test.ts
│   ├── hook-constants.test.ts
│   ├── hook-lifecycle.test.ts
│   ├── hooks/
│   │   └── context-reinjection-guard.test.ts
│   ├── infrastructure/
│   │   ├── CLAUDE.md
│   │   ├── graceful-shutdown.test.ts
│   │   ├── health-monitor.test.ts
│   │   ├── plugin-disabled-check.test.ts
│   │   ├── plugin-distribution.test.ts
│   │   ├── process-manager.test.ts
│   │   ├── version-consistency.test.ts
│   │   ├── wmic-parsing.test.ts
│   │   └── worker-json-status.test.ts
│   ├── integration/
│   │   ├── chroma-vector-sync.test.ts
│   │   ├── hook-execution-e2e.test.ts
│   │   └── worker-api-endpoints.test.ts
│   ├── log-level-audit.test.ts
│   ├── logger-usage-standards.test.ts
│   ├── sdk-agent-resume.test.ts
│   ├── server/
│   │   ├── error-handler.test.ts
│   │   └── server.test.ts
│   ├── services/
│   │   ├── logs-routes-tail-read.test.ts
│   │   ├── queue/
│   │   │   └── SessionQueueProcessor.test.ts
│   │   ├── sqlite/
│   │   │   ├── PendingMessageStore.test.ts
│   │   │   ├── migration-runner.test.ts
│   │   │   ├── schema-repair.test.ts
│   │   │   └── session-search-path-matching.test.ts
│   │   ├── stale-abort-controller-guard.test.ts
│   │   └── sync/
│   │       └── chroma-mcp-manager-ssl.test.ts
│   ├── session_id_usage_validation.test.ts
│   ├── session_store.test.ts
│   ├── shared/
│   │   ├── settings-defaults-manager.test.ts
│   │   └── timeline-formatting.test.ts
│   ├── smart-install.test.ts
│   ├── sqlite/
│   │   ├── data-integrity.test.ts
│   │   ├── observations.test.ts
│   │   ├── prompts.test.ts
│   │   ├── sessions.test.ts
│   │   ├── summaries.test.ts
│   │   └── transactions.test.ts
│   ├── supervisor/
│   │   ├── env-sanitizer.test.ts
│   │   ├── health-checker.test.ts
│   │   ├── index.test.ts
│   │   ├── process-registry.test.ts
│   │   └── shutdown.test.ts
│   ├── utils/
│   │   ├── CLAUDE.md
│   │   ├── claude-md-utils.test.ts
│   │   ├── logger-format-tool.test.ts
│   │   ├── project-filter.test.ts
│   │   └── tag-stripping.test.ts
│   ├── worker/
│   │   ├── agents/
│   │   │   ├── fallback-error-handler.test.ts
│   │   │   ├── response-processor.test.ts
│   │   │   └── session-cleanup-helper.test.ts
│   │   ├── http/
│   │   │   └── routes/
│   │   │       └── data-routes-coercion.test.ts
│   │   ├── middleware/
│   │   │   └── cors-restriction.test.ts
│   │   ├── process-registry.test.ts
│   │   └── search/
│   │       ├── result-formatter.test.ts
│   │       ├── search-orchestrator.test.ts
│   │       └── strategies/
│   │           ├── chroma-search-strategy.test.ts
│   │           ├── hybrid-search-strategy.test.ts
│   │           └── sqlite-search-strategy.test.ts
│   ├── worker-spawn.test.ts
│   └── zombie-prevention.test.ts
├── transcript-watch.example.json
└── tsconfig.json

================================================
FILE CONTENTS
================================================

================================================
FILE: .claude/commands/anti-pattern-czar.md
================================================
# Anti-Pattern Czar

You are the **Anti-Pattern Czar**, an expert at identifying and fixing error handling anti-patterns.

## Your Mission

Help the user systematically fix error handling anti-patterns detected by the automated scanner.

## Process

1. **Run the detector:**
   ```bash
   bun run scripts/anti-pattern-test/detect-error-handling-antipatterns.ts
   ```

2. **Analyze the results:**
   - Count CRITICAL, HIGH, MEDIUM, and APPROVED_OVERRIDE issues
   - Prioritize CRITICAL issues on critical paths first
   - Group similar patterns together

3. **For each CRITICAL issue:**

   a. **Read the problematic code** using the Read tool

   b. **Explain the problem:**
      - Why is this dangerous?
      - What debugging nightmare could this cause?
      - What specific error is being swallowed?

   c. **Determine the right fix:**
      - **Option 1: Add proper logging** - If this is a real error that should be visible
      - **Option 2: Add [APPROVED OVERRIDE]** - If this is expected/documented behavior
      - **Option 3: Remove the try-catch entirely** - If the error should propagate
      - **Option 4: Add specific error type checking** - If only certain errors should be caught

   d. **Propose the fix** and ask for approval

   e. **Apply the fix** after approval

4. **Work through issues methodically:**
   - Fix one at a time
   - Re-run the detector after each batch of fixes
   - Track progress: "Fixed 3/28 critical issues"

## Guidelines for Approved Overrides

Only approve overrides when ALL of these are true:
- The error is **expected and frequent** (e.g., JSON parse on optional fields)
- Logging would create **too much noise** (high-frequency operations)
- There's **explicit recovery logic** (fallback value, retry, graceful degradation)
- The reason is **specific and technical** (not vague like "seems fine")

## Valid Override Examples:

✅ **GOOD:**
- "Expected JSON parse failures for optional data fields, too frequent to log"
- "Logger can't log its own failures, using stderr as last resort"
- "Health check port scan, expected connection failures on free port detection"
- "Git repo detection, expected failures when not in a git directory"

❌ **BAD:**
- "Error is not important" (why catch it then?)
- "Happens sometimes" (when? why?)
- "Works fine without logging" (works until it doesn't)
- "Optional" (optional errors still need visibility)

## Critical Path Rules

For files in the CRITICAL_PATHS list (SDKAgent.ts, GeminiAgent.ts, OpenRouterAgent.ts, SessionStore.ts, worker-service.ts):

- **NEVER** approve overrides on critical paths without exceptional justification
- Errors on critical paths MUST be visible (logged) or fatal (thrown)
- Catch-and-continue on critical paths is BANNED unless explicitly approved
- If in doubt, make it throw - fail loud, not silent

## Output Format

After each fix:
```
✅ Fixed: src/utils/example.ts:42
   Pattern: NO_LOGGING_IN_CATCH
   Solution: Added logger.error() with context

Progress: 3/28 critical issues remaining
```

After completing a batch:
```
🎯 Batch complete! Re-running detector...
[shows new results]
```

## Important

- **Read the code** before proposing fixes - understand what it's doing
- **Ask the user** if you're uncertain about the right approach
- **Don't blindly add overrides** - challenge each one
- **Prefer logging** over overrides when in doubt
- **Work incrementally** - small batches, frequent validation

## When Complete

Report final statistics:
```
🎉 Anti-pattern cleanup complete!

Before:
  🔴 CRITICAL: 28
  🟠 HIGH: 47
  🟡 MEDIUM: 76

After:
  🔴 CRITICAL: 0
  🟠 HIGH: 47
  🟡 MEDIUM: 76
  ⚪ APPROVED OVERRIDES: 15

All critical anti-patterns resolved!
```

Now, ask the user: "Ready to fix error handling anti-patterns? I'll start with the critical issues."


================================================
FILE: .claude/reports/test-audit-2026-01-05.md
================================================
# Test Quality Audit Report

**Date**: 2026-01-05
**Auditor**: Claude Code (Opus 4.5)
**Methodology**: Deep analysis with focus on anti-pattern prevention, actual functionality testing, and regression prevention

---

## Executive Summary

**Total Test Files Audited**: 41
**Total Test Cases**: ~450+

### Score Distribution

| Score | Category | Count | Percentage |
|-------|----------|-------|------------|
| 5 | Essential | 8 | 19.5% |
| 4 | Valuable | 15 | 36.6% |
| 3 | Marginal | 11 | 26.8% |
| 2 | Weak | 5 | 12.2% |
| 1 | Delete | 2 | 4.9% |

### Key Findings

**Strengths**:
- SQLite database tests are exemplary - real database operations with proper setup/teardown
- Infrastructure tests (WMIC parsing, token calculator) use pure unit testing with no mocks
- Search strategy tests have comprehensive coverage of edge cases
- Logger formatTool tests are thorough and test actual transformation logic

**Critical Issues**:
- **context-builder.test.ts** has incomplete mocks that pollute the module cache, causing 81 test failures when run with the full suite
- Several tests verify mock behavior rather than actual functionality
- Type validation tests (export-types.test.ts) provide minimal value - TypeScript already validates types at compile time
- Some "validation" tests only verify code patterns exist, not that they work

**Recommendations**:
1. Fix or delete context-builder.test.ts - it actively harms the test suite
2. Delete trivial type validation tests that duplicate TypeScript compiler checks
3. Convert heavy-mock tests to integration tests where feasible
4. Add integration tests for critical paths (hook execution, worker API endpoints)

---

## Detailed Scores

### Score 5 - Essential (8 tests)

These tests catch real bugs, use minimal mocking, and test actual behavior.

| File | Test Count | Notes |
|------|------------|-------|
| `tests/sqlite/observations.test.ts` | 25+ | Real SQLite operations, in-memory DB, tests actual data persistence and retrieval |
| `tests/sqlite/sessions.test.ts` | 20+ | Real database CRUD operations, status transitions, relationship integrity |
| `tests/sqlite/transactions.test.ts` | 15+ | Critical transaction isolation tests, rollback behavior, error handling |
| `tests/context/token-calculator.test.ts` | 35+ | Pure unit tests, no mocks, tests actual token estimation algorithms |
| `tests/infrastructure/wmic-parsing.test.ts` | 20+ | Pure parsing logic tests, validates Windows process enumeration edge cases |
| `tests/utils/logger-format-tool.test.ts` | 56 | Comprehensive formatTool tests, validates JSON parsing, tool output formatting |
| `tests/server/server.test.ts` | 15+ | Real HTTP server integration tests, actual endpoint validation |
| `tests/cursor-hook-outputs.test.ts` | 12+ | Integration tests running actual hook scripts, validates real output |

**Why Essential**: These tests catch actual bugs before production. They test real behavior with minimal abstraction. The SQLite tests in particular are exemplary - they use an in-memory database but perform real SQL operations.

---

### Score 4 - Valuable (15 tests)

Good tests with acceptable mocking that still verify meaningful behavior.

| File | Test Count | Notes |
|------|------------|-------|
| `tests/sqlite/prompts.test.ts` | 15+ | Real DB operations for user prompts, timestamp handling |
| `tests/sqlite/summaries.test.ts` | 15+ | Real DB operations for session summaries |
| `tests/worker/search/search-orchestrator.test.ts` | 30+ | Comprehensive strategy selection logic, good edge case coverage |
| `tests/worker/search/strategies/sqlite-search-strategy.test.ts` | 25+ | Filter logic tests, date range handling |
| `tests/worker/search/strategies/hybrid-search-strategy.test.ts` | 20+ | Ranking preservation, merge logic |
| `tests/worker/search/strategies/chroma-search-strategy.test.ts` | 20+ | Vector search behavior, doc_type filtering |
| `tests/worker/search/result-formatter.test.ts` | 15+ | Output formatting validation |
| `tests/gemini_agent.test.ts` | 20+ | Multi-turn conversation flow, rate limiting fallback |
| `tests/infrastructure/health-monitor.test.ts` | 15+ | Health check logic, threshold validation |
| `tests/infrastructure/graceful-shutdown.test.ts` | 15+ | Shutdown sequence, timeout handling |
| `tests/infrastructure/process-manager.test.ts` | 12+ | Process lifecycle management |
| `tests/cursor-mcp-config.test.ts` | 10+ | MCP configuration generation validation |
| `tests/cursor-hooks-json-utils.test.ts` | 8+ | JSON parsing utilities |
| `tests/shared/settings-defaults-manager.test.ts` | 27 | Settings validation, migration logic |
| `tests/context/formatters/markdown-formatter.test.ts` | 15+ | Markdown generation, terminology consistency |

**Why Valuable**: These tests have some mocking but still verify important business logic. The search strategy tests are particularly good at testing the decision-making logic for query routing.

---

### Score 3 - Marginal (11 tests)

Tests with moderate value, often too much mocking or testing obvious behavior.

| File | Test Count | Issues |
|------|------------|--------|
| `tests/worker/agents/observation-broadcaster.test.ts` | 15+ | Heavy mocking of SSE workers, tests mock behavior more than actual broadcasting |
| `tests/worker/agents/fallback-error-handler.test.ts` | 10+ | Error message formatting tests, low complexity |
| `tests/worker/agents/session-cleanup-helper.test.ts` | 10+ | Cleanup logic with mocked dependencies |
| `tests/context/observation-compiler.test.ts` | 20+ | Mock database, tests query building not actual compilation |
| `tests/server/error-handler.test.ts` | 8+ | Mock Express response, tests formatting only |
| `tests/cursor-registry.test.ts` | 8+ | Registry pattern tests, low risk area |
| `tests/cursor-context-update.test.ts` | 5+ | File format validation, could be stricter |
| `tests/hook-constants.test.ts` | 5+ | Constant validation, low value |
| `tests/session_store.test.ts` | 10+ | In-memory store tests, straightforward logic |
| `tests/logger-coverage.test.ts` | 8+ | Coverage verification, not functionality |
| `tests/scripts/smart-install.test.ts` | 25+ | Path array tests, replicates rather than imports logic |

**Why Marginal**: These tests provide some regression protection but either mock too heavily or test low-risk areas. The smart-install tests notably replicate the path arrays from the source file rather than testing the actual module.

---

### Score 2 - Weak (5 tests)

Tests that mostly verify mocks work or provide little value.

| File | Test Count | Issues |
|------|------------|--------|
| `tests/worker/agents/response-processor.test.ts` | 20+ | **Heavy mocking**: >50% setup is mock configuration. Tests verify mocks are called, not that XML parsing actually works |
| `tests/session_id_refactor.test.ts` | 10+ | **Code pattern validation**: Tests that certain patterns exist in code, not that they work |
| `tests/session_id_usage_validation.test.ts` | 5+ | **Static analysis as tests**: Reads files and checks for string patterns. Should be a lint rule, not a test |
| `tests/validate_sql_update.test.ts` | 5+ | **One-time validation**: Validated a migration, no ongoing value |
| `tests/worker-spawn.test.ts` | 5+ | **Trivial mocking**: Tests spawn config exists, doesn't test actual spawning |

**Why Weak**: These tests create false confidence. The response-processor tests in particular set up elaborate mocks and then verify those mocks were called - they don't verify actual XML parsing or database operations work correctly.

---

### Score 1 - Delete (2 tests)

Tests that actively harm the codebase or provide zero value.

| File | Test Count | Issues |
|------|------------|--------|
| `tests/context/context-builder.test.ts` | 20+ | **CRITICAL**: Incomplete logger mock pollutes module cache. Causes 81 test failures when run with full suite. Tests verify mocks, not actual context building |
| `tests/scripts/export-types.test.ts` | 30+ | **Zero runtime value**: Tests TypeScript type definitions compile. TypeScript compiler already does this. These tests can literally never fail at runtime |

**Why Delete**:
- **context-builder.test.ts**: This test is actively harmful. It imports the logger module with an incomplete mock (only 4 of 13+ methods mocked), and this polluted mock persists in Bun's module cache. When other tests run afterwards, they get the broken logger singleton. The test itself only verifies that mocked methods were called with expected arguments - it doesn't test actual context building logic.
- **export-types.test.ts**: These tests instantiate TypeScript interfaces and verify properties exist. TypeScript already validates this at compile time. If a type definition is wrong, the code won't compile. These runtime tests add overhead without catching any bugs that TypeScript wouldn't already catch.

---

## Missing Test Coverage

### Critical Gaps

| Area | Risk | Current Coverage | Recommendation |
|------|------|------------------|----------------|
| **Hook execution E2E** | HIGH | None | Add integration tests that run hooks with real Claude Code SDK |
| **Worker API endpoints** | HIGH | Partial (server.test.ts) | Add tests for all REST endpoints: `/observe`, `/search`, `/health` |
| **Chroma vector sync** | HIGH | None | Add tests for ChromaSync.ts embedding generation and retrieval |
| **Database migrations** | MEDIUM | None | Add tests for schema migrations, especially version upgrades |
| **Settings file I/O** | MEDIUM | Partial | Add tests for settings file creation, corruption recovery |
| **Tag stripping** | MEDIUM | None | Add tests for `<private>` and `<meta-observation>` tag handling |
| **MCP tool handlers** | MEDIUM | None | Add tests for search, timeline, get_observations MCP tools |
| **Error recovery** | MEDIUM | Minimal | Add tests for worker crash recovery, database corruption handling |

### Recommended New Tests

1. **`tests/integration/hook-execution.test.ts`**
   - Run actual hooks with mocked Claude Code environment
   - Verify data flows correctly through SessionStart -> PostToolUse -> SessionEnd

2. **`tests/integration/worker-api.test.ts`**
   - Start actual worker server
   - Make real HTTP requests to all endpoints
   - Verify response formats and error handling

3. **`tests/services/chroma-sync.test.ts`**
   - Test embedding generation with real text
   - Test semantic similarity retrieval
   - Test sync between SQLite and Chroma

4. **`tests/utils/tag-stripping.test.ts`**
   - Test `<private>` tag removal
   - Test `<meta-observation>` tag handling
   - Test nested tag scenarios

---

## Recommendations

### Immediate Actions

1. **Delete or fix `tests/context/context-builder.test.ts`** (Priority: CRITICAL)
   - This test causes 81 other tests to fail due to module cache pollution
   - Either complete the logger mock (all 13+ methods) or delete entirely
   - Recommended: Delete and rewrite as integration test without mocks

2. **Delete `tests/scripts/export-types.test.ts`** (Priority: HIGH)
   - Zero runtime value - TypeScript compiler already validates types
   - Remove to reduce test suite noise

3. **Delete or convert validation tests** (Priority: MEDIUM)
   - `tests/session_id_refactor.test.ts` - Was useful during migration, no longer needed
   - `tests/session_id_usage_validation.test.ts` - Convert to lint rule
   - `tests/validate_sql_update.test.ts` - Was useful during migration, no longer needed

### Architecture Improvements

1. **Create test utilities for common mocks**
   - Centralize logger mock in `tests/utils/mock-logger.ts` with ALL methods
   - Centralize database mock with proper transaction support
   - Prevent incomplete mocks from polluting module cache

2. **Add integration test suite**
   - Create `tests/integration/` directory
   - Run with real worker server (separate database)
   - Test actual data flow, not mock interactions

3. **Implement test isolation**
   - Use `beforeEach` to reset module state
   - Consider test file ordering to prevent cache pollution
   - Add cleanup hooks for database state

### Quality Guidelines

For future tests, follow these principles:

1. **Prefer real implementations over mocks**
   - Use in-memory SQLite instead of mock database
   - Use real HTTP requests instead of mock req/res
   - Mock only external services (AI APIs, file system when needed)

2. **Test behavior, not implementation**
   - Bad: "verify function X was called with argument Y"
   - Good: "verify output contains expected data after operation"

3. **Each test should be able to fail**
   - If a test cannot fail (like type validation tests), it's not testing anything
   - Write tests that would catch real bugs

4. **Keep test setup minimal**
   - If >50% of test is mock setup, consider integration testing
   - Complex mock setup often indicates testing the wrong thing

---

## Appendix: Full Test File Inventory

| File | Score | Tests | LOC | Mock % |
|------|-------|-------|-----|--------|
| `tests/context/context-builder.test.ts` | 1 | 20+ | 400+ | 80% |
| `tests/context/formatters/markdown-formatter.test.ts` | 4 | 15+ | 200+ | 10% |
| `tests/context/observation-compiler.test.ts` | 3 | 20+ | 300+ | 60% |
| `tests/context/token-calculator.test.ts` | 5 | 35+ | 400+ | 0% |
| `tests/cursor-context-update.test.ts` | 3 | 5+ | 100+ | 20% |
| `tests/cursor-hook-outputs.test.ts` | 5 | 12+ | 250+ | 10% |
| `tests/cursor-hooks-json-utils.test.ts` | 4 | 8+ | 150+ | 0% |
| `tests/cursor-mcp-config.test.ts` | 4 | 10+ | 200+ | 20% |
| `tests/cursor-registry.test.ts` | 3 | 8+ | 150+ | 30% |
| `tests/gemini_agent.test.ts` | 4 | 20+ | 400+ | 40% |
| `tests/hook-constants.test.ts` | 3 | 5+ | 80+ | 0% |
| `tests/infrastructure/graceful-shutdown.test.ts` | 4 | 15+ | 300+ | 40% |
| `tests/infrastructure/health-monitor.test.ts` | 4 | 15+ | 250+ | 30% |
| `tests/infrastructure/process-manager.test.ts` | 4 | 12+ | 200+ | 35% |
| `tests/infrastructure/wmic-parsing.test.ts` | 5 | 20+ | 240+ | 0% |
| `tests/logger-coverage.test.ts` | 3 | 8+ | 150+ | 20% |
| `tests/scripts/export-types.test.ts` | 1 | 30+ | 350+ | 0% |
| `tests/scripts/smart-install.test.ts` | 3 | 25+ | 230+ | 0% |
| `tests/server/error-handler.test.ts` | 3 | 8+ | 150+ | 50% |
| `tests/server/server.test.ts` | 5 | 15+ | 300+ | 20% |
| `tests/session_id_refactor.test.ts` | 2 | 10+ | 200+ | N/A |
| `tests/session_id_usage_validation.test.ts` | 2 | 5+ | 150+ | N/A |
| `tests/session_store.test.ts` | 3 | 10+ | 180+ | 10% |
| `tests/shared/settings-defaults-manager.test.ts` | 4 | 27 | 400+ | 20% |
| `tests/sqlite/observations.test.ts` | 5 | 25+ | 400+ | 0% |
| `tests/sqlite/prompts.test.ts` | 4 | 15+ | 250+ | 0% |
| `tests/sqlite/sessions.test.ts` | 5 | 20+ | 350+ | 0% |
| `tests/sqlite/summaries.test.ts` | 4 | 15+ | 250+ | 0% |
| `tests/sqlite/transactions.test.ts` | 5 | 15+ | 300+ | 0% |
| `tests/utils/logger-format-tool.test.ts` | 5 | 56 | 1000+ | 0% |
| `tests/validate_sql_update.test.ts` | 2 | 5+ | 100+ | N/A |
| `tests/worker/agents/fallback-error-handler.test.ts` | 3 | 10+ | 200+ | 40% |
| `tests/worker/agents/observation-broadcaster.test.ts` | 3 | 15+ | 350+ | 60% |
| `tests/worker/agents/response-processor.test.ts` | 2 | 20+ | 500+ | 70% |
| `tests/worker/agents/session-cleanup-helper.test.ts` | 3 | 10+ | 200+ | 50% |
| `tests/worker/search/result-formatter.test.ts` | 4 | 15+ | 250+ | 20% |
| `tests/worker/search/search-orchestrator.test.ts` | 4 | 30+ | 500+ | 45% |
| `tests/worker/search/strategies/chroma-search-strategy.test.ts` | 4 | 20+ | 350+ | 50% |
| `tests/worker/search/strategies/hybrid-search-strategy.test.ts` | 4 | 20+ | 300+ | 45% |
| `tests/worker/search/strategies/sqlite-search-strategy.test.ts` | 4 | 25+ | 350+ | 40% |
| `tests/worker-spawn.test.ts` | 2 | 5+ | 100+ | 60% |

---

*Report generated by Claude Code (Opus 4.5) on 2026-01-05*


================================================
FILE: .claude/settings.json
================================================
{
  "env": {},
  "permissions": {
    "deny": [
      "Read(./package-lock.json)",
      "Read(./node_modules/**)",
      "Read(./.DS_Store)"
    ]
  }
}


================================================
FILE: .claude-plugin/CLAUDE.md
================================================
<claude-mem-context>
# Recent Activity

### Oct 25, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #2374 | 2:55 PM | ✅ | Marketplace metadata version synchronized to 4.2.11 | ~157 |

### Oct 27, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #2757 | 1:23 AM | 🟣 | Released v4.3.3 with Configurable Session Display and First-Time Setup UX | ~391 |

### Nov 4, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #3706 | 9:47 PM | ✅ | Marketplace Plugin Version Synchronized to 5.0.2 | ~162 |
| #3655 | 3:43 PM | ✅ | Version bumped to 5.0.1 across project | ~354 |

### Nov 5, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #4068 | 10:58 PM | ✅ | Committed v5.1.0 release with comprehensive release notes | ~486 |
| #4066 | 10:57 PM | ✅ | Updated marketplace.json version to 5.1.0 | ~192 |
| #3739 | 2:24 PM | ✅ | Updated version to 5.0.3 across project manifests | ~322 |

### Nov 6, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #4099 | 1:13 PM | 🟣 | Theme Toggle for Light/Dark Mode | ~253 |
| #4096 | " | ✅ | Marketplace Metadata Version Sync | ~179 |
| #4092 | 1:12 PM | 🔵 | Marketplace Configuration for Claude-Mem Plugin | ~194 |
| #4078 | 12:50 PM | 🔴 | Fixed PM2 ENOENT error on Windows systems | ~286 |
| #4075 | 12:49 PM | ✅ | Marketplace plugin version synchronized to 5.1.1 | ~189 |

### Nov 7, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #4612 | 6:33 PM | ✅ | Version Bumped to 5.2.0 Across All Package Metadata | ~359 |
| #4598 | 6:31 PM | ✅ | PR #69 Merged: cleanup/worker Branch Integration | ~469 |
| #4298 | 11:54 AM | 🔴 | Fixed PostToolUse Hook Schema Compliance | ~310 |
| #4295 | 11:53 AM | ✅ | Synchronized Plugin Marketplace Version to 5.1.4 | ~188 |

### Nov 8, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #5150 | 7:37 PM | 🟣 | Troubleshooting Skill Added to Claude-Mem Plugin | ~427 |
| #5133 | 7:29 PM | ✅ | Version 5.2.3 Released with Build Process | ~487 |

### Nov 9, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #5941 | 7:14 PM | ✅ | Marketplace Version Updated to 5.4.0 | ~157 |

### Nov 10, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #6341 | 1:49 PM | ✅ | Version Bumped to 5.4.1 | ~239 |

### Nov 11, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #6602 | 1:51 PM | ✅ | Version 5.4.5 Released to GitHub | ~279 |
| #6601 | " | ✅ | Version Patch Bump 5.4.4 to 5.4.5 | ~233 |

### Nov 14, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #8212 | 3:06 PM | 🔵 | Version Consistency Verification Across Multiple Configuration Files | ~238 |

### Nov 25, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #14882 | 1:32 PM | 🔵 | Marketplace Configuration Defines Plugin Version and Source Directory | ~366 |

### Nov 30, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #18064 | 10:52 PM | ✅ | Bumped version to 6.3.7 in marketplace.json | ~179 |
| #18060 | 10:51 PM | 🔵 | Read marketplace.json plugin manifest | ~190 |

### Dec 1, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #18428 | 3:33 PM | 🔵 | Version Conflict in Marketplace Configuration | ~191 |

### Dec 4, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #20049 | 3:23 PM | ✅ | Updated marketplace.json version to 6.5.2 | ~203 |

### Dec 9, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #22559 | 1:08 AM | ✅ | Version 7.0.3 committed to repository | ~261 |
| #22551 | 1:07 AM | ✅ | Marketplace metadata updated to version 7.0.3 | ~179 |

### Dec 10, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #23440 | 2:25 PM | ✅ | Marketplace Configuration Updated to 7.0.8 | ~188 |

### Dec 14, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #26799 | 11:39 PM | ✅ | Marketplace Manifest Version Updated to 7.2.3 | ~248 |
| #26796 | " | ✅ | Version Bumped to 7.2.3 in marketplace.json | ~259 |
| #26792 | 11:38 PM | 🔵 | Current Version Confirmed as 7.2.2 Across All Configuration Files | ~291 |

### Dec 16, 2025

| ID | Time | T | Title | Read |
|----|------|---|-------|------|
| #28306 | 10:08 PM | 🔵 | Marketplace Configuration Also Shows Version 7.3.3 | ~220 |
| #27555 | 4:48 PM | ✅ | Version bump committed to main branch | ~242 |
| #27553 | " | ✅ | Version consistency verified across all configuration files | ~195 |
| #27551 | 4:47 PM | ✅ | Marketplace.json version updated to 7.3.1 | ~207 |
</claude-mem-context>

================================================
FILE: .claude-plugin/marketplace.json
================================================
{
  "name": "thedotmack",
  "owner": {
    "name": "Alex Newman"
  },
  "metadata": {
    "description": "Plugins by Alex Newman (thedotmack)",
    "homepage": "https://github.com/thedotmack/claude-mem"
  },
  "plugins": [
    {
      "name": "claude-mem",
      "version": "10.6.3",
      "source": "./plugin",
      "description": "Persistent memory system for Claude Code - context compression across sessions"
    }
  ]
}


================================================
FILE: .claude-plugin/plugin.json
================================================
{
  "name": "claude-mem",
  "version": "10.4.1",
  "description": "Persistent memory system for Claude Code - seamlessly preserve context across sessions",
  "author": {
    "name": "Alex Newman"
  },
  "repository": "https://github.com/thedotmack/claude-mem",
  "license": "AGPL-3.0",
  "keywords": [
    "memory",
    "context",
    "persistence",
    "hooks",
    "mcp"
  ]
}


================================================
FILE: .github/FUNDING.yml
================================================
github: thedotmack


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Use the automated bug report tool for best results
title: ''
labels: 'bug, needs-triage'
assignees: ''

---

## Before submitting

- [ ] I searched [existing issues](https://github.com/thedotmack/claude-mem/issues) and confirmed this is not a duplicate

---

## ⚡ Quick Bug Report (Recommended)

**Use the automated bug report generator** for comprehensive diagnostics:

```bash
# Navigate to the plugin directory
cd ~/.claude/plugins/marketplaces/thedotmack

# Run the bug report tool
npm run bug-report
```

**Plugin Paths:**
- **macOS/Linux**: `~/.claude/plugins/marketplaces/thedotmack`
- **Windows**: `%USERPROFILE%\.claude\plugins\marketplaces\thedotmack`

**Features:**
- 🌎 Auto-translates any language to English
- 📊 Collects all diagnostics automatically
- 🤖 AI-formatted professional issue
- 🔒 Privacy-safe (paths sanitized, `--no-logs` option)
- 🌐 Auto-opens GitHub with pre-filled issue

---

## 📝 Manual Bug Report

If you prefer to file manually or can't access the plugin directory:

### Bug Description
A clear description of what the bug is.

### Steps to Reproduce
1. Go to '...'
2. Click on '...'
3. See error

### Expected Behavior
What you expected to happen.

### Environment
- **Claude-mem version**:
- **Claude Code version**:
- **OS**:
- **Platform**:

### Logs
Worker logs are located at:
- **Path**: `~/.claude-mem/logs/worker-YYYY-MM-DD.log`
- **Example**: `~/.claude-mem/logs/worker-2025-12-14.log`

Please paste relevant log entries (last 50 lines or error messages):

```
[Paste logs here]
```

### Additional Context
Any other context about the problem.


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature-request
assignees: ''

---

## Before submitting

- [ ] I searched [existing issues](https://github.com/thedotmack/claude-mem/issues) and confirmed this is not a duplicate

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/workflows/claude-code-review.yml
================================================
name: Claude Code Review

on:
  pull_request:
    types: [opened, synchronize]
    # Optional: Only run on specific file changes
    # paths:
    #   - "src/**/*.ts"
    #   - "src/**/*.tsx"
    #   - "src/**/*.js"
    #   - "src/**/*.jsx"

jobs:
  claude-review:
    # Optional: Filter by PR author
    # if: |
    #   github.event.pull_request.user.login == 'external-contributor' ||
    #   github.event.pull_request.user.login == 'new-developer' ||
    #   github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'

    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
      issues: read
      id-token: write

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - name: Run Claude Code Review
        id: claude-review
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
          prompt: |
            REPO: ${{ github.repository }}
            PR NUMBER: ${{ github.event.pull_request.number }}

            Please review this pull request and provide feedback on:
            - Code quality and best practices
            - Potential bugs or issues
            - Performance considerations
            - Security concerns
            - Test coverage

            Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.

            Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.

          # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
          # or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
          claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'



================================================
FILE: .github/workflows/claude.yml
================================================
name: Claude Code

on:
  issue_comment:
    types: [created]
  pull_request_review_comment:
    types: [created]
  issues:
    types: [opened, assigned]
  pull_request_review:
    types: [submitted]

jobs:
  claude:
    if: |
      (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
      (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
      (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')))
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: read
      issues: read
      id-token: write
      actions: read # Required for Claude to read CI results on PRs
    steps:
      - name: Checkout repository
        uses: actions/checkout@v6
        with:
          fetch-depth: 1

      - name: Run Claude Code
        id: claude
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

          # This is an optional setting that allows Claude to read CI results on PRs
          additional_permissions: |
            actions: read

          # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
          # prompt: 'Update the pull request description to include a summary of changes.'

          # Optional: Add claude_args to customize behavior and configuration
          # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
          # or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
          # claude_args: '--allowed-tools Bash(gh pr:*)'



================================================
FILE: .github/workflows/convert-feature-requests.yml
================================================
name: Convert Feature Requests to Discussions

on:
  issues:
    types: [labeled]
  workflow_dispatch:
    inputs:
      issue_number:
        description: 'Issue number to convert to discussion'
        required: true
        type: number

jobs:
  convert:
    runs-on: ubuntu-latest
    # Only run on labeled event if the label is 'feature-request', or always run on workflow_dispatch
    if: |
      (github.event_name == 'issues' && github.event.label.name == 'feature-request') ||
      github.event_name == 'workflow_dispatch'

    permissions:
      issues: write
      discussions: write
      contents: read

    steps:
      - name: Get issue details and create discussion
        id: discussion
        uses: actions/github-script@v8
        with:
          script: |
            // Get issue details
            let issue;
            if (context.eventName === 'workflow_dispatch') {
              const { data } = await github.rest.issues.get({
                owner: context.repo.owner,
                repo: context.repo.repo,
                issue_number: context.payload.inputs.issue_number
              });
              issue = data;
            } else {
              issue = context.payload.issue;
            }

            console.log(`Processing issue #${issue.number}: ${issue.title}`);

            // Format the discussion body with a reference to the original issue
            const discussionBody = `> Originally posted as issue #${issue.number} by @${issue.user.login}\n> ${issue.html_url}\n\n${issue.body || 'No description provided.'}`;

            const mutation = `
              mutation($repositoryId: ID!, $categoryId: ID!, $title: String!, $body: String!) {
                createDiscussion(input: {
                  repositoryId: $repositoryId
                  categoryId: $categoryId
                  title: $title
                  body: $body
                }) {
                  discussion {
                    url
                    number
                  }
                }
              }
            `;

            const variables = {
              repositoryId: 'R_kgDOPng1Jw',
              categoryId: 'DIC_kwDOPng1J84Cw86z',
              title: issue.title,
              body: discussionBody
            };

            try {
              const result = await github.graphql(mutation, variables);
              const discussionUrl = result.createDiscussion.discussion.url;
              const discussionNumber = result.createDiscussion.discussion.number;

              core.setOutput('url', discussionUrl);
              core.setOutput('number', discussionNumber);
              core.setOutput('issue_number', issue.number);

              console.log(`Created discussion #${discussionNumber}: ${discussionUrl}`);
              return { discussionUrl, discussionNumber, issueNumber: issue.number };
            } catch (error) {
              core.setFailed(`Failed to create discussion: ${error.message}`);
              throw error;
            }

      - name: Comment on issue
        uses: actions/github-script@v8
        with:
          script: |
            const issueNumber = ${{ steps.discussion.outputs.issue_number }};
            const discussionUrl = '${{ steps.discussion.outputs.url }}';

            const comment = `This feature request has been moved to [Discussions](${discussionUrl}) to keep bug reports separate from feature ideas.\n\nPlease continue the conversation there - we'd love to hear your thoughts!`;

            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issueNumber,
              body: comment
            });

            console.log(`Added comment to issue #${issueNumber}`);

      - name: Close and lock issue
        uses: actions/github-script@v8
        with:
          script: |
            const issueNumber = ${{ steps.discussion.outputs.issue_number }};

            // Close the issue
            await github.rest.issues.update({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issueNumber,
              state: 'closed'
            });

            console.log(`Closed issue #${issueNumber}`);

            // Lock the issue
            await github.rest.issues.lock({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: issueNumber,
              lock_reason: 'resolved'
            });

            console.log(`Locked issue #${issueNumber}`);


================================================
FILE: .github/workflows/deploy-install-scripts.yml
================================================
name: Deploy Install Scripts

on:
  push:
    branches: [main]
    paths:
      - 'openclaw/install.sh'
      - 'install/**'
  workflow_dispatch:

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Copy install scripts to deploy directory
        run: |
          mkdir -p install/public
          cp openclaw/install.sh install/public/openclaw.sh

      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'
          working-directory: ./install


================================================
FILE: .github/workflows/npm-publish.yml
================================================
name: Publish to npm

on:
  push:
    tags:
      - 'v*'

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          registry-url: 'https://registry.npmjs.org'
      - run: npm install --ignore-scripts
      - run: npm run build
      - run: npm publish
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}


================================================
FILE: .github/workflows/summary.yml
================================================
name: Summarize new issues

on:
  issues:
    types: [opened]

jobs:
  summary:
    runs-on: ubuntu-latest
    permissions:
      issues: write
      models: read
      contents: read

    steps:
      - name: Checkout repository
        uses: actions/checkout@v6

      - name: Run AI inference
        id: inference
        uses: actions/ai-inference@v2
        with:
          prompt: |
            Summarize the following GitHub issue in one paragraph:
            Title: ${{ github.event.issue.title }}
            Body: ${{ github.event.issue.body }}

      - name: Comment with AI summary
        run: |
          gh issue comment $ISSUE_NUMBER --body '${{ steps.inference.outputs.response }}'
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          ISSUE_NUMBER: ${{ github.event.issue.number }}
          RESPONSE: ${{ steps.inference.outputs.response }}


================================================
FILE: .gitignore
================================================
datasets/
node_modules/
dist/
!installer/dist/
**/_tree-sitter/
*.log
.DS_Store
.env
.env.local
*.tmp
*.temp
.install-version
.claude/settings.local.json
.claude/agents/
.claude/skills/
.claude/plans/
.claude/worktrees/
plugin/data/
plugin/data.backup/
package-lock.json
bun.lock
private/
Auto Run Docs/

# Generated UI files (built from viewer-template.html)
src/ui/viewer.html

# Local MCP server config (for development only)
.mcp.json
.cursor/

# Ignore WebStorm project files (for dinosaur IDE users)
.idea/

.claude-octopus/
.claude/session-intent.md
.claude/session-plan.md
.octo/

================================================
FILE: .markdownlint.json
================================================
{
  "MD013": false
}

================================================
FILE: .plan/npx-distribution.md
================================================
# Plan: NPX Distribution + Universal IDE/CLI Coverage for claude-mem

## Problem

1. **Installation is slow and fragile**: Current install clones the full git repo, runs `npm install`, and builds from source. The npm package already ships pre-built artifacts.

2. **IDE coverage is limited**: claude-mem only supports Claude Code (plugin) and Cursor (hooks installer). The AI coding tools landscape has exploded — Gemini CLI (95k stars), OpenCode (110k stars), Windsurf (~1M users), Codex CLI, Antigravity, Goose, Crush, Copilot CLI, and more all support extensibility.

## Key Insights

- **npm package already has everything**: `plugin/` directory ships pre-built. No git clone or build needed.
- **Transcript watcher already exists**: `src/services/transcripts/` has a fully built schema-based JSONL tailer. It just needs schemas for more tools.
- **3 integration tiers exist**: (1) Hook/plugin-based (Claude Code, Gemini CLI, OpenCode, Windsurf, Codex CLI, OpenClaw), (2) MCP-based (Cursor, Copilot CLI, Antigravity, Goose, Crush, Roo Code), (3) Transcript-based (anything with structured log files).
- **OpenClaw plugin already built**: Full plugin at `openclaw/src/index.ts` (1000+ lines). Needs to be wired into the npx installer.
- **Gemini CLI is architecturally near-identical to Claude Code**: 11 lifecycle hooks, JSON via stdin/stdout, exit code 0/2 convention, `GEMINI.md` context files, `~/.gemini/settings.json`. This is the easiest high-value integration.
- **OpenCode has the richest plugin system**: 20+ hook events across 12 categories, JS/TS plugin modules, custom tool creation, MCP support. 110k stars — largest open-source AI CLI.
- **`npx skills` by Vercel supports 41 agents** — proving the multi-IDE installer UX works. Their agent detection pattern (check if config dir exists) is the right model.
- **All IDEs share a single worker on port 37777**: One worker serves all integrations. Session source (which IDE) is tracked via the `source` field in hook payloads. No per-IDE worker instances.
- **This npx CLI fully replaces the old `claude-mem-installer`**: Not a supplement — the complete replacement.

## Solution

`npx claude-mem` becomes a unified CLI: install, configure any IDE, manage the worker, search memory.

```
npx claude-mem                          # Interactive install + IDE selection
npx claude-mem install                  # Same as above
npx claude-mem install --ide windsurf   # Direct IDE setup
npx claude-mem start / stop / status    # Worker management
npx claude-mem search <query>           # Search memory from terminal
npx claude-mem transcript watch         # Start transcript watcher
```

## Platform Support

**Windows, macOS, and Linux are all first-class targets.** Platform-specific considerations:

- **Config paths**: Use `os.homedir()` and `path.join()` everywhere — never hardcode `/` or `~`
- **Shebangs**: `#!/usr/bin/env node` for the CLI entry point (cross-platform via Node)
- **Bun detection**: Check `PATH`, common install locations per platform (`%USERPROFILE%\.bun\bin\bun.exe` on Windows, `~/.bun/bin/bun` on Unix)
- **File permissions**: `fs.chmod` is a no-op on Windows; don't gate on it
- **Process management**: Worker start/stop uses signals on Unix, taskkill on Windows — match existing `worker-service.ts` patterns
- **VS Code paths**: `~/Library/Application Support/Code/` (macOS), `~/.config/Code/` (Linux), `%APPDATA%/Code/` (Windows)
- **Shell config**: `.bashrc`/`.zshrc` on Unix, PowerShell profile on Windows (for PATH modifications if needed)

---

## Phase 0: Research Findings

### IDE Integration Tiers

**Tier 1 — Native Hook/Plugin Systems** (highest fidelity, real-time capture):

| Tool | Hooks | Config Location | Context Injection | Stars/Users |
|------|-------|----------------|-------------------|-------------|
| Claude Code | 5 lifecycle hooks | `~/.claude/settings.json` | CLAUDE.md, plugins | ~25% market |
| Gemini CLI | 11 lifecycle hooks | `~/.gemini/settings.json` | GEMINI.md | ~95k stars |
| OpenCode | 20+ event hooks + plugin SDK | `~/.config/opencode/opencode.json` | AGENTS.md + rules dirs | ~110k stars |
| Windsurf | 11 Cascade hooks | `.windsurf/hooks.json` | `.windsurf/rules/*.md` | ~1M users |
| Codex CLI | `notify` hook | `~/.codex/config.toml` | `.codex/AGENTS.md`, MCP | Growing (OpenAI) |
| OpenClaw | 8 event hooks + plugin SDK | `~/.openclaw/openclaw.json` | MEMORY.md sync | ~196k stars |

**Tier 2 — MCP Integration** (tool-based, search + context injection):

| Tool | MCP Support | Config Location | Context Injection |
|------|------------|----------------|-------------------|
| Cursor | First-class | `.cursor/mcp.json` | `.cursor/rules/*.mdc` |
| Copilot CLI | First-class (default MCP) | `~/.copilot/config` | `.github/copilot-instructions.md` |
| Antigravity | First-class + MCP Store | `~/.gemini/antigravity/mcp_config.json` | `.agent/rules/`, GEMINI.md |
| Goose | Native MCP (co-developed protocol) | `~/.config/goose/config.yaml` | MCP context |
| Crush | MCP + Skills | JSON config (charm.land schema) | Skills system |
| Roo Code | First-class | `.roo/` | `.roo/rules/*.md`, `AGENTS.md` |
| Warp | MCP + Warp Drive | `WARP.md` + Warp Drive UI | `WARP.md` |

**Tier 3 — Transcript File Watching** (passive, file-based):

| Tool | Transcript Location | Format |
|------|-------------------|--------|
| Claude Code | `~/.claude/projects/<proj>/<session>.jsonl` | JSONL |
| Codex CLI | `~/.codex/sessions/**/*.jsonl` | JSONL |
| Gemini CLI | `~/.gemini/tmp/<hash>/chats/` | JSON |
| OpenCode | `.opencode/` (SQLite) | SQLite — needs export |

### What claude-mem Already Has

| Component | Status | Location |
|-----------|--------|----------|
| Claude Code plugin | Complete | `plugin/hooks/hooks.json` |
| Cursor hooks installer | Complete | `src/services/integrations/CursorHooksInstaller.ts` |
| Platform adapters | Claude Code + Cursor + raw | `src/cli/adapters/` |
| Transcript watcher | Complete (schema-based JSONL) | `src/services/transcripts/` |
| Codex transcript schema | Sample exists | `src/services/transcripts/config.ts` |
| OpenClaw plugin | Complete (1000+ lines) | `openclaw/src/index.ts` |
| MCP server | Complete | `plugin/scripts/mcp-server.cjs` |
| Gemini CLI support | Not started | — |
| OpenCode support | Not started | — |
| Windsurf support | Not started | — |

### Patterns to Copy

- **Agent detection from `npx skills`** (`vercel-labs/skills/src/agents.ts`): Check if config directory exists
- **Existing installer logic** (`installer/src/steps/install.ts:29-83`): registerMarketplace, registerPlugin, enablePluginInClaudeSettings — **extract shared logic** from existing installer into reusable modules (DRY with the new CLI)
- **Bun resolution** (`plugin/scripts/bun-runner.js`): PATH lookup + common locations per platform
- **CursorHooksInstaller** (`src/services/integrations/CursorHooksInstaller.ts`): Reference implementation for IDE hooks installation

---

## Phase 1: NPX CLI Entry Point

### What to implement

1. **Add `bin` field to `package.json`**:
   ```json
   "bin": {
     "claude-mem": "./dist/cli/index.js"
   }
   ```

2. **Create `src/npx-cli/index.ts`** — a Node.js CLI router (NOT Bun) with command categories:

   **Install commands** (pure Node.js, no Bun required):
   - `npx claude-mem` or `npx claude-mem install` → interactive install (IDE multi-select)
   - `npx claude-mem install --ide <name>` → direct IDE setup (only for implemented IDEs; unimplemented ones error with "Support for <name> coming soon")
   - `npx claude-mem update` → update to latest version
   - `npx claude-mem uninstall` → remove plugin and IDE configs
   - `npx claude-mem version` → print version

   **Runtime commands** (delegate to Bun via installed plugin):
   - `npx claude-mem start` → spawns `bun worker-service.cjs start`
   - `npx claude-mem stop` → spawns `bun worker-service.cjs stop`
   - `npx claude-mem restart` → spawns `bun worker-service.cjs restart`
   - `npx claude-mem status` → spawns `bun worker-service.cjs status`
   - `npx claude-mem search <query>` → hits `GET http://localhost:37777/api/search?q=<query>`
   - `npx claude-mem transcript watch` → starts transcript watcher

   **Runtime commands must check for installation first**: If plugin directory doesn't exist at `~/.claude/plugins/marketplaces/thedotmack/`, print "claude-mem is not installed. Run: npx claude-mem install" and exit.

3. **The install flow** (fully replaces git clone + build):
   - Detect the npm package's own location (`import.meta.url` or `__dirname`)
   - Copy `plugin/` from the npm package to `~/.claude/plugins/marketplaces/thedotmack/`
   - Copy `plugin/` to `~/.claude/plugins/cache/thedotmack/claude-mem/<version>/`
   - Register marketplace in `~/.claude/plugins/known_marketplaces.json`
   - Register plugin in `~/.claude/plugins/installed_plugins.json`
   - Enable in `~/.claude/settings.json`
   - Run `npm install` in the marketplace dir (for `@chroma-core/default-embed` — native ONNX binaries, can't be bundled)
   - Trigger smart-install.js for Bun/uv setup
   - Run IDE-specific setup for each selected IDE

4. **Interactive IDE selection** (auto-detect + prompt):
   - Auto-detect installed IDEs by checking config directories
   - Present multi-select with detected IDEs pre-selected
   - Detection map:
     - Claude Code: `~/.claude/` exists
     - Gemini CLI: `~/.gemini/` exists
     - OpenCode: `~/.config/opencode/` exists OR `opencode` in PATH
     - OpenClaw: `~/.openclaw/` exists
     - Windsurf: `~/.codeium/windsurf/` exists
     - Codex CLI: `~/.codex/` exists
     - Cursor: `~/.cursor/` exists
     - Copilot CLI: `copilot` in PATH (it's a CLI tool, not a config dir)
     - Antigravity: `~/.gemini/antigravity/` exists
     - Goose: `~/.config/goose/` exists OR `goose` in PATH
     - Crush: `crush` in PATH
     - Roo Code: check for VS Code extension directory containing `roo-code`
     - Warp: `~/.warp/` exists OR `warp` in PATH

5. **The runtime command routing**:
   - Locate the installed plugin directory
   - Find Bun binary (same logic as `bun-runner.js`, platform-aware)
   - Spawn `bun worker-service.cjs <command>` and pipe stdio through
   - For `search`: HTTP request to running worker

### Patterns to follow

- `installer/src/steps/install.ts:29-83` for marketplace registration — **extract to shared module**
- `plugin/scripts/bun-runner.js` for Bun resolution
- `vercel-labs/skills/src/agents.ts` for IDE auto-detection pattern

### Verification

- `npx claude-mem install` copies plugin to correct directories on macOS, Linux, and Windows
- Auto-detection finds installed IDEs
- `npx claude-mem start/stop/status` work after install
- `npx claude-mem search "test"` returns results
- `npx claude-mem start` before install prints helpful error message
- `npx claude-mem update` and `npx claude-mem uninstall` work correctly
- `npx claude-mem version` prints version

### Anti-patterns

- Do NOT require Bun for install commands — pure Node.js
- Do NOT clone the git repo
- Do NOT build from source at install time
- Do NOT depend on `bun:sqlite` in the CLI entry point

---

## Phase 2: Build Pipeline Integration

### What to implement

1. **Add CLI build step to `scripts/build-hooks.js`**:
   - Compile `src/npx-cli/index.ts` → `dist/cli/index.js`
   - Bundle `@clack/prompts` and `picocolors` into the output (self-contained)
   - Shebang: `#!/usr/bin/env node`
   - Set executable permissions (no-op on Windows, that's fine)

2. **Move `@clack/prompts` and `picocolors`** to main package.json as dev dependencies (bundled by esbuild into dist/cli/index.js)

3. **Verify `package.json` `files` field**: Currently `["dist", "plugin"]`. `dist/cli/index.js` is already included since it's under `dist/`. No change needed.

4. **Update `prepublishOnly`** to ensure CLI is built before npm publish (already covered — `npm run build` calls `build-hooks.js`)

5. **Pre-build OpenClaw plugin**: Add an esbuild step that compiles `openclaw/src/index.ts` → `openclaw/dist/index.js` so it ships ready-to-use. No `tsc` at install time.

6. **Add `openclaw/dist/` to `package.json` `files` field** (or add `openclaw` if the whole directory should ship)

### Verification

- `npm run build` produces `dist/cli/index.js` with correct shebang
- `npm run build` produces `openclaw/dist/index.js` pre-built
- `npm pack` includes both `dist/cli/index.js` and `openclaw/dist/`
- `node dist/cli/index.js --help` works without Bun
- Package size is reasonable (check with `npm pack --dry-run`)

---

## Phase 3: Gemini CLI Integration (Tier 1 — Hook-Based)

**Why first among new IDEs**: Near-identical architecture to Claude Code. 11 lifecycle hooks with JSON stdin/stdout, same exit code conventions (0=success, 2=block), `GEMINI.md` context files. 95k GitHub stars. Lowest effort, highest confidence.

### Gemini CLI Hook Events

| Event | Map to claude-mem | Use |
|-------|-------------------|-----|
| `SessionStart` | `session-init` | Start tracking session |
| `BeforeAgent` | `user-prompt` | Capture user prompt |
| `AfterAgent` | `observation` | Capture full agent response |
| `BeforeTool` | — | Skip (pre-execution, no result yet) |
| `AfterTool` | `observation` | Capture tool name + input + response |
| `BeforeModel` | — | Skip (too low-level, LLM request details) |
| `AfterModel` | — | Skip (raw LLM response, redundant with AfterAgent) |
| `BeforeToolSelection` | — | Skip (internal planning step) |
| `PreCompress` | `summary` | Trigger summary before context compression |
| `Notification` | — | Skip (system alerts, not session data) |
| `SessionEnd` | `session-end` | Finalize session |

**Mapped**: 5 of 11 events. **Skipped**: 6 events that are either too low-level (BeforeModel/AfterModel), pre-execution (BeforeTool, BeforeToolSelection), or system-level (Notification).

### Verified Stdin Payload Schemas (from `packages/core/src/hooks/types.ts`)

**Base input (all hooks receive):**
```typescript
{ session_id: string, transcript_path: string, cwd: string, hook_event_name: string, timestamp: string }
```

**Event-specific fields:**
| Event | Additional Fields |
|-------|-------------------|
| `SessionStart` | `source: "startup" \| "resume" \| "clear"` |
| `SessionEnd` | `reason: "exit" \| "clear" \| "logout" \| "prompt_input_exit" \| "other"` |
| `BeforeAgent` | `prompt: string` |
| `AfterAgent` | `prompt: string, prompt_response: string, stop_hook_active: boolean` |
| `BeforeTool` | `tool_name: string, tool_input: Record<string, unknown>, mcp_context?: McpToolContext, original_request_name?: string` |
| `AfterTool` | `tool_name: string, tool_input: Record<string, unknown>, tool_response: Record<string, unknown>, mcp_context?: McpToolContext` |
| `PreCompress` | `trigger: "auto" \| "manual"` |
| `Notification` | `notification_type: "ToolPermission", message: string, details: Record<string, unknown>` |

**Output (all hooks can return):**
```typescript
{ continue?: boolean, stopReason?: string, suppressOutput?: boolean, systemMessage?: string, decision?: "allow" | "deny" | "block" | "approve" | "ask", reason?: string, hookSpecificOutput?: Record<string, unknown> }
```

**Advisory (non-blocking) hooks:** SessionStart, SessionEnd, PreCompress, Notification — `continue` and `decision` fields are ignored.

**Environment variables provided:** `GEMINI_PROJECT_DIR`, `GEMINI_SESSION_ID`, `GEMINI_CWD`, `CLAUDE_PROJECT_DIR` (compat alias)

### What to implement

1. **Create Gemini CLI platform adapter** at `src/cli/adapters/gemini-cli.ts`:
   - Normalize Gemini CLI's hook JSON to `NormalizedHookInput`
   - Base fields always present: `session_id`, `transcript_path`, `cwd`, `hook_event_name`, `timestamp`
   - Map per event:
     - `SessionStart`: `source` → session init metadata
     - `BeforeAgent`: `prompt` → user prompt text
     - `AfterAgent`: `prompt` + `prompt_response` → full conversation turn
     - `AfterTool`: `tool_name` + `tool_input` + `tool_response` → observation
     - `PreCompress`: `trigger` → summary trigger
     - `SessionEnd`: `reason` → session finalization

2. **Create Gemini CLI hooks installer** at `src/services/integrations/GeminiCliHooksInstaller.ts`:
   - Write hooks to `~/.gemini/settings.json` under the `hooks` key
   - Must **merge** with existing settings (read → parse → deep merge → write)
   - Hook config format (verified against official docs):
     ```json
     {
       "hooks": {
         "AfterTool": [{
           "matcher": "*",
           "hooks": [{ "name": "claude-mem", "type": "command", "command": "<path-to-hook-script>", "timeout": 5000 }]
         }]
       }
     }
     ```
   - Note: `matcher` uses regex for tool events, exact string for lifecycle events. `"*"` or `""` matches all.
   - Hook groups support `sequential: boolean` (default false = parallel execution)
   - Security: Project-level hooks are fingerprinted — if name/command changes, user is warned
   - Context injection via `~/.gemini/GEMINI.md` (append claude-mem section with `<claude-mem-context>` tags, same pattern as CLAUDE.md)
   - Settings hierarchy: project `.gemini/settings.json` > user `~/.gemini/settings.json` > system `/etc/gemini-cli/settings.json`

3. **Register `gemini-cli` in `getPlatformAdapter()`** at `src/cli/adapters/index.ts`

4. **Add Gemini CLI to installer IDE selection**

### Verification

- `npx claude-mem install --ide gemini-cli` merges hooks into `~/.gemini/settings.json`
- Gemini CLI sessions are captured by the worker
- `AfterTool` events produce observations with correct `tool_name`, `tool_input`, `tool_response`
- `GEMINI.md` gets claude-mem context section
- Existing Gemini CLI settings are preserved (merge, not overwrite)
- Verify `session_id` from base input is used for session tracking

### Anti-patterns

- Do NOT overwrite `~/.gemini/settings.json` — must deep merge
- Do NOT map all 11 events — the 6 skipped events would produce noise, not signal
- Do NOT use `type: "runtime"` — that's for internal extensions only; use `type: "command"`
- Advisory hooks (SessionStart, SessionEnd, PreCompress, Notification) cannot block — don't set `decision` or `continue` fields on them

---

## Phase 4: OpenCode Integration (Tier 1 — Plugin-Based)

**Why next**: 110k stars, richest plugin ecosystem. OpenCode plugins are JS/TS modules auto-loaded from plugin directories. OpenCode also has a Claude Code compatibility fallback (reads `~/.claude/CLAUDE.md` if no global `AGENTS.md` exists, controllable via `OPENCODE_DISABLE_CLAUDE_CODE_PROMPT=1`).

### Verified Plugin API (from `packages/plugin/src/index.ts`)

**Plugin signature:**
```typescript
import { type Plugin, tool } from "@opencode-ai/plugin"

export const ClaudeMemPlugin: Plugin = async (ctx) => {
  // ctx: { client, project, directory, worktree, serverUrl, $ }
  return { /* hooks object */ }
}
```

**PluginInput type (6 properties, not 4):**
```typescript
type PluginInput = {
  client: ReturnType<typeof createOpencodeClient>  // OpenCode SDK client
  project: Project                                   // Current project info
  directory: string                                  // Current working directory
  worktree: string                                   // Git worktree path
  serverUrl: URL                                     // Server URL
  $: BunShell                                        // Bun shell API
}
```

**Two hook mechanisms (important distinction):**

1. **Direct interceptor hooks** — keys on the returned `Hooks` object, receive `(input, output)` allowing mutation:
   - `tool.execute.before`: `(input: { tool, sessionID, callID }, output: { args })`
   - `tool.execute.after`: `(input: { tool, sessionID, callID, args }, output: { title, output, metadata })`
   - `shell.env`, `chat.message`, `chat.params`, `chat.headers`, `permission.ask`, `command.execute.before`
   - Experimental: `experimental.session.compacting`, `experimental.chat.messages.transform`, `experimental.chat.system.transform`

2. **Bus event catch-all** — generic `event` hook, receives `{ event }` where `event.type` is the event name:
   - `session.created`, `session.compacted`, `session.deleted`, `session.idle`, `session.error`, `session.status`, `session.updated`, `session.diff`
   - `message.updated`, `message.part.updated`, `message.part.removed`, `message.removed`
   - `file.edited`, `file.watcher.updated`
   - `command.executed`, `todo.updated`, `installation.updated`, `server.connected`
   - `permission.asked`, `permission.replied`
   - `lsp.client.diagnostics`, `lsp.updated`
   - `tui.prompt.append`, `tui.command.execute`, `tui.toast.show`
   - Total: **27 bus events** across **12 categories**

**Custom tool registration (CORRECTED — name is the key, not positional arg):**
```typescript
return {
  tool: {
    claude_mem_search: tool({
      description: "Search claude-mem memory database",
      args: { query: tool.schema.string() },
      async execute(args, context) {
        // context: { sessionID, messageID, agent, directory, worktree, abort, metadata, ask }
        const response = await fetch(`http://localhost:37777/api/search?q=${encodeURIComponent(args.query)}`)
        return await response.text()
      },
    }),
  },
}
```

### What to implement

1. **Create OpenCode plugin** at `src/integrations/opencode-plugin/index.ts`:
   - Export a `Plugin` function receiving full `PluginInput` context
   - Use **direct interceptor** `tool.execute.after` for tool observation capture (gives `tool`, `args`, `output`)
   - Use **bus event catch-all** `event` for session lifecycle:

   | Mechanism | Event | Map to claude-mem |
   |-----------|-------|-------------------|
   | interceptor | `tool.execute.after` | `observation` (tool name + args + output) |
   | bus event | `session.created` | `session-init` |
   | bus event | `message.updated` | `observation` (assistant messages) |
   | bus event | `session.compacted` | `summary` |
   | bus event | `file.edited` | `observation` (file changes) |
   | bus event | `session.deleted` | `session-end` |

   - Register `claude_mem_search` custom tool using correct `tool({ description, args, execute })` API
   - Hit `localhost:37777` API endpoints from the plugin

2. **Build the plugin** in the esbuild pipeline → `dist/opencode-plugin/index.js`

3. **Create OpenCode setup in installer** (two options, prefer file-based):
   - **Option A (file-based):** Copy plugin to `~/.config/opencode/plugins/claude-mem.ts` (auto-loaded at startup)
   - **Option B (npm-based):** Add to `~/.config/opencode/opencode.json` under `"plugin"` array: `["claude-mem"]`
   - Config also supports JSONC (`opencode.jsonc`) and legacy `config.json`
   - Context injection: Append to `~/.config/opencode/AGENTS.md` (or create it) with `<claude-mem-context>` tags
   - Additional context via `"instructions"` config key (supports file paths, globs, remote URLs)

4. **Add OpenCode to installer IDE selection**

### OpenCode Verification

- `npx claude-mem install --ide opencode` registers the plugin (file or npm)
- OpenCode loads the plugin on next session
- `tool.execute.after` interceptor produces observations with `tool`, `args`, `output`
- Bus events (`session.created`, `session.deleted`) handle session lifecycle
- `claude_mem_search` custom tool works in OpenCode sessions
- Context is injected via AGENTS.md

### OpenCode Anti-patterns

- Do NOT try to use OpenCode's `session.diff` for full capture — it's a summary diff, not raw data
- Do NOT use `tool('name', schema, handler)` — wrong signature. Name is the key in the `tool:{}` map
- Do NOT assume bus events have the same `(input, output)` mutation pattern — they only receive `{ event }`
- OpenCode plugins run in Bun — the plugin CAN use Bun APIs (unlike the npx CLI itself)
- Do NOT hardcode `~/.config/opencode/` — respect `OPENCODE_CONFIG_DIR` env var if set

---

## Phase 5: Windsurf Integration (Tier 1 — Hook-Based)

**Why next**: 11 Cascade hooks, ~1M users. Hook architecture uses JSON stdin with a consistent envelope format.

### Verified Windsurf Hook Events (from docs.windsurf.com/windsurf/cascade/hooks)

**Naming pattern**: `pre_`/`post_` prefix + 5 action categories, plus 2 standalone post-only events.

| Event | Can Block? | Map to claude-mem | Use |
|-------|-----------|-------------------|-----|
| `pre_user_prompt` | Yes | `session-init` + `context` | Start session, inject context |
| `pre_read_code` | Yes | — | Skip (pre-execution, can block file reads) |
| `post_read_code` | No | — | Skip (too noisy, file reads are frequent) |
| `pre_write_code` | Yes | — | Skip (pre-execution, can block writes) |
| `post_write_code` | No | `observation` | Code generation |
| `pre_run_command` | Yes | — | Skip (pre-execution, can block commands) |
| `post_run_command` | No | `observation` | Shell command execution |
| `pre_mcp_tool_use` | Yes | — | Skip (pre-execution, can block MCP calls) |
| `post_mcp_tool_use` | No | `observation` | MCP tool results |
| `post_cascade_response` | No | `observation` | Full AI response |
| `post_setup_worktree` | No | — | Skip (informational) |

**Mapped**: 5 of 11 events (all post-action). **Skipped**: 4 pre-hooks (blocking-capable, pre-execution) + 2 low-value post-hooks.

### Verified Stdin Payload Schema

**Common envelope (all hooks):**
```json
{
  "agent_action_name": "string",
  "trajectory_id": "string",
  "execution_id": "string",
  "timestamp": "ISO 8601 string",
  "tool_info": { /* event-specific payload */ }
}
```

**Event-specific `tool_info` payloads:**

| Event | `tool_info` fields |
|-------|-------------------|
| `pre_user_prompt` | `{ user_prompt: string }` |
| `pre_read_code` / `post_read_code` | `{ file_path: string }` |
| `pre_write_code` / `post_write_code` | `{ file_path: string, edits: [{ old_string: string, new_string: string }] }` |
| `pre_run_command` / `post_run_command` | `{ command_line: string, cwd: string }` |
| `pre_mcp_tool_use` | `{ mcp_server_name: string, mcp_tool_name: string, mcp_tool_arguments: {} }` |
| `post_mcp_tool_use` | `{ mcp_server_name: string, mcp_tool_name: string, mcp_tool_arguments: {}, mcp_result: string }` |
| `post_cascade_response` | `{ response: string }` (markdown) |
| `post_setup_worktree` | `{ worktree_path: string, root_workspace_path: string }` |

**Exit codes:** `0` = success, `2` = block (pre-hooks only; stderr shown to agent), any other = non-blocking warning.

### What to implement

1. **Create Windsurf platform adapter** at `src/cli/adapters/windsurf.ts`:
   - Normalize Windsurf's hook input format to `NormalizedHookInput`
   - Common envelope: `agent_action_name`, `trajectory_id`, `execution_id`, `timestamp`, `tool_info`
   - Map: `trajectory_id` → `sessionId`, `tool_info` fields per event type
   - For `post_write_code`: `tool_info.file_path` + `tool_info.edits` → file change observation
   - For `post_run_command`: `tool_info.command_line` + `tool_info.cwd` → command observation
   - For `post_mcp_tool_use`: `tool_info.mcp_tool_name` + `tool_info.mcp_tool_arguments` + `tool_info.mcp_result` → tool observation
   - For `post_cascade_response`: `tool_info.response` → full AI response observation

2. **Create Windsurf hooks installer** at `src/services/integrations/WindsurfHooksInstaller.ts`:
   - Write hooks to `~/.codeium/windsurf/hooks.json` (user-level, for global coverage)
   - Per-workspace override at `.windsurf/hooks.json` if user chooses workspace-level install
   - Config format (verified):
     ```json
     {
       "hooks": {
         "post_write_code": [{
           "command": "<path-to-hook-script>",
           "show_output": false,
           "working_directory": "<optional>"
         }]
       }
     }
     ```
   - Note: Tilde expansion (`~`) is NOT supported in `working_directory` — use absolute paths
   - Merge order: cloud → system → user → workspace (all hooks at all levels execute)
   - Context injection via `.windsurf/rules/claude-mem-context.md` (workspace-level; Windsurf rules are workspace-scoped)
   - Rule limits: 6,000 chars per file, 12,000 chars total across all rules

3. **Register `windsurf` in `getPlatformAdapter()`** at `src/cli/adapters/index.ts`

4. **Add Windsurf to installer IDE selection**

### Windsurf Verification

- `npx claude-mem install --ide windsurf` creates hooks config at `~/.codeium/windsurf/hooks.json`
- Windsurf sessions are captured by the worker via post-action hooks
- `trajectory_id` is used as session identifier
- Context is injected via `.windsurf/rules/claude-mem-context.md` (under 6K char limit)
- Existing hooks.json is preserved (merge, not overwrite)

### Windsurf Anti-patterns

- Do NOT use fabricated event names (`post_search_code`, `post_lint_code`, `on_error`, `pre_tool_execution`) — they don't exist
- Do NOT assume Windsurf's stdin JSON matches Claude Code's — it uses `tool_info` envelope, not flat fields
- Do NOT use tilde (`~`) in `working_directory` — not supported, use absolute paths
- Do NOT exceed 6K chars in the context rule file — Windsurf truncates beyond that
- Pre-hooks can block actions (exit 2) — only use post-hooks for observation capture

---

## Phase 6: Codex CLI Integration (Tier 1 — Hook + Transcript)

### Dedup strategy

Codex has both a `notify` hook (real-time) and transcript files (complete history). Use **transcript watching only** — it's more complete and avoids the complexity of dual capture paths. The `notify` hook is a simpler mechanism that doesn't provide enough granularity to justify maintaining two integration paths. If transcript watching proves insufficient, add the notify hook later.

### What to implement

1. **Create Codex transcript schema** — the sample in `src/services/transcripts/config.ts` is already production-quality. Verify against current Codex CLI JSONL format and update if needed.

2. **Create Codex setup in installer**:
   - Write transcript-watch config to `~/.claude-mem/transcript-watch.json`
   - Set up watch for `~/.codex/sessions/**/*.jsonl` using existing CODEX_SAMPLE_SCHEMA
   - Context injection via `.codex/AGENTS.md` (Codex reads this natively)
   - Must merge with existing `config.toml` if it exists (read → parse → merge → write)

3. **Add Codex CLI to installer IDE selection**

### Verification

- `npx claude-mem install --ide codex` creates transcript watch config
- Codex sessions appear in claude-mem database
- `AGENTS.md` updated with context after sessions
- Existing `config.toml` is preserved

---

## Phase 7: OpenClaw Integration (Tier 1 — Plugin-Based)

**Plugin is already fully built** at `openclaw/src/index.ts` (~1000 lines). Has event hooks, SSE observation feed, MEMORY.md sync, slash commands. Only wiring into the installer is needed.

### What to implement

1. **Wire OpenClaw into the npx installer**:
   - Detect `~/.openclaw/` directory
   - Copy pre-built plugin from `openclaw/dist/` (built in Phase 2) to OpenClaw plugins location
   - Register in `~/.openclaw/openclaw.json` under `plugins.claude-mem`
   - Configure worker port, project name, syncMemoryFile
   - Optionally prompt for observation feed setup (channel type + target ID)

2. **Add OpenClaw to IDE selection TUI** with hint about messaging channel support

### Verification

- `npx claude-mem install --ide openclaw` registers the plugin
- OpenClaw gateway loads the plugin on restart
- Observations are recorded from OpenClaw sessions
- MEMORY.md syncs to agent workspaces

### Anti-patterns

- Do NOT rebuild the OpenClaw plugin from source at install time — it ships pre-built from Phase 2
- Do NOT modify the plugin's event handling — it's battle-tested

---

## Phase 8: MCP-Based Integrations (Tier 2)

**These get the MCP server for free** — it already exists at `plugin/scripts/mcp-server.cjs`. The installer just needs to write the right config files per IDE.

MCP-only integrations provide: search tools + context injection. They do NOT capture transcripts or tool usage in real-time.

### What to implement

1. **Copilot CLI MCP setup**:
   - Write MCP config to `~/.copilot/config` (merge, not overwrite)
   - Context injection: `.github/copilot-instructions.md`
   - Detection: `copilot` command in PATH

2. **Antigravity MCP setup**:
   - Write MCP config to `~/.gemini/antigravity/mcp_config.json` (merge, not overwrite)
   - Context injection: `~/.gemini/GEMINI.md` (shared with Gemini CLI) and/or `.agent/rules/claude-mem-context.md`
   - Detection: `~/.gemini/antigravity/` exists
   - Note: Antigravity has NO hook system — MCP is the only integration path

3. **Goose MCP setup**:
   - Write MCP config to `~/.config/goose/config.yaml` (YAML merge — use a lightweight YAML parser or write the block manually if config doesn't exist)
   - Detection: `~/.config/goose/` exists OR `goose` in PATH
   - Note: Goose co-developed MCP with Anthropic, so MCP support is excellent

4. **Crush MCP setup**:
   - Write MCP config to Crush's JSON config
   - Detection: `crush` in PATH

5. **Roo Code MCP setup**:
   - Write MCP config to `.roo/` or workspace settings
   - Context injection: `.roo/rules/claude-mem-context.md`
   - Detection: Check for VS Code extension directory containing `roo-code`

6. **Warp MCP setup**:
   - Warp uses `WARP.md` in project root for context injection (similar to CLAUDE.md)
   - MCP servers configured via Warp Drive UI, but also via config files
   - Detection: `~/.warp/` exists OR `warp` in PATH
   - Note: Warp is a terminal replacement (~26k stars), not just a CLI tool — multi-agent orchestration with management UI

7. **For each**: Add to installer IDE detection and selection

### Config merging strategy

JSON configs: Read → parse → deep merge → write back. YAML configs (Goose): If file exists, read and append the MCP block. If not, create from template. Avoid pulling in a full YAML parser library — write the MCP block as a string append with proper indentation if the format is predictable.

### Verification

- Each IDE can search claude-mem via MCP tools
- Context files are written to IDE-specific locations
- Existing configs are preserved

### Anti-patterns

- MCP-only integrations do NOT capture transcripts — don't claim "full integration"
- Do NOT overwrite existing config files — always merge
- Do NOT add a heavy YAML parser dependency for one integration

---

## Phase 9: Remove Old Installer

This is a **full replacement**, not a deprecation.

### What to implement

1. Remove `claude-mem-installer` npm package (unpublish or mark deprecated with message pointing to `npx claude-mem`)
2. Update `install/public/install.sh` → redirect to `npx claude-mem`
3. Remove `installer/` directory from the repository (it's replaced by `src/npx-cli/`)
4. Update docs site to reflect the new install command
5. Update README.md install instructions

---

## Phase 10: Final Verification

### All platforms (macOS, Linux, Windows)

1. `npm run build` succeeds, produces `dist/cli/index.js` and `openclaw/dist/index.js`
2. `node dist/cli/index.js install` works clean (no prior install)
3. Auto-detects installed IDEs correctly per platform
4. `npx claude-mem start/stop/status/search` all work
5. `npx claude-mem update` updates correctly
6. `npx claude-mem uninstall` cleans up all IDE configs
7. `npx claude-mem version` prints version
8. `npx claude-mem start` before install shows helpful error
9. No Bun dependency at install time

### Per-integration verification

| Integration | Type | Captures Sessions | Search via MCP | Context Injection |
|-------------|------|-------------------|----------------|-------------------|
| Claude Code | Plugin | Yes (hooks) | Yes | CLAUDE.md |
| Gemini CLI | Hooks | Yes (AfterTool, AfterAgent) | Yes (via hook) | GEMINI.md |
| OpenCode | Plugin | Yes (tool.execute.after, message.updated) | Yes (custom tool) | AGENTS.md / rules |
| Windsurf | Hooks | Yes (post_cascade_response, etc.) | Yes (via hook) | .windsurf/rules/ |
| Codex CLI | Transcript | Yes (JSONL watcher) | No (passive only) | .codex/AGENTS.md |
| OpenClaw | Plugin | Yes (event hooks) | Yes (slash commands) | MEMORY.md |
| Copilot CLI | MCP | No | Yes | copilot-instructions.md |
| Antigravity | MCP | No | Yes | .agent/rules/ |
| Goose | MCP | No | Yes | MCP context |
| Crush | MCP | No | Yes | Skills |
| Roo Code | MCP | No | Yes | .roo/rules/ |
| Warp | MCP | No | Yes | WARP.md |

---

## Priority Order & Impact

| Phase | IDE/Tool | Integration Type | Stars/Users | Effort |
|-------|----------|-----------------|-------------|--------|
| 1-2 | (infrastructure) | npx CLI + build pipeline | All users | Medium |
| 3 | Gemini CLI | Hooks (Tier 1) | ~95k stars | Medium (near-identical to Claude Code) |
| 4 | OpenCode | Plugin (Tier 1) | ~110k stars | Medium (rich plugin SDK) |
| 5 | Windsurf | Hooks (Tier 1) | ~1M users | Medium |
| 6 | Codex CLI | Transcript (Tier 3) | Growing (OpenAI) | Low (schema already exists) |
| 7 | OpenClaw | Plugin (Tier 1) — pre-built | ~196k stars | Low (wire into installer) |
| 8 | Copilot CLI, Antigravity, Goose, Crush, Warp, Roo Code | MCP (Tier 2) | 20M+ combined | Low per IDE |
| 9 | (remove old installer) | — | — | Low |
| 10 | (final verification) | — | — | Low |

## Out of Scope

- **Removing Bun as runtime dependency**: Worker still requires Bun for `bun:sqlite`. Runtime commands delegate to Bun; install commands don't need it.
- **JetBrains plugin**: Requires Kotlin/Java development — different ecosystem entirely.
- **Zed extension**: WASM sandbox limits feasibility.
- **Neovim/Emacs plugins**: Niche audiences, complex plugin ecosystems (Lua/Elisp). Could be added later via MCP (gptel supports it).
- **Amazon Q / Kiro**: Amazon Q Developer CLI has been sunsetted in favor of Kiro (proprietary, no public extensibility API yet). Revisit when Kiro opens up.
- **Aider**: Niche audience, writes Markdown transcripts (not JSONL), would require a markdown parser mode in the watcher. Add if demand materializes.
- **Continue.dev**: Small user base relative to other MCP tools. Can be added as a Tier 2 MCP integration later if requested.
- **Toad / Qwen Code / Oh-my-pi**: Too early-stage or too niche. Monitor for growth.
- **OpenClaw plugin development**: The plugin is already complete. Only installer wiring is in scope.


================================================
FILE: .translation-cache.json
================================================
{
  "sourceHash": "9ab0d799179c66f9",
  "lastUpdated": "2025-12-12T07:42:03.489Z",
  "translations": {
    "zh": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:06:55.026Z",
      "costUsd": 0.12256679999999998
    },
    "ja": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:06:55.026Z",
      "costUsd": 0.12973164999999998
    },
    "pt-br": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:06:55.026Z",
      "costUsd": 0.11508539999999999
    },
    "ko": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:06:55.026Z",
      "costUsd": 0.13952664999999997
    },
    "es": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:06:55.026Z",
      "costUsd": 0.12530165
    },
    "de": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:06:55.026Z",
      "costUsd": 0.12232164999999998
    },
    "fr": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:06:55.026Z",
      "costUsd": 0.11906665
    },
    "he": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:25:00.076Z",
      "costUsd": 0.151329
    },
    "ar": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:25:00.076Z",
      "costUsd": 0.151952
    },
    "ru": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:25:00.076Z",
      "costUsd": 0.13418499999999997
    },
    "pl": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:25:00.076Z",
      "costUsd": 0.13196799999999997
    },
    "cs": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:25:00.076Z",
      "costUsd": 0.12714599999999998
    },
    "nl": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:25:00.076Z",
      "costUsd": 0.118389
    },
    "tr": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:25:00.076Z",
      "costUsd": 0.13991199999999998
    },
    "uk": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:25:00.076Z",
      "costUsd": 0.13786
    },
    "vi": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:42:03.489Z",
      "costUsd": 0.15467299999999998
    },
    "id": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:42:03.489Z",
      "costUsd": 0.185581
    },
    "th": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:42:03.489Z",
      "costUsd": 0.177859
    },
    "hi": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:42:03.489Z",
      "costUsd": 0.17412700000000003
    },
    "bn": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:42:03.489Z",
      "costUsd": 0.202735
    },
    "ro": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:42:03.489Z",
      "costUsd": 0.12212875
    },
    "sv": {
      "hash": "9ab0d799179c66f9",
      "translatedAt": "2025-12-12T07:42:03.489Z",
      "costUsd": 0.12143675000000001
    }
  }
}

================================================
FILE: CHANGELOG.md
================================================
# Changelog

All notable changes to claude-mem.

## [v10.6.3] - 2026-03-29

## v10.6.3 — Critical Patch Release

### Bug Fixes

- **Fix MCP server crash**: Removed erroneous `import.meta.url` ESM-compat banner from CJS files that caused Node.js startup failures
- **Fix 7 critical bugs** affecting all non-dev-machine users and Windows:
  - Hook registration paths corrected for plugin distribution
  - Worker service spawn handling hardened for Windows
  - Environment sanitization for cross-platform compatibility
  - ProcessManager Windows spawn catch block improvements
  - SessionEnd inline hook exemption in regression tests
  - `summarize.ts` warning log now includes `sessionId` for triage
- **CodeRabbit review feedback** addressed from PR #1518

### Improvements

- **Gemini CLI integration**: Strip ANSI color codes from timeline display, provide markdown fallback

### Files Changed

- `plugin/hooks/hooks.json`
- `plugin/scripts/mcp-server.cjs`
- `plugin/scripts/worker-service.cjs`
- `scripts/build-hooks.js`
- `src/cli/handlers/summarize.ts`
- `src/services/infrastructure/ProcessManager.ts`
- `src/services/worker-service.ts`
- `src/supervisor/env-sanitizer.ts`
- `tests/infrastructure/plugin-distribution.test.ts`
- `tests/supervisor/env-sanitizer.test.ts`

## [v10.6.2] - 2026-03-21

## fix: Activity spinner stuck spinning forever

The viewer UI activity spinner would spin indefinitely because `isAnySessionProcessing()` queried all pending/processing messages in the database globally — including orphaned messages from dead sessions that no generator would ever process. These orphans caused `isProcessing=true` forever.

### Changes

- Scoped `isAnySessionProcessing()` and `hasPendingMessages()` to only check sessions in the active in-memory Map, so orphaned DB messages no longer affect the spinner
- Added `terminateSession()` method enforcing a restart-or-terminate invariant — every generator exit must either restart or fully clean up
- Fixed 3 zombie paths in the `.finally()` handler that previously left sessions alive in memory with no generator running
- Fixed idle-timeout race condition where fresh messages arriving between idle abort and cleanup could be silently dropped
- Removed redundant bare `isProcessing: true` broadcast and eliminated double-iteration in `broadcastProcessingStatus()`
- Replaced inline `require()` with proper accessor via `sessionManager.getPendingMessageStore()`
- Added 8 regression tests for session termination invariant

## [v10.6.1] - 2026-03-18

### New Features
- **Timeline Report Skill** — New `/timeline-report` skill generates narrative "Journey Into [Project]" reports from claude-mem's development history with token-aware economics
- **Git Worktree Detection** — Timeline report automatically detects git worktrees and uses parent project as data source
- **Compressed Context Output** — Markdown context injection compressed ~53% (tables → compact flat lines), reducing token overhead in session starts
- **Full Observation Fetch** — Added `full=true` parameter to `/api/context/inject` for fetching all observations

### Improvements
- Split `TimelineRenderer` into separate markdown/color rendering paths
- Fixed timestamp ditto marker leaking across session summary boundaries

### Security
- Removed arbitrary file write vulnerability (`dump_to_file` parameter)

## [v10.6.0] - 2026-03-18

## OpenClaw: System prompt context injection

The OpenClaw plugin no longer writes to `MEMORY.md`. Instead, it injects the observation timeline into each agent's system prompt via the `before_prompt_build` hook using `appendSystemContext`. This keeps `MEMORY.md` under the agent's control for curated long-term memory. Context is cached for 60 seconds per project.

## New `syncMemoryFileExclude` config

Exclude specific agent IDs from automatic context injection (e.g., `["snarf", "debugger"]`). Observations are still recorded for excluded agents — only the context injection is skipped.

## Fix: UI settings now preserve falsy values

The viewer settings hook used `||` instead of `??`, which silently replaced backend values like `'0'`, `'false'`, and `''` with UI defaults. Fixed with nullish coalescing. Frontend defaults now aligned with backend `SettingsDefaultsManager`.

## Documentation

- Updated `openclaw-integration.mdx` and `openclaw/SKILL.md` to reflect system prompt injection behavior
- Fixed "prompt injection" → "context injection" terminology to avoid confusion with the OWASP security term

## [v10.5.6] - 2026-03-16

## Patch: Process Supervisor Hardening & Logging Cleanup

### Fixes
- **Downgrade HTTP request/response logging from INFO to DEBUG** — eliminates noisy per-request log spam from the viewer UI polling
- **Fix `isPidAlive(0)` returning true** — PID 0 is the kernel scheduler, not a valid child process
- **Fix signal handler race condition** — added `shutdownInitiated` flag to prevent duplicate shutdown cascades when signals arrive before `stopPromise` is set
- **Remove unused `dataDir` parameter** from `ShutdownCascadeOptions`
- **Export and reuse env sanitizer constants** — `Server.ts` now imports `ENV_PREFIXES`/`ENV_EXACT_MATCHES` from `env-sanitizer.ts` instead of duplicating them
- **Rename `zombiePidFiles` to `deadProcessPids`** — now returns actual PID array instead of a boolean
- **Use `buildWorkerUrl` helper** in `workerHttpRequest` instead of inline URL construction
- **Remove unused `getWorkerPort` imports** from observation and session-init handlers
- **Upgrade `reapSession` failure log** from debug to warn level
- **Clean up `.gitignore`** — remove stale `~*/`, `http*/`, `https*/` patterns and duplicate `datasets/` entry

### Tests
- Rewrote supervisor index tests to use temp directories instead of relying on real `~/.claude-mem/worker.pid`
- Added deterministic test cases for missing, invalid, stale, and alive PID file states
- Removed unused `dataDir` from shutdown test fixtures

## [v10.5.5] - 2026-03-09

### Bug Fix

- **Fixed empty context queries after mode switching**: Switching from a non-code mode (e.g., law-study) back to code mode left stale observation type/concept filters in `settings.json`, causing all context queries to return empty results. All modes now read types/concepts from their mode JSON definition uniformly.

### Cleanup

- Removed dead `CLAUDE_MEM_CONTEXT_OBSERVATION_TYPES` and `CLAUDE_MEM_CONTEXT_OBSERVATION_CONCEPTS` settings constants
- Deleted `src/constants/observation-metadata.ts` (no longer needed)
- Removed observation type/concept filter UI controls from the viewer's Context Settings modal

## [v10.5.4] - 2026-03-09

## Bug Fixes

- **fix: restore modes to correct location** — All modes (`code`, code language variants, `email-investigation`) were erroneously moved from `plugin/modes/` to `plugin/hooks/modes/` during the v10.5.3 release, breaking mode loading. This patch restores them to `plugin/modes/` where they belong.

## [v10.5.3] - 2026-03-09

## What's New

### Law Study Mode

Adds `law-study` — a purpose-built claude-mem mode for law students.

**Observation Types:**
- **Case Holding** — 2-3 sentence brief with extracted legal rule
- **Issue Pattern** — exam trigger or fact pattern that signals a legal issue
- **Prof Framework** — professor's analytical lens and emphasis for a topic
- **Doctrine / Rule** — legal test or standard synthesized from cases/statutes
- **Argument Structure** — legal argument or counter-argument worked through analytically
- **Cross-Case Connection** — insight linking cases or doctrines to reveal a deeper principle

**Concepts (cross-cutting tags):**
`exam-relevant` · `minority-position` · `gotcha` · `unsettled-law` · `policy-rationale` · `course-theme`

**Chill Variant** — `law-study--chill` records only high-signal items: issue patterns, gotchas, and professor frameworks. Skips routine case holdings unless the result is counterintuitive.

**CLAUDE.md Template** — `law-study-CLAUDE.md` is a drop-in template for any law study project directory. It configures Claude as a Socratic legal study partner: precise case briefs, critical document analysis, issue spotting, and doctrine synthesis — without writing exam answers for the student.

Activate with: `/mode law-study` or `/mode law-study--chill`

## [v10.5.2] - 2026-02-26

## Smart Explore Benchmark Docs & Skill Update

### Documentation
- Published smart-explore benchmark report to public docs — full A/B comparison with methodology, raw data tables, quality assessment, and decision framework
- Added benchmark report to docs.json navigation under Best Practices

### Smart Explore Skill
- Updated token economics with benchmark-accurate data (11-18x savings on exploration, 4-8x on file understanding)
- Added "map first" core principle as decision heuristic for tool selection
- Added AST completeness guarantee to smart_unfold documentation (never truncates, unlike Explore agents)
- Added Explore agent escalation guidance for multi-file synthesis tasks
- Updated smart_unfold token range from ~1-7k to ~400-2,100 based on measurements
- Updated Explore agent token range from ~20-40k to ~39-59k based on measurements

## [v10.5.1] - 2026-02-26

### Bug Fix

- Restored hooks.json to pre-smart-explore configuration (re-adds Setup hook, separate worker start command, PostToolUse matcher)

## [v10.5.0] - 2026-02-26

## Smart Explore: AST-Powered Code Navigation

This release introduces **Smart Explore**, a token-optimized structural code search system built on tree-sitter AST parsing. It applies the same progressive disclosure pattern used in human-readable code outlines — but programmatically, for AI agents.

### Why This Matters

The standard exploration cycle (Glob → Grep → Read) forces agents to consume entire files to understand code structure. A typical 800-line file costs ~12,000 tokens to read. Smart Explore replaces this with a 3-layer progressive disclosure workflow that delivers the same understanding at **6-12x lower token cost**.

### 3 New MCP Tools

- **`smart_search`** — Walks directories, parses all code files via tree-sitter, and returns ranked symbols with signatures and line numbers. Replaces the Glob → Grep discovery cycle in a single call (~2-6k tokens).
- **`smart_outline`** — Returns the complete structural skeleton of a file: all functions, classes, methods, properties, imports (~1-2k tokens vs ~12k for a full Read).
- **`smart_unfold`** — Expands a single symbol to its full source code including JSDoc, decorators, and implementation (~1-7k tokens).

### Token Economics

| Approach | Tokens | Savings |
|----------|--------|---------|
| smart_outline + smart_unfold | ~3,100 | 8x vs Read |
| smart_search (cross-file) | ~2,000-6,000 | 6-12x vs Explore agent |
| Read (full file) | ~12,000+ | baseline |
| Explore agent | ~20,000-40,000 | baseline |

### Language Support

10 languages via tree-sitter grammars: TypeScript, JavaScript, Python, Rust, Go, Java, C, C++, Ruby, PHP.

### Other Changes

- Simplified hooks configuration
- Removed legacy setup.sh script
- Security fix: replaced `execSync` with `execFileSync` to prevent command injection in file path handling

## [v10.4.4] - 2026-02-26

## Fix

- **Remove `save_observation` from MCP tool surface** — This tool was exposed as an MCP tool available to Claude, but it's an internal API-only feature. Removing it from the MCP server prevents unintended tool invocation and keeps the tool surface clean.

## [v10.4.3] - 2026-02-25

## Bug Fixes

- **Fix PostToolUse hook crashes and 5-second latency (#1220)**: Added missing `break` statements to all 7 switch cases in `worker-service.ts` preventing fall-through execution, added `.catch()` on `main()` to handle unhandled promise rejections, and removed redundant `start` commands from hook groups that triggered the 5-second `collectStdin()` timeout
- **Fix CLAUDE_PLUGIN_ROOT fallback for Stop hooks (#1215)**: Added POSIX shell-level `CLAUDE_PLUGIN_ROOT` fallback in `hooks.json` for environments where the variable isn't injected, added script-level self-resolution via `import.meta.url` in `bun-runner.js`, and regression test added in `plugin-distribution.test.ts`

## Maintenance

- Synced all version files (plugin.json was stuck at 10.4.0)

## [v10.4.2] - 2026-02-25

## Bug Fixes

- **Fix PostToolUse hook crashes and 5-second latency (#1220)**: Added missing `break` statements to all 7 switch cases in `worker-service.ts` preventing fall-through execution, added `.catch()` on `main()` to handle unhandled promise rejections, and removed redundant `start` commands from hook groups that triggered the 5-second `collectStdin()` timeout
- **Fix CLAUDE_PLUGIN_ROOT fallback for Stop hooks (#1215)**: Added POSIX shell-level `CLAUDE_PLUGIN_ROOT` fallback in `hooks.json` for environments where the variable isn't injected, added script-level self-resolution via `import.meta.url` in `bun-runner.js`, and regression test added in `plugin-distribution.test.ts`
- **Sync plugin.json version**: Fixed `plugin.json` being stuck at 10.4.0 while other version files were at 10.4.1

## [v10.4.1] - 2026-02-24

### Refactor
- **Skills Conversion**: Converted `/make-plan` and `/do` commands into first-class skills in `plugin/skills/`.
- **Organization**: Centralized planning and execution instructions alongside `mem-search`.
- **Compatibility**: Added symlinks for `openclaw/skills/` to ensure seamless integration with OpenClaw.

### Chore
- **Version Bump**: Aligned all package and plugin manifests to v10.4.1.

## [v10.4.0] - 2026-02-24

## v10.4.0 — Stability & Platform Hardening

Massive reliability release: 30+ root-cause bug fixes across 10 triage phases, plus new features for agent attribution, Chroma control, and broader platform support.

### New Features

- **Session custom titles** — Agents can now set `custom_title` on sessions for attribution (migration 23, new endpoint)
- **Chroma toggle** — `CLAUDE_MEM_CHROMA_ENABLED` setting allows SQLite-only fallback mode (#707)
- **Plugin disabled state** — Early exit check in all hook entry points when plugin is disabled (#781)
- **Context re-injection guard** — `contextInjected` session flag prevents re-injecting context on every UserPromptSubmit turn (#1079)

### Bug Fixes

#### Data Integrity
- SHA-256 content-hash deduplication on observation INSERT (migration 22 with backfill + index)
- Project name collision fix: `getCurrentProjectName()` now returns `parent/basename`
- Empty project string guard with cwd-derived fallback
- Stuck `isProcessing` reset: pending work older than 5 minutes auto-clears

#### ChromaDB
- Python version pinning in uvx args for both local and remote mode (#1196, #1206, #1208)
- Windows backslash-to-forward-slash path conversion for `--data-dir` (#1199)
- Metadata sanitization: filter null/undefined/empty values in `addDocuments()` (#1183, #1188)
- Transport error auto-reconnect in `callTool()` (#1162)
- Stale transport retry with transparent reconnect (#1131)

#### Hook Lifecycle
- Suppress `process.stderr.write` in `hookCommand()` to prevent diagnostic output showing as error UI (#1181)
- Route all `console.error()` through logger instead of stderr
- Verified all 7 handlers return `suppressOutput: true` (#598, #784)

#### Worker Lifecycle
- PID file mtime guard prevents concurrent restart storms (#1145)
- `getInstalledPluginVersion()` ENOENT/EBUSY handling (#1042)

#### SQLite Migrations
- Schema initialization always creates core tables via `CREATE TABLE IF NOT EXISTS`
- Migrations 5-7 check actual DB state instead of version tracking (fixes version collision between old/new migration systems, #979)
- Crash-safe temp table rebuilds

#### Platform Support
- **Windows**: `cmd.exe /c` uvx spawn, PowerShell `$_` elimination with WQL filtering, `windowsHide: true`, FTS5 runtime probe with fallback (#1190, #1192, #1199, #1024, #1062, #1048, #791)
- **Cursor IDE**: Adapter field fallbacks, tolerant session-init validation (#838, #1049)
- **Codex CLI**: `session_id` fallbacks, unknown platform tolerance, undefined guard (#744)

#### API & Infrastructure
- `/api/logs` OOM fix: tail-read replaces full-file `readFileSync` (64KB expanding chunks, 10MB cap, #1203)
- CORS: explicit methods and allowedHeaders (#1029)
- MCP type coercion for batch endpoints: string-to-array for `ids` and `memorySessionIds`
- Defensive observation error handling returns 200 on recoverable errors instead of 500
- `.git/` directory write guard on all 4 CLAUDE.md/AGENTS.md write sites (#1165)

#### Stale AbortController Fix
- `lastGeneratorActivity` timestamp tracking with 30s timeout (#1099)
- Stale generator detection + abort + restart in `ensureGeneratorRunning`
- `AbortSignal.timeout(30000)` in `deleteSession` prevents indefinite hang

### Installation
- `resolveRoot()` replaces hardcoded marketplace path using `CLAUDE_PLUGIN_ROOT` env var (#1128, #1166)
- `installCLI()` path correction and `verifyCriticalModules()` post-install check
- Build-time distribution verification for skills, hooks, and plugin manifest (#1187)

### Testing
- 50+ new tests across hook lifecycle, context re-injection, plugin distribution, migration runner, data integrity, stale abort controller, logs tail-read, CORS, MCP type coercion, and smart-install
- 68 files changed, ~4200 insertions, ~900 deletions

## [v10.3.3] - 2026-02-23

### Bug Fixes

- Fixed session context footer to reference the claude-mem skill instead of MCP search tools for accessing memories

## [v10.3.2] - 2026-02-23

## Bug Fixes

- **Worker startup readiness**: Worker startup hook now waits for full DB/search readiness before proceeding, fixing the race condition where hooks would fire before the worker was initialized on first start (#1210)
- **MCP tool naming**: Renamed `save_memory` to `save_observation` for consistency with the observation-based data model (#1210)
- **MCP search instructions**: Updated MCP server tool descriptions to accurately reflect the 3-layer search workflow (#1210)
- **Installer hosting**: Serve installer JS from install.cmem.ai instead of GitHub raw URLs for reliability
- **Installer routing**: Added rewrite rule so install.cmem.ai root path correctly serves the install script
- **Installer build**: Added compiled installer dist so CLI installation works out of the box

## [v10.3.1] - 2026-02-19

## Fix: Prevent Duplicate Worker Daemons and Zombie Processes

Three root causes of chroma-mcp timeouts identified and fixed:

### PID-based daemon guard
Exit immediately on startup if PID file points to a live process. Prevents the race condition where hooks firing simultaneously could start multiple daemons before either wrote a PID file.

### Port-based daemon guard
Exit if port 37777 is already bound — runs before WorkerService constructor registers keepalive signal handlers that previously prevented exit on EADDRINUSE.

### Guaranteed process.exit() after HTTP shutdown
HTTP shutdown (POST /api/admin/shutdown) now calls `process.exit(0)` in a `try/finally` block. Previously, zombie workers stayed alive after shutdown, and background tasks reconnected to chroma-mcp, spawning duplicate subprocesses contending for the same data directory.

## [v10.3.0] - 2026-02-18

## Replace WASM Embeddings with Persistent chroma-mcp MCP Connection

### Highlights

- **New: ChromaMcpManager** — Singleton stdio MCP client communicating with chroma-mcp via `uvx`, replacing the previous ChromaServerManager (`npx chroma run` + `chromadb` npm + ONNX/WASM)
- **Eliminates native binary issues** — No more segfaults, WASM embedding failures, or cross-platform install headaches
- **Graceful subprocess lifecycle** — Wired into GracefulShutdown for clean teardown; zombie process prevention with kill-on-failure and stale `onclose` handler guards
- **Connection backoff** — 10-second reconnect backoff prevents chroma-mcp spawn storms
- **SQL injection guards** — Added parameterization to ChromaSync ID exclusion queries
- **Simplified ChromaSync** — Reduced complexity by delegating embedding concerns to chroma-mcp

### Breaking Changes

None — backward compatible. ChromaDB data is preserved; only the connection mechanism changed.

### Files Changed

- `src/services/sync/ChromaMcpManager.ts` (new) — MCP client singleton
- `src/services/sync/ChromaServerManager.ts` (deleted) — Old WASM/native approach
- `src/services/sync/ChromaSync.ts` — Simplified to use MCP client
- `src/services/worker-service.ts` — Updated startup sequence
- `src/services/infrastructure/GracefulShutdown.ts` — Subprocess cleanup integration

## [v10.2.6] - 2026-02-18

## Bug Fixes

### Zombie Process Prevention (#1168, #1175)

Observer Claude CLI subprocesses were accumulating as zombies — processes that never exited after their session ended, causing massive resource leaks on long-running systems.

**Root cause:** When observer sessions ended (via idle timeout, abort, or error), the spawned Claude CLI subprocesses were not being reliably killed. The existing `ensureProcessExit()` in `SDKAgent` only covered the happy path; sessions terminated through `SessionRoutes` or `worker-service` bypassed process cleanup entirely.

**Fix — dual-layer approach:**

1. **Immediate cleanup:** Added `ensureProcessExit()` calls to the `finally` blocks in both `SessionRoutes.ts` and `worker-service.ts`, ensuring every session exit path kills its subprocess
2. **Periodic reaping:** Added `reapStaleSessions()` to `SessionManager` — a background interval that scans `~/.claude-mem/observer-sessions/` for stale PID files, verifies the process is still running, and kills any orphans with SIGKILL escalation

This ensures no observer subprocess survives beyond its session lifetime, even in crash scenarios.

## [v10.2.5] - 2026-02-18

### Bug Fixes

- **Self-healing message queue**: Renamed `claimAndDelete` → `claimNextMessage` with atomic self-healing — automatically resets stale processing messages (>60s) back to pending before claiming, eliminating stuck messages from generator crashes without external timers
- **Removed redundant idle-timeout reset**: The `resetStaleProcessingMessages()` call during idle timeout in worker-service was removed (startup reset kept), since the atomic self-healing in `claimNextMessage` now handles recovery inline
- **TypeScript diagnostic fix**: Added `QUEUE` to logger `Component` type

### Tests

- 5 new tests for self-healing behavior (stuck recovery, active protection, atomicity, empty queue, session isolation)
- 1 new integration test for stuck recovery in zombie-prevention suite
- All existing queue tests updated for renamed method

## [v10.2.4] - 2026-02-18

## Chroma Vector DB Backfill Fix

Fixes the Chroma backfill system to correctly sync all SQLite observations into the vector database on worker startup.

### Bug Fixes

- **Backfill all projects on startup** — `backfillAllProjects()` now runs on worker startup, iterating all projects in SQLite and syncing missing observations to Chroma. Previously `ensureBackfilled()` existed but was never called, leaving Chroma with incomplete data after cache clears.

- **Fixed critical collection routing bug** — Backfill now uses the shared `cm__claude-mem` collection (matching how DatabaseManager and SearchManager operate) instead of creating per-project orphan collections that no search path reads from.

- **Hardened collection name sanitization** — Project names with special characters (e.g., "YC Stuff") are sanitized for Chroma's naming constraints, including stripping trailing non-alphanumeric characters.

- **Eliminated shared mutable state** — `ensureBackfilled()` and `getExistingChromaIds()` now accept project as a parameter instead of mutating instance state, keeping a single Chroma connection while avoiding fragile property mutation across iterations.

- **Chroma readiness guard** — Backfill waits for Chroma server readiness before running, preventing spurious error logs when Chroma fails to start.

### Changed Files

- `src/services/sync/ChromaSync.ts` — Core backfill logic, sanitization, parameter passing
- `src/services/worker-service.ts` — Startup backfill trigger + readiness guard
- `src/utils/logger.ts` — Added `CHROMA_SYNC` log component

## [v10.2.3] - 2026-02-17

## Fix Chroma ONNX Model Cache Corruption

Addresses the persistent embedding pipeline failures reported across #1104, #1105, #1110, and subsequent sessions. Three root causes identified and fixed:

### Changes

- **Removed nuclear `bun pm cache rm`** from both `smart-install.js` and `sync-marketplace.cjs`. This was added in v10.2.2 for the now-removed sharp dependency but destroyed all cached packages, breaking the ONNX resolution chain.
- **Added `bun install` in plugin cache directory** after marketplace sync. The cache directory had a `package.json` with `@chroma-core/default-embed` as a dependency but never ran install, so the worker couldn't resolve it at runtime.
- **Moved HuggingFace model cache to `~/.claude-mem/models/`** outside `node_modules`. The ~23MB ONNX model was stored inside `node_modules/@huggingface/transformers/.cache/`, so any reinstall or cache clear corrupted it.
- **Added self-healing retry** for Protobuf parsing failures. If the downloaded model is corrupted, the cache is cleared and re-downloaded automatically on next use.

### Files Changed

- `scripts/smart-install.js` — removed `bun pm cache rm`
- `scripts/sync-marketplace.cjs` — removed `bun pm cache rm`, added `bun install` in cache dir
- `src/services/sync/ChromaSync.ts` — moved model cache, added corruption recovery

## [v10.2.2] - 2026-02-17

## Bug Fixes

- **Removed `node-addon-api` dev dependency** — was only needed for `sharp`, which was already removed in v10.2.1
- **Simplified native module cache clearing** in `smart-install.js` and `sync-marketplace.cjs` — replaced targeted `@img/sharp` directory deletion and lockfile removal with `bun pm cache rm`
- Reduced ~30 lines of brittle file system manipulation to a clean Bun CLI command

## [v10.2.1] - 2026-02-16

## Bug Fixes

- **Bun install & sharp native modules**: Fixed stale native module cache issues on Bun updates, added `node-addon-api` as a dev dependency required by sharp (#1140)
- **PendingMessageStore consolidation**: Deduplicated PendingMessageStore initialization in worker-service; added session-scoped filtering to `resetStaleProcessingMessages` to prevent cross-session message resets (#1140)
- **Gemini empty response handling**: Fixed silent message deletion when Gemini returns empty summary responses — now logs a warning and preserves the original message (#1138)
- **Idle timeout session scoping**: Fixed idle timeout handler to only reset messages for the timed-out session instead of globally resetting all sessions (#1138)
- **Shell injection in sync-marketplace**: Replaced `execSync` with `spawnSync` for rsync calls to eliminate command injection via gitignore patterns (#1138)
- **Sharp cache invalidation**: Added cache clearing for sharp's native bindings when Bun version changes (#1138)
- **Marketplace install**: Switched marketplace sync from npm to bun for package installation consistency (#1140)

## [v10.1.0] - 2026-02-16

## SessionStart System Message & Cleaner Defaults

### New Features

- **SessionStart `systemMessage` support** — Hooks can now display user-visible ANSI-colored messages directly in the CLI via a new `systemMessage` field on `HookResult`. The SessionStart hook uses this to render a colored timeline summary (separate from the markdown context injected for Claude), giving users an at-a-glance view of recent activity every time they start a session.

- **"View Observations Live" link** — Each session start now appends a clickable `http://localhost:{port}` URL so users can jump straight to the live observation viewer.

### Performance

- **Truly parallel context fetching** — The SessionStart handler now uses `Promise.all` to fetch both the markdown context (for Claude) and the ANSI-colored timeline (for user display) simultaneously, eliminating the serial fetch overhead.

### Defaults Changes

- **Cleaner out-of-box experience** — New installs now default to a streamlined context display:
  - Read tokens column: hidden (`CLAUDE_MEM_CONTEXT_SHOW_READ_TOKENS: false`)
  - Work tokens column: hidden (`CLAUDE_MEM_CONTEXT_SHOW_WORK_TOKENS: false`)
  - Savings amount: hidden (`CLAUDE_MEM_CONTEXT_SHOW_SAVINGS_AMOUNT: false`)
  - Full observation expansion: disabled (`CLAUDE_MEM_CONTEXT_FULL_COUNT: 0`)
  - Savings percentage remains visible by default

  Existing users are unaffected — your `~/.claude-mem/settings.json` overrides these defaults.

### Technical Details

- Added `systemMessage?: string` to `HookResult` interface (`src/cli/types.ts`)
- Claude Code adapter now forwards `systemMessage` in hook output (`src/cli/adapters/claude-code.ts`)
- Context handler refactored for parallel fetch with graceful fallback (`src/cli/handlers/context.ts`)
- Default settings tuned in `SettingsDefaultsManager` (`src/shared/SettingsDefaultsManager.ts`)

## [v10.0.8] - 2026-02-16

## Bug Fixes

### Orphaned Subprocess Cleanup
- Add explicit subprocess cleanup after SDK query loop using existing `ProcessRegistry` infrastructure (`getProcessBySession` + `ensureProcessExit`), preventing orphaned Claude subprocesses from accumulating
- Closes #1010, #1089, #1090, #1068

### Chroma Binary Resolution
- Replace `npx chroma run` with absolute binary path resolution via `require.resolve`, falling back to `npx` with explicit `cwd` when the binary isn't found directly
- Closes #1120

### Cross-Platform Embedding Fix
- Remove `@chroma-core/default-embed` which pulled in `onnxruntime` + `sharp` native binaries that fail on many platforms
- Use WASM backend for Chroma embeddings, eliminating native binary compilation issues
- Closes #1104, #1105, #1110

## [v10.0.7] - 2026-02-14

## Chroma HTTP Server Architecture

- **Persistent HTTP server**: Switched from in-process Chroma to a persistent HTTP server managed by the new `ChromaServerManager` for better reliability and performance
- **Local embeddings**: Added `DefaultEmbeddingFunction` for local vector embeddings — no external API required
- **Pinned chromadb v3.2.2**: Fixed compatibility with v2 API heartbeat endpoint
- **Server lifecycle improvements**: Addressed PR review feedback for proper start/stop/health check handling

## Bug Fixes

- Fixed SDK spawn failures and sharp native binary crashes
- Added `plugin.json` to root `.claude-plugin` directory for proper plugin structure
- Removed duplicate else block from merge artifact

## Infrastructure

- Added multi-tenancy support for claude-mem Pro
- Updated OpenClaw install URLs to `install.cmem.ai`
- Added Vercel deploy workflow for install scripts
- Added `.claude/plans` and `.claude/worktrees` to `.gitignore`

## [v10.0.6] - 2026-02-13

## Bug Fixes

- **OpenClaw: Fix MEMORY.md project query mismatch** — `syncMemoryToWorkspace` now includes both the base project name and the agent-scoped project name (e.g., both "openclaw" and "openclaw-main") when querying for context injection, ensuring the correct observations are pulled into MEMORY.md.

- **OpenClaw: Add feed botToken support for Telegram** — Feeds can now configure a dedicated `botToken` for direct Telegram message delivery, bypassing the OpenClaw gateway channel. This fixes scenarios where the gateway bot token couldn't be used for feed messages.

## Other

- Changed OpenClaw plugin kind from "integration" to "memory" for accuracy.

## [v10.0.5] - 2026-02-13

## OpenClaw Installer & Distribution

This release introduces the OpenClaw one-liner installer and fixes several OpenClaw plugin issues.

### New Features

- **OpenClaw Installer** (`openclaw/install.sh`): Full cross-platform installer script with `curl | bash` support
  - Platform detection (macOS, Linux, WSL)
  - Automatic dependency management (Bun, uv, Node.js)
  - Interactive AI provider setup with settings writer
  - OpenClaw gateway detection, plugin install, and memory slot configuration
  - Worker startup and health verification with rich diagnostics
  - TTY detection, `--provider`/`--api-key` CLI flags
  - Error recovery and upgrade handling for existing installations
  - jq/python3/node fallback chain for JSON config writing
- **Distribution readiness tests** (`openclaw/test-install.sh`): Comprehensive test suite for the installer
- **Enhanced `/api/health` endpoint**: Now returns version, uptime, workerPath, and AI status

### Bug Fixes

- Fix: use `event.prompt` instead of `ctx.sessionKey` for prompt storage in OpenClaw plugin
- Fix: detect both `openclaw` and `openclaw.mjs` binary names in gateway discovery
- Fix: pass file paths via env vars instead of bash interpolation in `node -e` calls
- Fix: handle stale plugin config that blocks OpenClaw CLI during reinstall
- Fix: remove stale memory slot reference during reinstall cleanup
- Fix: remove opinionated filters from OpenClaw plugin

## [v10.0.4] - 2026-02-12

## Revert: v10.0.3 chroma-mcp spawn storm fix

v10.0.3 introduced regressions. This release reverts the codebase to the stable v10.0.2 state.

### What was reverted

- Connection mutex via promise memoization
- Pre-spawn process count guard
- Hardened `close()` with try-finally + Unix `pkill -P` fallback
- Count-based orphan reaper in `ProcessManager`
- Circuit breaker (3 failures → 60s cooldown)
- `etime`-based sorting for process guards

### Files restored to v10.0.2

- `src/services/sync/ChromaSync.ts`
- `src/services/infrastructure/GracefulShutdown.ts`
- `src/services/infrastructure/ProcessManager.ts`
- `src/services/worker-service.ts`
- `src/services/worker/ProcessRegistry.ts`
- `tests/infrastructure/process-manager.test.ts`
- `tests/integration/chroma-vector-sync.test.ts`

## [v10.0.3] - 2026-02-11

## Fix: Prevent chroma-mcp spawn storm (PR #1065)

Fixes a critical bug where killing the worker daemon during active sessions caused **641 chroma-mcp Python processes** to spawn in ~5 minutes, consuming 75%+ CPU and ~64GB virtual memory.

### Root Cause

`ChromaSync.ensureConnection()` had no connection mutex. Concurrent fire-and-forget `syncObservation()` calls from multiple sessions raced through the check-then-act guard, each spawning a chroma-mcp subprocess via `StdioClientTransport`. Error-driven reconnection created a positive feedback loop.

### 5-Layer Defense

| Layer | Mechanism | Purpose |
|-------|-----------|---------|
| **0** | Connection mutex via promise memoization | Coalesces concurrent callers onto a single spawn attempt |
| **1** | Pre-spawn process count guard (`execFileSync('ps')`) | Kills excess chroma-mcp processes before spawning new ones |
| **2** | Hardened `close()` with try-finally + Unix `pkill -P` fallback | Guarantees state reset even on error, kills orphaned children |
| **3** | Count-based orphan reaper in `ProcessManager` | Kills by count (not age), catches spawn storms where all processes are young |
| **4** | Circuit breaker (3 failures → 60s cooldown) | Stops error-driven reconnection positive feedback loop |

### Additional Fix

- Process guards now use `etime`-based sorting instead of PID ordering for reliable age determination (PIDs wrap and don't guarantee ordering)

### Testing

- 16 new tests for mutex, circuit breaker, close() hardening, and count guard
- All tests pass (947 pass, 3 skip)

Closes #1063, closes #695. Relates to #1010, #707.

**Contributors:** @rodboev

## [v10.0.2] - 2026-02-11

## Bug Fixes

- **Prevent daemon silent death from SIGHUP + unhandled errors** — Worker process could silently die when receiving SIGHUP signals or encountering unhandled errors, leaving hooks without a backend. Now properly handles these signals and prevents silent crashes.
- **Hook resilience and worker lifecycle improvements** — Comprehensive fixes for hook command error classification, addressing issues #957, #923, #984, #987, and #1042. Hooks now correctly distinguish between worker unavailability errors and other failures.
- **Clarify TypeError order dependency in error classifier** — Fixed error classification logic to properly handle TypeError ordering edge cases.

## New Features

- **Project-scoped statusline counter utility** — Added `statusline-counts.js` for tracking observation counts per project in the Claude Code status line.

## Internal

- Added test coverage for hook command error classification and process manager
- Worker service and MCP server lifecycle improvements
- Process manager enhancements for better cross-platform stability

### Contributors
- @rodboev — Hook resilience and worker lifecycle fixes (PR #1056)

## [v10.0.1] - 2026-02-11

## What's Changed

### OpenClaw Observation Feed
- Enabled SSE observation feed for OpenClaw agent sessions, allowing real-time streaming of observations to connected OpenClaw clients
- Fixed `ObservationSSEPayload.project` type to be nullable, preventing type errors when project context is unavailable
- Added `EnvManager` support for OpenClaw environment configuration

### Build Artifacts
- Rebuilt worker service and MCP server with latest changes

## [v10.0.0] - 2026-02-11

## OpenClaw Plugin — Persistent Memory for OpenClaw Agents

Claude-mem now has an official [OpenClaw](https://openclaw.ai) plugin, bringing persistent memory to agents running on the OpenClaw gateway. This is a major milestone — claude-mem's memory system is no longer limited to Claude Code sessions.

### What It Does

The plugin bridges claude-mem's observation pipeline with OpenClaw's embedded runner (`pi-embedded`), which calls the Anthropic API directly without spawning a `claude` process. Three core capabilities:

1. **Observation Recording** — Captures every tool call from OpenClaw agents and sends it to the claude-mem worker for AI-powered compression and storage
2. **MEMORY.md Live Sync** — Writes a continuously-updated memory timeline to each agent's workspace, so agents start every session with full context from previous work
3. **Observation Feed** — Streams new observations to messaging channels (Telegram, Discord, Slack, Signal, WhatsApp, LINE) in real-time via SSE

### Quick Start

Add claude-mem to your OpenClaw gateway config:

```json
{
  "plugins": {
    "claude-mem": {
      "enabled": true,
      "config": {
        "project": "my-project",
        "syncMemoryFile": true,
        "observationFeed": {
          "enabled": true,
          "channel": "telegram",
          "to": "your-chat-id"
        }
      }
    }
  }
}
```

The claude-mem worker service must be running on the same machine (`localhost:37777`).

### Commands

- `/claude-mem-status` — Worker health check, active sessions, feed connection state
- `/claude-mem-feed` — Show/toggle observation feed status
- `/claude-mem-feed on|off` — Enable/disable feed

### How the Event Lifecycle Works

```
OpenClaw Gateway
  ├── session_start ──────────→ Init claude-mem session
  ├── before_agent_start ─────→ Sync MEMORY.md + track workspace
  ├── tool_result_persist ────→ Record observation + re-sync MEMORY.md
  ├── agent_end ──────────────→ Summarize + complete session
  ├── session_end ────────────→ Clean up session tracking
  └── gateway_start ──────────→ Reset all tracking
```

All observation recording and MEMORY.md syncs are fire-and-forget — they never block the agent.

📖 Full documentation: [OpenClaw Integration Guide](https://docs.claude-mem.ai/docs/openclaw-integration)

---

## Windows Platform Improvements

- **ProcessManager**: Migrated daemon spawning from deprecated WMIC to PowerShell `Start-Process` with `-WindowStyle Hidden`
- **ChromaSync**: Re-enabled vector search on Windows (was previously disabled entirely)
- **Worker Service**: Added unified DB-ready gate middleware — all DB-dependent endpoints now wait for initialization instead of returning "Database not initialized" errors
- **EnvManager**: Switched from fragile allowlist to simple blocklist for subprocess env vars (only strips `ANTHROPIC_API_KEY` per Issue #733)

## Session Management Fixes

- Fixed unbounded session tracking map growth — maps are now cleaned up on `session_end`
- Session init moved to `session_start` and `after_compaction` hooks for correct lifecycle handling

## SSE Fixes

- Fixed stream URL consistency across the codebase
- Fixed multi-line SSE data frame parsing (concatenates `data:` lines per SSE spec)

## Issue Triage

Closed 37+ duplicate/stale/invalid issues across multiple triage phases, significantly cleaning up the issue tracker.

## [v9.1.1] - 2026-02-07

## Critical Bug Fix: Worker Initialization Failure

**v9.1.0 was unable to initialize its database on existing installations.** This patch fixes the root cause and several related issues.

### Bug Fixes

- **Fix FOREIGN KEY constraint failure during migration** — The `addOnUpdateCascadeToForeignKeys` migration (schema v21) crashed when orphaned observations existed (observations whose `memory_session_id` has no matching row in `sdk_sessions`). Fixed by disabling FK checks (`PRAGMA foreign_keys = OFF`) during table recreation, following SQLite's recommended migration pattern.

- **Remove hardcoded CHECK constraints on observation type column** — Multiple locations enforced `CHECK(type IN ('decision', 'bugfix', ...))` but the mode system (v8.0.0+) allows custom observation types, causing constraint violations. Removed all 5 occurrences across `SessionStore.ts`, `migrations.ts`, and `migrations/runner.ts`.

- **Fix Express middleware ordering for initialization guard** — The `/api/*` guard middleware that waits for DB initialization was registered AFTER routes, so Express matched routes before the guard. Moved guard middleware registration BEFORE route registrations. Added dedicated early handler for `/api/context/inject` to fail-open during init.

### New

- **Restored mem-search skill** — Recreated `plugin/skills/mem-search/SKILL.md` with the 3-layer workflow (search → timeline → batch fetch) updated for the current MCP tool set.

## [v9.1.0] - 2026-02-07

## v9.1.0 — The Great PR Triage

100 open PRs reviewed, triaged, and resolved. 157 commits, 123 files changed, +6,104/-721 lines. This release focuses on stability, security, and community contributions.

### Highlights

- **100 PR triage**: Reviewed every open PR — merged 48, cherry-picked 13, closed 39 (stale/duplicate/YAGNI)
- **Fail-open hook architecture**: Hooks no longer block Claude Code prompts when the worker is starting up
- **DB initialization guard**: All API endpoints now wait for database initialization instead of crashing with "Database not initialized"
- **Security hardening**: CORS restricted to localhost, XSS defense-in-depth via DOMPurify
- **3 new features**: Manual memory save, project exclusion, folder exclude setting

---

### Security

- **CORS restricted to localhost** — Worker API no longer accepts cross-origin requests from arbitrary websites. Only localhost/127.0.0.1 origins allowed. (PR #917 by @Spunky84)
- **XSS defense-in-depth** — Added DOMPurify sanitization to TerminalPreview.tsx viewer component (concept from PR #896)

### New Features

- **Manual memory storage** — New \`save_memory\` MCP tool and \`POST /api/memory/save\` endpoint for explicit memory capture (PR #662 by @darconada, closes #645)
- **Project exclusion setting** — \`CLAUDE_MEM_EXCLUDED_PROJECTS\` glob patterns to exclude entire projects from tracking (PR #920 by @Spunky84)
- **Folder exclude setting** — \`CLAUDE_MEM_FOLDER_MD_EXCLUDE\` JSON array to exclude paths from CLAUDE.md generation, fixing Xcode/drizzle build conflicts (PR #699 by @leepokai, closes #620)
- **Folder CLAUDE.md opt-in** — \`CLAUDE_MEM_FOLDER_CLAUDEMD_ENABLED\` now defaults to \`false\` (opt-in) instead of always-on (PR #913 by @superbiche)
- **Generate/clean CLI commands** — \`generate\` and \`clean\` commands for CLAUDE.md management with \`--dry-run\` support (PR #657 by @thedotmack)
- **Ragtime email investigation** — Batch processor for email investigation workflows (PR #863 by @thedotmack)

### Hook Resilience (Fail-Open Architecture)

Hooks no longer block Claude Code when the worker is unavailable or slow:

- **Graceful hook failures** — Hooks exit 0 with empty responses instead of crashing with exit 2 (PR #973 by @farikh)
- **Fail-open context injection** — Returns empty context during initialization instead of 503 (PR #959 by @rodboev)
- **Fetch timeouts** — All hook fetch calls have timeouts via \`fetchWithTimeout()\` helper (PR #964 by @rodboev)
- **Removed stale user-message hook** — Eliminated startup error from incorrectly bundled hook (PR #960 by @rodboev)
- **DB initialization middleware** — All \`/api/*\` routes now wait for DB init with 30s timeout instead of crashing

### Windows Stability

- **Path spaces fix** — bun-runner.js no longer fails for Windows usernames with spaces (PR #972 by @farikh)
- **Spawn guard** — 2-minute cooldown prevents repeated worker popup windows on startup failure

### Process & Zombie Management

- **Daemon children cleanup** — Orphan reaper now catches idle daemon child processes (PR #879 by @boaz-robopet)
- **Expanded orphan cleanup** — Startup cleanup now targets mcp-server.cjs and worker-service.cjs processes
- **Session-complete hook** — New Stop phase 2 hook removes sessions from active map, enabling effective orphan reaper cleanup (PR #844 by @thusdigital, fixes #842)

### Session Management

- **Prompt-too-long termination** — Sessions terminate cleanly instead of infinite retry loops (PR #934 by @jayvenn21)
- **Infinite restart prevention** — Max 3 restart attempts with exponential backoff, prevents runaway API costs (PR #693 by @ajbmachon)
- **Orphaned message fallback** — Messages from terminated sessions drain via Gemini/OpenRouter fallback (PR #937 by @jayvenn21, fixes #936)
- **Project field backfill** — Sessions correctly scoped when PostToolUse creates session before UserPromptSubmit (PR #940 by @miclip)
- **Provider-aware recovery** — Startup recovery uses correct provider instead of hardcoding SDKAgent (PR #741 by @licutis)
- **AbortController reset** — Prevents infinite "Generator aborted" loops after session abort (PR #627 by @TranslateMe)
- **Stateless provider IDs** — Synthetic memorySessionId generation for Gemini/OpenRouter (concept from PR #615 by @JiehoonKwak)
- **Duplicate generator prevention** — Legacy init endpoint uses idempotent \`ensureGeneratorRunning()\` (PR #932 by @jayvenn21)
- **DB readiness wait** — Session-init endpoint waits for database initialization (PR #828 by @rajivsinclair)
- **Image-only prompt support** — Empty/media prompts use \`[media prompt]\` placeholder (concept from PR #928 by @iammike)

### CLAUDE.md Path & Generation

- **Race condition fix** — Two-pass detection prevents corruption when Claude Code edits CLAUDE.md (concept from PR #974 by @cheapsteak)
- **Duplicate path prevention** — Detects \`frontend/frontend/\` style nested duplicates (concept from PR #836 by @Glucksberg)
- **Unsafe directory exclusion** — Blocks generation in \`res/\`, \`.git/\`, \`build/\`, \`node_modules/\`, \`__pycache__/\` (concept from PR #929 by @jayvenn21)

### Chroma/Vector Search

- **ID/metadata alignment fix** — Search results no longer misaligned after deduplication (PR #887 by @abkrim)
- **Transport zombie prevention** — Connection error handlers now close transport (PR #769 by @jenyapoyarkov)
- **Zscaler SSL support** — Enterprise environments with SSL inspection now work via combined cert path (PR #884 by @RClark4958)

### Parser & Config

- **Nested XML tag handling** — Parser correctly extracts fields with nested XML content (PR #835 by @Glucksberg)
- **Graceful empty transcripts** — Transcript parser returns empty string instead of crashing (PR #862 by @DennisHartrampf)
- **Gemini model name fix** — Corrected \`gemini-3-flash\` → \`gemini-3-flash-preview\` (PR #831 by @Glucksberg)
- **CLAUDE_CONFIG_DIR support** — Plugin paths respect custom config directory (PR #634 by @Kuroakira, fixes #626)
- **Env var priority** — \`env > file > defaults\` ordering via \`applyEnvOverrides()\` (PR #712 by @cjpeterein)
- **Minimum Bun version check** — smart-install.js enforces Bun 1.1.14+ (PR #524 by @quicktime, fixes #519)
- **Stdin timeout** — JSON self-delimiting detection with 30s safety timeout prevents hook hangs (PR #771 by @rajivsinclair, fixes #727)
- **FK constraint prevention** — \`ensureMemorySessionIdRegistered()\` guard + \`ON UPDATE CASCADE\` schema migration (PR #889 by @Et9797, fixes #846)
- **Cursor bun runtime** — Cursor hooks use bun instead of node, fixing bun:sqlite crashes (PR #721 by @polux0)

### Documentation

- **9 README PRs merged**: formatting fixes, Korean/Japanese/Chinese render fixes, documentation link updates, Traditional Chinese + Urdu translations (PRs #953, #898, #864, #637, #636, #894, #907, #691 by @Leonard013, @youngsu5582, @eltociear, @WuMingDao, @fengluodb, @PeterDaveHello, @yasirali646)
- **Windows setup note** — npm PATH instructions (PR #919 by @kamran-khalid-v9)
- **Issue templates** — Duplicate check checkbox added (PR #970 by @bmccann36)

### Community Contributors

Thank you to the 35+ contributors whose PRs were reviewed in this release:

@Spunky84, @farikh, @rodboev, @boaz-robopet, @jayvenn21, @ajbmachon, @miclip, @licutis, @TranslateMe, @JiehoonKwak, @rajivsinclair, @iammike, @cheapsteak, @Glucksberg, @abkrim, @jenyapoyarkov, @RClark4958, @DennisHartrampf, @Kuroakira, @cjpeterein, @quicktime, @polux0, @Et9797, @thusdigital, @superbiche, @darconada, @leepokai, @Leonard013, @youngsu5582, @eltociear, @WuMingDao, @fengluodb, @PeterDaveHello, @yasirali646, @kamran-khalid-v9, @bmccann36

---

**Full Changelog**: https://github.com/thedotmack/claude-mem/compare/v9.0.17...v9.1.0

## [v9.0.17] - 2026-02-05

## Bug Fixes

### Fix Fresh Install Bun PATH Resolution (#818)

On fresh installations, hooks would fail because Bun wasn't in PATH until terminal restart. The `smart-install.js` script installs Bun to `~/.bun/bin/bun`, but the current shell session doesn't have it in PATH.

**Fix:** Introduced `bun-runner.js` — a Node.js wrapper that searches common Bun installation locations across all platforms:
- PATH (via `which`/`where`)
- `~/.bun/bin/bun` (default install location)
- `/usr/local/bin/bun`
- `/opt/homebrew/bin/bun` (macOS Homebrew)
- `/home/linuxbrew/.linuxbrew/bin/bun` (Linuxbrew)
- Windows: `%LOCALAPPDATA%\bun` or fallback paths

All 9 hook definitions updated to use `node bun-runner.js` instead of direct `bun` calls.

**Files changed:**
- `plugin/scripts/bun-runner.js` — New 88-line Bun discovery script
- `plugin/hooks/hooks.json` — All hook commands now route through bun-runner

Fixes #818 | PR #827 by @bigphoot

## [v9.0.16] - 2026-02-05

## Bug Fixes

### Fix Worker Startup Timeout (#811, #772, #729)

Resolves the "Worker did not become ready within 15 seconds" timeout error that could prevent hooks from communicating with the worker service.

**Root cause:** `isWorkerHealthy()` and `waitForHealth()` were checking `/api/readiness`, which returns 503 until full initialization completes — including MCP connection setup that can take 5+ minutes. Hooks only have a 15-second timeout window.

**Fix:** Switched to `/api/health` (liveness check), which returns 200 as soon as the HTTP server is listening. This is sufficient for hook communication since the worker accepts requests while background initialization continues.

**Files changed:**
- `src/shared/worker-utils.ts` — `isWorkerHealthy()` now checks `/api/health`
- `src/services/infrastructure/HealthMonitor.ts` — `waitForHealth()` now checks `/api/health`
- `tests/infrastructure/health-monitor.test.ts` — Updated test expectations

### PR Merge Tasks
- PR #820 merged with full verification pipeline (rebase, code review, build verification, test, manual verification)

## [v9.0.15] - 2026-02-05

## Security Fix

### Isolated Credentials (#745)
- **Prevents API key hijacking** from random project `.env` files
- Credentials now sourced exclusively from `~/.claude-mem/.env`
- Only whitelisted environment variables passed to SDK `query()` calls
- Authentication method logging shows whether using Claude Code CLI subscription billing or explicit API key

This is a security-focused patch release that hardens credential handling to prevent unintended API key usage from project directories.

## [v9.0.14] - 2026-02-05

## In-Process Worker Architecture

This release includes the merged in-process worker architecture from PR #722, which fundamentally improves how hooks interact with the worker service.

### Changes

- **In-process worker architecture** - Hook processes now become the worker when port 37777 is available, eliminating Windows spawn issues
- **Hook command improvements** - Added `skipExit` option to `hook-command.ts` for chained command execution
- **Worker health checks** - `worker-utils.ts` now returns boolean status for cleaner health monitoring
- **Massive CLAUDE.md cleanup** - Removed 76 redundant documentation files (4,493 lines removed)
- **Chained hook configuration** - `hooks.json` now supports chained commands for complex workflows

### Technical Details

The in-process architecture means hooks no longer need to spawn separate worker processes. When port 37777 is available, the hook itself becomes the worker, providing:
- Faster startup times
- Better resource utilization
- Elimination of process spawn failures on Windows

Full PR: https://github.com/thedotmack/claude-mem/pull/722

## [v9.0.13] - 2026-02-05

## Bug Fixes

### Zombie Observer Prevention (#856)

Fixed a critical issue where observer processes could become "zombies" - lingering indefinitely without activity. This release adds:

- **3-minute idle timeout**: SessionQueueProcessor now automatically terminates after 3 minutes of inactivity
- **Race condition fix**: Resolved spurious wakeup issues by resetting `lastActivityTime` on queue activity
- **Comprehensive test coverage**: Added 11 new tests for the idle timeout mechanism

This fix prevents resource leaks from orphaned observer processes that could accumulate over time.

## [v9.0.12] - 2026-01-28

## Fix: Authentication failure from observer session isolation

**Critical bugfix** for users who upgraded to v9.0.11.

### Problem

v9.0.11 introduced observer session isolation using `CLAUDE_CONFIG_DIR` override, which inadvertently broke authentication:

```
Invalid API key · Please run /login
```

This happened because Claude Code stores credentials in the config directory, and overriding it prevented access to existing auth tokens.

### Solution

Observer sessions now use the SDK's `cwd` option instead:
- Sessions stored under `~/.claude-mem/observer-sessions/` project
- Auth credentials in `~/.claude/` remain accessible
- Observer sessions still won't pollute `claude --resume` lists

### Affected Users

Anyone running v9.0.11 who saw "Invalid API key" errors should upgrade immediately.

---

🤖 Generated with [Claude Code](https://claude.ai/code)

## [v9.0.11] - 2026-01-28

## Bug Fixes

### Observer Session Isolation (#837)
Observer sessions created by claude-mem were polluting the `claude --resume` list, cluttering it with internal plugin sessions that users never intend to resume. In one user's case, 74 observer sessions out of ~220 total (34% noise).

**Solution**: Observer processes now use a dedicated config directory (`~/.claude-mem/observer-config/`) to isolate their session files from user sessions.

Thanks to @Glucksberg for this fix! Fixes #832.

### Stale memory_session_id Crash Prevention (#839)
After a worker restart, stale `memory_session_id` values in the database could cause crashes when attempting to resume SDK conversations. The existing guard didn't protect against this because session data was loaded from the database.

**Solution**: Clear `memory_session_id` when loading sessions from the database (not from cache). The key insight: if a session isn't in memory, any database `memory_session_id` is definitely stale.

Thanks to @bigph00t for this fix! Fixes #817.

---
**Full Changelog**: https://github.com/thedotmack/claude-mem/compare/v9.0.10...v9.0.11

## [v9.0.10] - 2026-01-26

## Bug Fix

**Fixed path format mismatch causing folder CLAUDE.md files to show "No recent activity" (#794)** - Thanks @bigph00t!

The folder-level CLAUDE.md generation was failing to find observations due to a path format mismatch between how API queries used absolute paths and how the database stored relative paths. The `isDirectChild()` function's simple prefix match always returned false in these cases.

**Root cause:** PR #809 (v9.0.9) only masked this bug by skipping file creation when "no activity" was detected. Since ALL folders were affected, this prevented file creation entirely. This PR provides the actual fix.

**Changes:**
- Added new shared module `src/shared/path-utils.ts` with robust path normalization and matching utilities
- Updated `SessionSearch.ts`, `regenerate-claude-md.ts`, and `claude-md-utils.ts` to use shared path utilities
- Added comprehensive test coverage (61 new tests) for path matching edge cases

---

🤖 Generated with [Claude Code](https://claude.com/claude-code)

## [v9.0.9] - 2026-01-26

## Bug Fixes

### Prevent Creation of Empty CLAUDE.md Files (#809)

Previously, claude-mem would create new `CLAUDE.md` files in project directories even when there was no activity to display, cluttering codebases with empty context files showing only "*No recent activity*".

**What changed:** The `updateFolderClaudeMdFiles` function now checks if the formatted content contains no activity before writing. If a `CLAUDE.md` file doesn't already exist and there's nothing to show, it will be skipped entirely. Existing files will still be updated to reflect "No recent activity" if that's the current state.

**Impact:** Cleaner project directories - only folders with actual activity will have `CLAUDE.md` context files created.

Thanks to @maxmillienjr for this contribution!

## [v9.0.8] - 2026-01-26

## Fix: Prevent Zombie Process Accumulation (Issue #737)

This release fixes a critical issue where Claude haiku subprocesses spawned by the SDK weren't terminating properly, causing zombie process accumulation. One user reported 155 processes consuming 51GB RAM.

### Root Causes Addressed
- SDK's SpawnedProcess interface hides subprocess PIDs
- `deleteSession()` didn't verify subprocess exit
- `abort()` was fire-and-forget with no confirmation
- No mechanism to track or clean up orphaned processes

### Solution
- **ProcessRegistry module**: Tracks spawned Claude subprocesses via PID
- **Custom spawn**: Uses SDK's `spawnClaudeCodeProcess` option to capture PIDs
- **Signal propagation**: Passes signal parameter to enable AbortController integration
- **Graceful shutdown**: Waits for subprocess exit in `deleteSession()` with 5s timeout
- **SIGKILL escalation**: Force-kills processes that don't exit gracefully
- **Orphan reaper**: Safety net running every 5 minutes to clean up any missed processes
- **Race detection**: Warns about multiple processes per session (race condition indicator)

### Files Changed
- `src/services/worker/ProcessRegistry.ts` (new): PID registry and reaper
- `src/services/worker/SDKAgent.ts`: Use custom spawn to capture PIDs
- `src/services/worker/SessionManager.ts`: Verify subprocess exit on delete
- `src/services/worker-service.ts`: Start/stop orphan reaper

**Full Changelog**: https://github.com/thedotmack/claude-mem/compare/v9.0.7...v9.0.8

Fixes #737

## [v9.0.6] - 2026-01-22

## Windows Console Popup Fix

This release eliminates the annoying console window popups that Windows users experienced when claude-mem spawned background processes.

### Fixed
- **Windows console popups eliminated** - Daemon spawn and Chroma operations no longer create visible console windows (#748, #708, #681, #676)
- **Race condition in PID file writing** - Worker now writes its own PID file after listen() succeeds, ensuring reliable process tracking on all platforms

### Changed
- **Chroma temporarily disabled on Windows** - Vector search is disabled on Windows while we migrate to a popup-free architecture. Keyword search and all other memory features continue to work. A follow-up release will re-enable Chroma.
- **Slash command discoverability** - Added YAML frontmatter to `/do` and `/make-plan` commands

### Technical Details
- Uses WMIC for detached process spawning on Windows
- PID file location unchanged, but now written by worker process
- Cross-platform: Linux/macOS behavior unchanged

### Contributors
- @bigph00t (Alexander Knigge)

## [v9.0.5] - 2026-01-14

## Major Worker Service Cleanup

This release contains a significant refactoring of `worker-service.ts`, removing ~216 lines of dead code and simplifying the architecture.

### Refactoring
- **Removed dead code**: Deleted `runInteractiveSetup` function (defined but never called)
- **Cleaned up imports**: Removed unused imports (fs namespace, spawn, homedir, readline, existsSync, writeFileSync, readFileSync, mkdirSync)
- **Removed fallback agent concept**: Users who choose Gemini/OpenRouter now get those providers directly without hidden fallback behavior
- **Eliminated re-export indirection**: ResponseProcessor now imports directly from CursorHooksInstaller instead of through worker-service

### Security Fix
- **Removed dangerous ANTHROPIC_API_KEY check**: Claude Code uses CLI authentication, not direct API calls. The previous check could accidentally use a user's API key (from other projects) which costs 20x more than Claude Code's pricing

### Build Improvements
- **Dynamic MCP version management**: MCP server and client versions now use build-time injected values from package.json instead of hardcoded strings, ensuring version synchronization

### Documentation
- Added Anti-Pattern Czar Generalization Analysis report
- Updated README with $CMEM links and contract address
- Added comprehensive cleanup and validation plans for worker-service.ts



================================================
FILE: CLAUDE.md
================================================
# Claude-Mem: AI Development Instructions

Claude-mem is a Claude Code plugin providing persistent memory across sessions. It captures tool usage, compresses observations using the Claude Agent SDK, and injects relevant context into future sessions.

## Architecture

**5 Lifecycle Hooks**: SessionStart → UserPromptSubmit → PostToolUse → Summary → SessionEnd

**Hooks** (`src/hooks/*.ts`) - TypeScript → ESM, built to `plugin/scripts/*-hook.js`

**Worker Service** (`src/services/worker-service.ts`) - Express API on port 37777, Bun-managed, handles AI processing asynchronously

**Database** (`src/services/sqlite/`) - SQLite3 at `~/.claude-mem/claude-mem.db`

**Search Skill** (`plugin/skills/mem-search/SKILL.md`) - HTTP API for searching past work, auto-invoked when users ask about history

**Planning Skill** (`plugin/skills/make-plan/SKILL.md`) - Orchestrator instructions for creating phased implementation plans with documentation discovery

**Execution Skill** (`plugin/skills/do/SKILL.md`) - Orchestrator instructions for executing phased plans using subagents

**Chroma** (`src/services/sync/ChromaSync.ts`) - Vector embeddings for semantic search

**Viewer UI** (`src/ui/viewer/`) - React interface at http://localhost:37777, built to `plugin/ui/viewer.html`

## Privacy Tags
- `<private>content</private>` - User-level privacy control (manual, prevents storage)

**Implementation**: Tag stripping happens at hook layer (edge processing) before data reaches worker/database. See `src/utils/tag-stripping.ts` for shared utilities.

## Build Commands

```bash
npm run build-and-sync        # Build, sync to marketplace, restart worker
```

## Configuration

Settings are managed in `~/.claude-mem/settings.json`. The file is auto-created with defaults on first run.

## File Locations

- **Source**: `<project-root>/src/`
- **Built Plugin**: `<project-root>/plugin/`
- **Installed Plugin**: `~/.claude/plugins/marketplaces/thedotmack/`
- **Database**: `~/.claude-mem/claude-mem.db`
- **Chroma**: `~/.claude-mem/chroma/`

## Exit Code Strategy

Claude-mem hooks use specific exit codes per Claude Code's hook contract:

- **Exit 0**: Success or graceful shutdown (Windows Terminal closes tabs)
- **Exit 1**: Non-blocking error (stderr shown to user, continues)
- **Exit 2**: Blocking error (stderr fed to Claude for processing)

**Philosophy**: Worker/hook errors exit with code 0 to prevent Windows Terminal tab accumulation. The wrapper/plugin layer handles restart logic. ERROR-level logging is maintained for diagnostics.

See `private/context/claude-code/exit-codes.md` for full hook behavior matrix.

## Requirements

- **Bun** (all platforms - auto-installed if missing)
- **uv** (all platforms - auto-installed if missing, provides Python for Chroma)
- Node.js

## Documentation

**Public Docs**: https://docs.claude-mem.ai (Mintlify)
**Source**: `docs/public/` - MDX files, edit `docs.json` for navigation
**Deploy**: Auto-deploys from GitHub on push to main

## Pro Features Architecture

Claude-mem is designed with a clean separation between open-source core functionality and optional Pro features.

**Open-Source Core** (this repository):

- All worker API endpoints on localhost:37777 remain fully open and accessible
- Pro features are headless - no proprietary UI elements in this codebase
- Pro integration points are minimal: settings for license keys, tunnel provisioning logic
- The architecture ensures Pro features extend rather than replace core functionality

**Pro Features** (coming soon, external):

- Enhanced UI (Memory Stream) connects to the same localhost:37777 endpoints as the open viewer
- Additional features like advanced filtering, timeline scrubbing, and search tools
- Access gated by license validation, not by modifying core endpoints
- Users without Pro licenses continue using the full open-source viewer UI without limitation

This architecture preserves the open-source nature of the project while enabling sustainable development through optional paid features.

## Important

No need to edit the changelog ever, it's generated automatically.


================================================
FILE: LICENSE
================================================
                  GNU AFFERO GENERAL PUBLIC LICENSE
                      Version 3, 19 November 2007

  Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.

  This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

  This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

================================================
FILE: README.md
================================================
<h1 align="center">
  <br>
  <a href="https://github.com/thedotmack/claude-mem">
    <picture>
      <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-dark-mode.webp">
      <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-light-mode.webp">
      <img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/claude-mem-logo-for-light-mode.webp" alt="Claude-Mem" width="400">
    </picture>
  </a>
  <br>
</h1>

<p align="center">
  <a href="docs/i18n/README.zh.md">🇨🇳 中文</a> •
  <a href="docs/i18n/README.zh-tw.md">🇹🇼 繁體中文</a> •
  <a href="docs/i18n/README.ja.md">🇯🇵 日本語</a> •
  <a href="docs/i18n/README.pt.md">🇵🇹 Português</a> •
  <a href="docs/i18n/README.pt-br.md">🇧🇷 Português</a> •
  <a href="docs/i18n/README.ko.md">🇰🇷 한국어</a> •
  <a href="docs/i18n/README.es.md">🇪🇸 Español</a> •
  <a href="docs/i18n/README.de.md">🇩🇪 Deutsch</a> •
  <a href="docs/i18n/README.fr.md">🇫🇷 Français</a> •
  <a href="docs/i18n/README.he.md">🇮🇱 עברית</a> •
  <a href="docs/i18n/README.ar.md">🇸🇦 العربية</a> •
  <a href="docs/i18n/README.ru.md">🇷🇺 Русский</a> •
  <a href="docs/i18n/README.pl.md">🇵🇱 Polski</a> •
  <a href="docs/i18n/README.cs.md">🇨🇿 Čeština</a> •
  <a href="docs/i18n/README.nl.md">🇳🇱 Nederlands</a> •
  <a href="docs/i18n/README.tr.md">🇹🇷 Türkçe</a> •
  <a href="docs/i18n/README.uk.md">🇺🇦 Українська</a> •
  <a href="docs/i18n/README.vi.md">🇻🇳 Tiếng Việt</a> •
  <a href="docs/i18n/README.tl.md">🇵🇭 Tagalog</a> •
  <a href="docs/i18n/README.id.md">🇮🇩 Indonesia</a> •
  <a href="docs/i18n/README.th.md">🇹🇭 ไทย</a> •
  <a href="docs/i18n/README.hi.md">🇮🇳 हिन्दी</a> •
  <a href="docs/i18n/README.bn.md">🇧🇩 বাংলা</a> •
  <a href="docs/i18n/README.ur.md">🇵🇰 اردو</a> •
  <a href="docs/i18n/README.ro.md">🇷🇴 Română</a> •
  <a href="docs/i18n/README.sv.md">🇸🇪 Svenska</a> •
  <a href="docs/i18n/README.it.md">🇮🇹 Italiano</a> •
  <a href="docs/i18n/README.el.md">🇬🇷 Ελληνικά</a> •
  <a href="docs/i18n/README.hu.md">🇭🇺 Magyar</a> •
  <a href="docs/i18n/README.fi.md">🇫🇮 Suomi</a> •
  <a href="docs/i18n/README.da.md">🇩🇰 Dansk</a> •
  <a href="docs/i18n/README.no.md">🇳🇴 Norsk</a>
</p>

<h4 align="center">Persistent memory compression system built for <a href="https://claude.com/claude-code" target="_blank">Claude Code</a>.</h4>

<p align="center">
  <a href="LICENSE">
    <img src="https://img.shields.io/badge/License-AGPL%203.0-blue.svg" alt="License">
  </a>
  <a href="package.json">
    <img src="https://img.shields.io/badge/version-6.5.0-green.svg" alt="Version">
  </a>
  <a href="package.json">
    <img src="https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen.svg" alt="Node">
  </a>
  <a href="https://github.com/thedotmack/awesome-claude-code">
    <img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Claude Code">
  </a>
</p>

<p align="center">
  <a href="https://trendshift.io/repositories/15496" target="_blank">
    <picture>
      <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge-dark.svg">
      <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge.svg">
      <img src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/trendshift-badge.svg" alt="thedotmack/claude-mem | Trendshift" width="250" height="55"/>
    </picture>
  </a>
</p>

<br>

<table align="center">
  <tr>
    <td align="center">
      <a href="https://github.com/thedotmack/claude-mem">
        <picture>
          <img
            src="https://raw.githubusercontent.com/thedotmack/claude-mem/main/docs/public/cm-preview.gif"
            alt="Claude-Mem Preview"
            width="500"
          >
        </picture>
      </a>
    </td>
    <td align="center">
      <a href="https://www.star-history.com/#thedotmack/claude-mem&Date">
        <picture>
          <source
            media="(prefers-color-scheme: dark)"
            srcset="https://api.star-history.com/image?repos=thedotmack/claude-mem&type=date&theme=dark&legend=top-left"
          />
          <source
            media="(prefers-color-scheme: light)"
            srcset="https://api.star-history.com/image?repos=thedotmack/claude-mem&type=date&legend=top-left"
          />
          <img
            alt="Star History Chart"
            src="https://api.star-history.com/image?repos=thedotmack/claude-mem&type=date&legend=top-left"
            width="500"
          />
        </picture>
      </a>
    </td>
  </tr>
</table>

<p align="center">
  <a href="#quick-start">Quick Start</a> •
  <a href="#how-it-works">How It Works</a> •
  <a href="#mcp-search-tools">Search Tools</a> •
  <a href="#documentation">Documentation</a> •
  <a href="#configuration">Configuration</a> •
  <a href="#troubleshooting">Troubleshooting</a> •
  <a href="#license">License</a>
</p>

<p align="center">
  Claude-Mem seamlessly preserves context across sessions by automatically capturing tool usage observations, generating semantic summaries, and making them available to future sessions. This enables Claude to maintain continuity of knowledge about projects even after sessions end or reconnect.
</p>

---

## Quick Start

Start a new Claude Code session in the terminal and enter the following commands:

```
/plugin marketplace add thedotmack/claude-mem

/plugin install claude-mem
```

Restart Claude Code. Context from previous sessions will automatically appear in new sessions.

> **Note:** Claude-Mem is also published on npm, but `npm install -g claude-mem` installs the **SDK/library only** — it does not register the plugin hooks or set up the worker service. To use Claude-Mem as a plugin, always install via the `/plugin` commands above.

### 🦞 OpenClaw Gateway

Install claude-mem as a persistent memory plugin on [OpenClaw](https://openclaw.ai) gateways with a single command:

```bash
curl -fsSL https://install.cmem.ai/openclaw.sh | bash
```

The installer handles dependencies, plugin setup, AI provider configuration, worker startup, and optional real-time observation feeds to Telegram, Discord, Slack, and more. See the [OpenClaw Integration Guide](https://docs.claude-mem.ai/openclaw-integration) for details.

**Key Features:**

- 🧠 **Persistent Memory** - Context survives across sessions
- 📊 **Progressive Disclosure** - Layered memory retrieval with token cost visibility
- 🔍 **Skill-Based Search** - Query your project history with mem-search skill
- 🖥️ **Web Viewer UI** - Real-time memory stream at http://localhost:37777
- 💻 **Claude Desktop Skill** - Search memory from Claude Desktop conversations
- 🔒 **Privacy Control** - Use `<private>` tags to exclude sensitive content from storage
- ⚙️ **Context Configuration** - Fine-grained control over what context gets injected
- 🤖 **Automatic Operation** - No manual intervention required
- 🔗 **Citations** - Reference past observations with IDs (access via http://localhost:37777/api/observation/{id} or view all in the web viewer at http://localhost:37777)
- 🧪 **Beta Channel** - Try experimental features like Endless Mode via version switching

---

## Documentation

📚 **[View Full Documentation](https://docs.claude-mem.ai/)** - Browse on official website

### Getting Started

- **[Installation Guide](https://docs.claude-mem.ai/installation)** - Quick start & advanced installation
- **[Usage Guide](https://docs.claude-mem.ai/usage/getting-started)** - How Claude-Mem works automatically
- **[Search Tools](https://docs.claude-mem.ai/usage/search-tools)** - Query your project history with natural language
- **[Beta Features](https://docs.claude-mem.ai/beta-features)** - Try experimental features like Endless Mode

### Best Practices

- **[Context Engineering](https://docs.claude-mem.ai/context-engineering)** - AI agent context optimization principles
- **[Progressive Disclosure](https://docs.claude-mem.ai/progressive-disclosure)** - Philosophy behind Claude-Mem's context priming strategy

### Architecture

- **[Overview](https://docs.claude-mem.ai/architecture/overview)** - System components & data flow
- **[Architecture Evolution](https://docs.claude-mem.ai/architecture-evolution)** - The journey from v3 to v5
- **[Hooks Architecture](https://docs.claude-mem.ai/hooks-architecture)** - How Claude-Mem uses lifecycle hooks
- **[Hooks Reference](https://docs.claude-mem.ai/architecture/hooks)** - 7 hook scripts explained
- **[Worker Service](https://docs.claude-mem.ai/architecture/worker-service)** - HTTP API & Bun management
- **[Database](https://docs.claude-mem.ai/architecture/database)** - SQLite schema & FTS5 search
- **[Search Architecture](https://docs.claude-mem.ai/architecture/search-architecture)** - Hybrid search with Chroma vector database

### Configuration & Development

- **[Configuration](https://docs.claude-mem.ai/configuration)** - Environment variables & settings
- **[Development](https://docs.claude-mem.ai/development)** - Building, testing, contributing
- **[Troubleshooting](https://docs.claude-mem.ai/troubleshooting)** - Common issues & solutions

---

## How It Works

**Core Components:**

1. **5 Lifecycle Hooks** - SessionStart, UserPromptSubmit, PostToolUse, Stop, SessionEnd (6 hook scripts)
2. **Smart Install** - Cached dependency checker (pre-hook script, not a lifecycle hook)
3. **Worker Service** - HTTP API on port 37777 with web viewer UI and 10 search endpoints, managed by Bun
4. **SQLite Database** - Stores sessions, observations, summaries
5. **mem-search Skill** - Natural language queries with progressive disclosure
6. **Chroma Vector Database** - Hybrid semantic + keyword search for intelligent context retrieval

See [Architecture Overview](https://docs.claude-mem.ai/architecture/overview) for details.

---

## MCP Search Tools

Claude-Mem provides intelligent memory search through **4 MCP tools** following a token-efficient **3-layer workflow pattern**:

**The 3-Layer Workflow:**

1. **`search`** - Get compact index with IDs (~50-100 tokens/result)
2. **`timeline`** - Get chronological context around interesting results
3. **`get_observations`** - Fetch full details ONLY for filtered IDs (~500-1,000 tokens/result)

**How It Works:**
- Claude uses MCP tools to search your memory
- Start with `search` to get an index of results
- Use `timeline` to see what was happening around specific observations
- Use `get_observations` to fetch full details for relevant IDs
- **~10x token savings** by filtering before fetching details

**Available MCP Tools:**

1. **`search`** - Search memory index with full-text queries, filters by type/date/project
2. **`timeline`** - Get chronological context around a specific observation or query
3. **`get_observations`** - Fetch full observation details by IDs (always batch multiple IDs)

**Example Usage:**

```typescript
// Step 1: Search for index
search(query="authentication bug", type="bugfix", limit=10)

// Step 2: Review index, identify relevant IDs (e.g., #123, #456)

// Step 3: Fetch full details
get_observations(ids=[123, 456])
```

See [Search Tools Guide](https://docs.claude-mem.ai/usage/search-tools) for detailed examples.

---

## Beta Features

Claude-Mem offers a **beta channel** with experimental features like **Endless Mode** (biomimetic memory architecture for extended sessions). Switch between stable and beta versions from the web viewer UI at http://localhost:37777 → Settings.

See **[Beta Features Documentation](https://docs.claude-mem.ai/beta-features)** for details on Endless Mode and how to try it.

---

## System Requirements

- **Node.js**: 18.0.0 or higher
- **Claude Code**: Latest version with plugin support
- **Bun**: JavaScript runtime and process manager (auto-installed if missing)
- **uv**: Python package manager for vector search (auto-installed if missing)
- **SQLite 3**: For persistent storage (bundled)

---
### Windows Setup Notes

If you see an error like:

```powershell
npm : The term 'npm' is not recognized as the name of a cmdlet
```

Make sure Node.js and npm are installed and added to your PATH. Download the latest Node.js installer from https://nodejs.org and restart your terminal after installation.

---

## Configuration

Settings are managed in `~/.claude-mem/settings.json` (auto-created with defaults on first run). Configure AI model, worker port, data directory, log level, and context injection settings.

See the **[Configuration Guide](https://docs.claude-mem.ai/configuration)** for all available settings and examples.

---

## Development

See the **[Development Guide](https://docs.claude-mem.ai/development)** for build instructions, testing, and contribution workflow.

---

## Troubleshooting

If experiencing issues, describe the problem to Claude and the troubleshoot skill will automatically diagnose and provide fixes.

See the **[Troubleshooting Guide](https://docs.claude-mem.ai/troubleshooting)** for common issues and solutions.

---

## Bug Reports

Create comprehensive bug reports with the automated generator:

```bash
cd ~/.claude/plugins/marketplaces/thedotmack
npm run bug-report
```

## Contributing

Contributions are welcome! Please:

1. Fork the repository
2. Create a feature branch
3. Make your changes with tests
4. Update documentation
5. Submit a Pull Request

See [Development Guide](https://docs.claude-mem.ai/development) for contribution workflow.

---

## License

This project is licensed under the **GNU Affero General Public License v3.0** (AGPL-3.0).

Copyright (C) 2025 Alex Newman (@thedotmack). All rights reserved.

See the [LICENSE](LICENSE) file for full details.

**What This Means:**

- You can use, modify, and distribute this software freely
- If you modify and deploy on a network server, you must make your source code available
- Derivative works must also be licensed under AGPL-3.0
- There is NO WARRANTY for this software

**Note on Ragtime**: The `ragtime/` directory is licensed separately under the **PolyForm Noncommercial License 1.0.0**. See [ragtime/LICENSE](ragtime/LICENSE) for details.

---

## Support

- **Documentation**: [docs/](docs/)
- **Issues**: [GitHub Issues](https://github.com/thedotmack/claude-mem/issues)
- **Repository**: [github.com/thedotmack/claude-mem](https://github.com/thedotmack/claude-mem)
- **Official X Account**: [@Claude_Memory](https://x.com/Claude_Memory)
- **Official Discord**: [Join Discord](https://discord.com/invite/J4wttp9vDu)
- **Author**: Alex Newman ([@thedotmack](https://github.com/thedotmack))

---

**Built with Claude Agent SDK** | **Powered by Claude Code** | **Made with TypeScript**

---

### What About $CMEM?

$CMEM is a solana token created by a 3rd party without Claude-Mem's prior consent, but officially embraced by the creator of Claude-Mem (Alex Newman, @thedotmack). The token acts as a community catalyst for growth and a vehicle for bringing real-time agent data to the developers and knowledge workers that need it most. $CMEM: 2TsmuYUrsctE57VLckZBYEEzdokUF8j8e1GavekWBAGS


================================================
FILE: conductor.json
================================================
{
    "scripts": {
        "setup": "cp ../settings.local.json .claude/settings.local.json && npm install",
        "run": "npm run build-and-sync"
    }
}

================================================
FILE: cursor-hooks/.gitignore
================================================
# Ignore backup files created by sed
*.bak



================================================
FILE: cursor-hooks/CONTEXT-INJECTION.md
================================================
# Context Injection in Cursor Hooks

## The Solution: Auto-Updated Rules File

Context is automatically injected via Cursor's **Rules** system:

1. **Install**: `claude-mem cursor install` creates initial context file
2. **Stop hook**: `session-summary.sh` updates context after each session ends
3. **Cursor**: Automatically includes `.cursor/rules/claude-mem-context.mdc` in all chats

**Result**: Context appears at the start of every conversation, just like Claude Code!

## How It Works

### Installation Creates Initial Context

```bash
claude-mem cursor install
```

This:
1. Copies hook scripts to `.cursor/hooks/`
2. Creates `hooks.json` configuration
3. Fetches existing context from claude-mem and writes to `.cursor/rules/claude-mem-context.mdc`

### Context Updates at Three Points

Context is refreshed **three times** per session for maximum freshness:

1. **Before prompt submission** (`context-inject.sh`): Ensures you start with the latest context from previous sessions
2. **After summary completes** (worker auto-update): Immediately after the summary is saved, worker updates the context file
3. **After session ends** (`session-summary.sh`): Fallback update in case worker update was missed

### Before Prompt Hook Updates Context

When you submit a prompt, `context-inject.sh`:

```bash
# 1. Ensure worker is running
ensure_worker_running "$worker_port"

# 2. Fetch fresh context
context=$(curl -s ".../api/context/inject?project=...")

# 3. Write to rules file (used immediately by Cursor)
cat > .cursor/rules/claude-mem-context.mdc << EOF
---
alwaysApply: true
---
# Memory Context
${context}
EOF
```

### Stop Hook Updates Context

After each session ends, `session-summary.sh`:

```bash
# 1. Generate session summary
curl -X POST .../api/sessions/summarize

# 2. Fetch fresh context (includes new observations)
context=$(curl -s ".../api/context/inject?project=...")

# 3. Write to rules file for next session
cat > .cursor/rules/claude-mem-context.mdc << EOF
---
alwaysApply: true
---
# Memory Context
${context}
EOF
```

### The Rules File

Located at: `.cursor/rules/claude-mem-context.mdc`

```markdown
---
alwaysApply: true
description: "Claude-mem context from past sessions (
Download .txt
gitextract_sw8zeb60/

├── .claude/
│   ├── commands/
│   │   └── anti-pattern-czar.md
│   ├── reports/
│   │   └── test-audit-2026-01-05.md
│   └── settings.json
├── .claude-plugin/
│   ├── CLAUDE.md
│   ├── marketplace.json
│   └── plugin.json
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   └── feature_request.md
│   └── workflows/
│       ├── claude-code-review.yml
│       ├── claude.yml
│       ├── convert-feature-requests.yml
│       ├── deploy-install-scripts.yml
│       ├── npm-publish.yml
│       └── summary.yml
├── .gitignore
├── .markdownlint.json
├── .plan/
│   └── npx-distribution.md
├── .translation-cache.json
├── CHANGELOG.md
├── CLAUDE.md
├── LICENSE
├── README.md
├── conductor.json
├── cursor-hooks/
│   ├── .gitignore
│   ├── CONTEXT-INJECTION.md
│   ├── INTEGRATION.md
│   ├── PARITY.md
│   ├── QUICKSTART.md
│   ├── README.md
│   ├── REVIEW.md
│   ├── STANDALONE-SETUP.md
│   ├── cursorrules-template.md
│   └── hooks.json
├── docs/
│   ├── CLAUDE.md
│   ├── PR-SHIPPING-REPORT.md
│   ├── SESSION_ID_ARCHITECTURE.md
│   ├── VERSION_FIX.md
│   ├── anti-pattern-cleanup-plan.md
│   ├── bug-fixes/
│   │   └── windows-spaces-issue.md
│   ├── context/
│   │   ├── agent-sdk-v2-examples.ts
│   │   ├── agent-sdk-v2-preview.md
│   │   ├── cursor-hooks-reference.md
│   │   └── hooks-reference-2026-01-07.md
│   ├── i18n/
│   │   ├── .translation-cache.json
│   │   ├── README.ar.md
│   │   ├── README.bn.md
│   │   ├── README.cs.md
│   │   ├── README.da.md
│   │   ├── README.de.md
│   │   ├── README.el.md
│   │   ├── README.es.md
│   │   ├── README.fi.md
│   │   ├── README.fr.md
│   │   ├── README.he.md
│   │   ├── README.hi.md
│   │   ├── README.hu.md
│   │   ├── README.id.md
│   │   ├── README.it.md
│   │   ├── README.ja.md
│   │   ├── README.ko.md
│   │   ├── README.nl.md
│   │   ├── README.no.md
│   │   ├── README.pl.md
│   │   ├── README.pt-br.md
│   │   ├── README.ro.md
│   │   ├── README.ru.md
│   │   ├── README.sv.md
│   │   ├── README.th.md
│   │   ├── README.tl.md
│   │   ├── README.tr.md
│   │   ├── README.uk.md
│   │   ├── README.ur.md
│   │   ├── README.vi.md
│   │   ├── README.zh-tw.md
│   │   ├── README.zh.md
│   │   └── pt.md
│   ├── public/
│   │   ├── CLAUDE.md
│   │   ├── architecture/
│   │   │   ├── database.mdx
│   │   │   ├── hooks.mdx
│   │   │   ├── overview.mdx
│   │   │   ├── pm2-to-bun-migration.mdx
│   │   │   ├── search-architecture.mdx
│   │   │   └── worker-service.mdx
│   │   ├── architecture-evolution.mdx
│   │   ├── beta-features.mdx
│   │   ├── configuration.mdx
│   │   ├── context-engineering.mdx
│   │   ├── cursor/
│   │   │   ├── gemini-setup.mdx
│   │   │   ├── index.mdx
│   │   │   └── openrouter-setup.mdx
│   │   ├── development.mdx
│   │   ├── docs.json
│   │   ├── endless-mode.mdx
│   │   ├── hooks-architecture.mdx
│   │   ├── installation.mdx
│   │   ├── introduction.mdx
│   │   ├── modes.mdx
│   │   ├── openclaw-integration.mdx
│   │   ├── platform-integration.mdx
│   │   ├── progressive-disclosure.mdx
│   │   ├── smart-explore-benchmark.mdx
│   │   ├── troubleshooting.mdx
│   │   └── usage/
│   │       ├── claude-desktop.mdx
│   │       ├── export-import.mdx
│   │       ├── folder-context.mdx
│   │       ├── gemini-provider.mdx
│   │       ├── getting-started.mdx
│   │       ├── manual-recovery.mdx
│   │       ├── openrouter-provider.mdx
│   │       ├── private-tags.mdx
│   │       └── search-tools.mdx
│   └── reports/
│       ├── 2026-01-02--generator-failure-investigation.md
│       ├── 2026-01-02--observation-duplication-regression.md
│       ├── 2026-01-02--stuck-observations.md
│       ├── 2026-01-03--observation-saving-failure.md
│       ├── 2026-01-04--gemini-agent-failures.md
│       ├── 2026-01-04--issue-511-gemini-model-missing.md
│       ├── 2026-01-04--issue-514-orphaned-sessions-analysis.md
│       ├── 2026-01-04--issue-517-windows-powershell-analysis.md
│       ├── 2026-01-04--issue-520-stuck-messages-analysis.md
│       ├── 2026-01-04--issue-527-uv-homebrew-analysis.md
│       ├── 2026-01-04--issue-531-export-type-duplication.md
│       ├── 2026-01-04--issue-532-memory-leak-analysis.md
│       ├── 2026-01-04--logger-coverage-failures.md
│       ├── 2026-01-04--logging-analysis-and-recommendations.md
│       ├── 2026-01-04--session-id-refactor-failures.md
│       ├── 2026-01-04--session-id-validation-failures.md
│       ├── 2026-01-04--session-store-failures.md
│       ├── 2026-01-04--test-suite-report.md
│       ├── 2026-01-05--PR-556-brainstorming-claude-md-distribution.md
│       ├── 2026-01-05--context-hook-investigation.md
│       ├── 2026-01-05--issue-543-slash-command-unavailable.md
│       ├── 2026-01-05--issue-544-mem-search-hint-claude-code.md
│       ├── 2026-01-05--issue-545-formattool-json-parse-crash.md
│       ├── 2026-01-05--issue-555-windows-hooks-ipc-false.md
│       ├── 2026-01-05--issue-557-settings-module-loader-error.md
│       ├── 2026-01-06--windows-woes-comprehensive-report.md
│       ├── 2026-01-07--all-open-issues-explained.md
│       ├── 2026-01-07--open-issues-summary.md
│       ├── 2026-01-10--anti-pattern-czar-generalization-analysis.md
│       ├── intentional-patterns-validation.md
│       ├── issue-586-feature-request-unknown.md
│       ├── issue-587-observations-not-stored.md
│       ├── issue-588-api-key-usage-warning.md
│       ├── issue-590-windows-chroma-terminal-popup.md
│       ├── issue-591-openrouter-memorysessionid-capture.md
│       ├── issue-596-processtransport-not-ready.md
│       ├── issue-597-too-many-bugs.md
│       ├── issue-598-conversation-history-pollution.md
│       ├── issue-599-windows-drive-root-400-error.md
│       ├── issue-600-documentation-audit-features-not-implemented.md
│       ├── issue-602-posttooluse-worker-service-failed.md
│       ├── issue-603-worker-daemon-leaks-child-processes.md
│       ├── log-level-audit.txt
│       └── nonsense-logic.md
├── install/
│   ├── .gitignore
│   ├── public/
│   │   ├── install.sh
│   │   └── installer.js
│   └── vercel.json
├── installer/
│   ├── build.mjs
│   ├── dist/
│   │   └── index.js
│   ├── package.json
│   ├── src/
│   │   ├── index.ts
│   │   ├── steps/
│   │   │   ├── complete.ts
│   │   │   ├── dependencies.ts
│   │   │   ├── ide-selection.ts
│   │   │   ├── install.ts
│   │   │   ├── provider.ts
│   │   │   ├── settings.ts
│   │   │   ├── welcome.ts
│   │   │   └── worker.ts
│   │   └── utils/
│   │       ├── dependencies.ts
│   │       ├── settings-writer.ts
│   │       └── system.ts
│   └── tsconfig.json
├── openclaw/
│   ├── .gitignore
│   ├── Dockerfile.e2e
│   ├── SKILL.md
│   ├── TESTING.md
│   ├── e2e-verify.sh
│   ├── install.sh
│   ├── openclaw.plugin.json
│   ├── package.json
│   ├── src/
│   │   ├── index.test.ts
│   │   └── index.ts
│   ├── test-e2e.sh
│   ├── test-install.sh
│   ├── test-sse-consumer.js
│   └── tsconfig.json
├── package.json
├── plugin/
│   ├── .claude-plugin/
│   │   ├── CLAUDE.md
│   │   └── plugin.json
│   ├── CLAUDE.md
│   ├── hooks/
│   │   ├── CLAUDE.md
│   │   ├── bugfixes-2026-01-10.md
│   │   └── hooks.json
│   ├── modes/
│   │   ├── code--ar.json
│   │   ├── code--bn.json
│   │   ├── code--chill.json
│   │   ├── code--cs.json
│   │   ├── code--da.json
│   │   ├── code--de.json
│   │   ├── code--el.json
│   │   ├── code--es.json
│   │   ├── code--fi.json
│   │   ├── code--fr.json
│   │   ├── code--he.json
│   │   ├── code--hi.json
│   │   ├── code--hu.json
│   │   ├── code--id.json
│   │   ├── code--it.json
│   │   ├── code--ja.json
│   │   ├── code--ko.json
│   │   ├── code--nl.json
│   │   ├── code--no.json
│   │   ├── code--pl.json
│   │   ├── code--pt-br.json
│   │   ├── code--ro.json
│   │   ├── code--ru.json
│   │   ├── code--sv.json
│   │   ├── code--th.json
│   │   ├── code--tr.json
│   │   ├── code--uk.json
│   │   ├── code--ur.json
│   │   ├── code--vi.json
│   │   ├── code--zh.json
│   │   ├── code.json
│   │   ├── email-investigation.json
│   │   ├── law-study--chill.json
│   │   ├── law-study-CLAUDE.md
│   │   └── law-study.json
│   ├── package.json
│   ├── scripts/
│   │   ├── CLAUDE.md
│   │   ├── bun-runner.js
│   │   ├── claude-mem
│   │   ├── context-generator.cjs
│   │   ├── mcp-server.cjs
│   │   ├── smart-install.js
│   │   ├── statusline-counts.js
│   │   ├── worker-cli.js
│   │   ├── worker-service.cjs
│   │   └── worker-wrapper.cjs
│   ├── skills/
│   │   ├── do/
│   │   │   └── SKILL.md
│   │   ├── make-plan/
│   │   │   └── SKILL.md
│   │   ├── mem-search/
│   │   │   └── SKILL.md
│   │   ├── smart-explore/
│   │   │   └── SKILL.md
│   │   └── timeline-report/
│   │       └── SKILL.md
│   └── ui/
│       ├── CLAUDE.md
│       ├── viewer-bundle.js
│       └── viewer.html
├── ragtime/
│   ├── CLAUDE.md
│   ├── LICENSE
│   ├── README.md
│   └── ragtime.ts
├── scripts/
│   ├── CLAUDE.md
│   ├── analyze-transformations-smart.js
│   ├── anti-pattern-test/
│   │   ├── CLAUDE.md
│   │   └── detect-error-handling-antipatterns.ts
│   ├── bug-report/
│   │   ├── cli.ts
│   │   ├── collector.ts
│   │   └── index.ts
│   ├── build-hooks.js
│   ├── build-viewer.js
│   ├── build-worker-binary.js
│   ├── check-pending-queue.ts
│   ├── cleanup-duplicates.ts
│   ├── clear-failed-queue.ts
│   ├── debug-transcript-structure.ts
│   ├── discord-release-notify.js
│   ├── dump-transcript-readable.ts
│   ├── endless-mode-token-calculator.js
│   ├── export-memories.ts
│   ├── extract-prompts-to-yaml.cjs
│   ├── extract-rich-context-examples.ts
│   ├── extraction/
│   │   ├── README.md
│   │   ├── extract-all-xml.py
│   │   └── filter-actual-xml.py
│   ├── find-silent-failures.sh
│   ├── fix-all-timestamps.ts
│   ├── fix-corrupted-timestamps.ts
│   ├── format-transcript-context.ts
│   ├── generate-changelog.js
│   ├── import-memories.ts
│   ├── investigate-timestamps.ts
│   ├── publish.js
│   ├── regenerate-claude-md.ts
│   ├── smart-install.js
│   ├── sync-marketplace.cjs
│   ├── sync-to-marketplace.sh
│   ├── test-transcript-parser.ts
│   ├── transcript-to-markdown.ts
│   ├── translate-readme/
│   │   ├── README.md
│   │   ├── cli.ts
│   │   ├── examples.ts
│   │   └── index.ts
│   ├── types/
│   │   └── export.ts
│   ├── validate-timestamp-logic.ts
│   ├── verify-timestamp-fix.ts
│   └── wipe-chroma.cjs
├── src/
│   ├── CLAUDE.md
│   ├── bin/
│   │   ├── cleanup-duplicates.ts
│   │   └── import-xml-observations.ts
│   ├── cli/
│   │   ├── CLAUDE.md
│   │   ├── adapters/
│   │   │   ├── CLAUDE.md
│   │   │   ├── claude-code.ts
│   │   │   ├── cursor.ts
│   │   │   ├── gemini-cli.ts
│   │   │   ├── index.ts
│   │   │   └── raw.ts
│   │   ├── claude-md-commands.ts
│   │   ├── handlers/
│   │   │   ├── CLAUDE.md
│   │   │   ├── context.ts
│   │   │   ├── file-edit.ts
│   │   │   ├── index.ts
│   │   │   ├── observation.ts
│   │   │   ├── session-complete.ts
│   │   │   ├── session-init.ts
│   │   │   ├── summarize.ts
│   │   │   └── user-message.ts
│   │   ├── hook-command.ts
│   │   ├── stdin-reader.ts
│   │   └── types.ts
│   ├── hooks/
│   │   └── hook-response.ts
│   ├── sdk/
│   │   ├── index.ts
│   │   ├── parser.ts
│   │   └── prompts.ts
│   ├── servers/
│   │   └── mcp-server.ts
│   ├── services/
│   │   ├── CLAUDE.md
│   │   ├── Context.ts
│   │   ├── context/
│   │   │   ├── ContextBuilder.ts
│   │   │   ├── ContextConfigLoader.ts
│   │   │   ├── ObservationCompiler.ts
│   │   │   ├── TokenCalculator.ts
│   │   │   ├── formatters/
│   │   │   │   ├── ColorFormatter.ts
│   │   │   │   └── MarkdownFormatter.ts
│   │   │   ├── index.ts
│   │   │   ├── sections/
│   │   │   │   ├── FooterRenderer.ts
│   │   │   │   ├── HeaderRenderer.ts
│   │   │   │   ├── SummaryRenderer.ts
│   │   │   │   └── TimelineRenderer.ts
│   │   │   └── types.ts
│   │   ├── context-generator.ts
│   │   ├── domain/
│   │   │   ├── CLAUDE.md
│   │   │   ├── ModeManager.ts
│   │   │   └── types.ts
│   │   ├── infrastructure/
│   │   │   ├── CLAUDE.md
│   │   │   ├── GracefulShutdown.ts
│   │   │   ├── HealthMonitor.ts
│   │   │   ├── ProcessManager.ts
│   │   │   └── index.ts
│   │   ├── integrations/
│   │   │   ├── CursorHooksInstaller.ts
│   │   │   ├── index.ts
│   │   │   └── types.ts
│   │   ├── queue/
│   │   │   └── SessionQueueProcessor.ts
│   │   ├── server/
│   │   │   ├── ErrorHandler.ts
│   │   │   ├── Middleware.ts
│   │   │   ├── Server.ts
│   │   │   ├── allowed-constants.ts
│   │   │   └── index.ts
│   │   ├── smart-file-read/
│   │   │   ├── parser.ts
│   │   │   └── search.ts
│   │   ├── sqlite/
│   │   │   ├── CLAUDE.md
│   │   │   ├── Database.ts
│   │   │   ├── Import.ts
│   │   │   ├── Observations.ts
│   │   │   ├── PendingMessageStore.ts
│   │   │   ├── Prompts.ts
│   │   │   ├── SessionSearch.ts
│   │   │   ├── SessionStore.ts
│   │   │   ├── Sessions.ts
│   │   │   ├── Summaries.ts
│   │   │   ├── Timeline.ts
│   │   │   ├── import/
│   │   │   │   └── bulk.ts
│   │   │   ├── index.ts
│   │   │   ├── migrations/
│   │   │   │   └── runner.ts
│   │   │   ├── migrations.ts
│   │   │   ├── observations/
│   │   │   │   ├── files.ts
│   │   │   │   ├── get.ts
│   │   │   │   ├── recent.ts
│   │   │   │   ├── store.ts
│   │   │   │   └── types.ts
│   │   │   ├── prompts/
│   │   │   │   ├── get.ts
│   │   │   │   ├── store.ts
│   │   │   │   └── types.ts
│   │   │   ├── sessions/
│   │   │   │   ├── create.ts
│   │   │   │   ├── get.ts
│   │   │   │   └── types.ts
│   │   │   ├── summaries/
│   │   │   │   ├── get.ts
│   │   │   │   ├── recent.ts
│   │   │   │   ├── store.ts
│   │   │   │   └── types.ts
│   │   │   ├── timeline/
│   │   │   │   └── queries.ts
│   │   │   ├── transactions.ts
│   │   │   └── types.ts
│   │   ├── sync/
│   │   │   ├── ChromaMcpManager.ts
│   │   │   └── ChromaSync.ts
│   │   ├── transcripts/
│   │   │   ├── cli.ts
│   │   │   ├── config.ts
│   │   │   ├── field-utils.ts
│   │   │   ├── processor.ts
│   │   │   ├── state.ts
│   │   │   ├── types.ts
│   │   │   └── watcher.ts
│   │   ├── worker/
│   │   │   ├── BranchManager.ts
│   │   │   ├── CLAUDE.md
│   │   │   ├── DatabaseManager.ts
│   │   │   ├── FormattingService.ts
│   │   │   ├── GeminiAgent.ts
│   │   │   ├── OpenRouterAgent.ts
│   │   │   ├── PaginationHelper.ts
│   │   │   ├── ProcessRegistry.ts
│   │   │   ├── README.md
│   │   │   ├── SDKAgent.ts
│   │   │   ├── SSEBroadcaster.ts
│   │   │   ├── Search.ts
│   │   │   ├── SearchManager.ts
│   │   │   ├── SessionManager.ts
│   │   │   ├── SettingsManager.ts
│   │   │   ├── TimelineService.ts
│   │   │   ├── agents/
│   │   │   │   ├── FallbackErrorHandler.ts
│   │   │   │   ├── ObservationBroadcaster.ts
│   │   │   │   ├── ResponseProcessor.ts
│   │   │   │   ├── SessionCleanupHelper.ts
│   │   │   │   ├── index.ts
│   │   │   │   └── types.ts
│   │   │   ├── events/
│   │   │   │   └── SessionEventBroadcaster.ts
│   │   │   ├── http/
│   │   │   │   ├── BaseRouteHandler.ts
│   │   │   │   ├── middleware.ts
│   │   │   │   └── routes/
│   │   │   │       ├── DataRoutes.ts
│   │   │   │       ├── LogsRoutes.ts
│   │   │   │       ├── MemoryRoutes.ts
│   │   │   │       ├── SearchRoutes.ts
│   │   │   │       ├── SessionRoutes.ts
│   │   │   │       ├── SettingsRoutes.ts
│   │   │   │       └── ViewerRoutes.ts
│   │   │   ├── search/
│   │   │   │   ├── ResultFormatter.ts
│   │   │   │   ├── SearchOrchestrator.ts
│   │   │   │   ├── TimelineBuilder.ts
│   │   │   │   ├── filters/
│   │   │   │   │   ├── DateFilter.ts
│   │   │   │   │   ├── ProjectFilter.ts
│   │   │   │   │   └── TypeFilter.ts
│   │   │   │   ├── index.ts
│   │   │   │   ├── strategies/
│   │   │   │   │   ├── ChromaSearchStrategy.ts
│   │   │   │   │   ├── HybridSearchStrategy.ts
│   │   │   │   │   ├── SQLiteSearchStrategy.ts
│   │   │   │   │   └── SearchStrategy.ts
│   │   │   │   └── types.ts
│   │   │   ├── session/
│   │   │   │   └── SessionCompletionHandler.ts
│   │   │   └── validation/
│   │   │       └── PrivacyCheckValidator.ts
│   │   ├── worker-service.ts
│   │   └── worker-types.ts
│   ├── shared/
│   │   ├── CLAUDE.md
│   │   ├── EnvManager.ts
│   │   ├── SettingsDefaultsManager.ts
│   │   ├── hook-constants.ts
│   │   ├── path-utils.ts
│   │   ├── paths.ts
│   │   ├── plugin-state.ts
│   │   ├── timeline-formatting.ts
│   │   ├── transcript-parser.ts
│   │   └── worker-utils.ts
│   ├── supervisor/
│   │   ├── env-sanitizer.ts
│   │   ├── health-checker.ts
│   │   ├── index.ts
│   │   ├── process-registry.ts
│   │   └── shutdown.ts
│   ├── types/
│   │   ├── database.ts
│   │   ├── transcript.ts
│   │   └── tree-kill.d.ts
│   ├── ui/
│   │   ├── viewer/
│   │   │   ├── App.tsx
│   │   │   ├── components/
│   │   │   │   ├── ContextSettingsModal.tsx
│   │   │   │   ├── ErrorBoundary.tsx
│   │   │   │   ├── Feed.tsx
│   │   │   │   ├── GitHubStarsButton.tsx
│   │   │   │   ├── Header.tsx
│   │   │   │   ├── LogsModal.tsx
│   │   │   │   ├── ObservationCard.tsx
│   │   │   │   ├── PromptCard.tsx
│   │   │   │   ├── ScrollToTop.tsx
│   │   │   │   ├── SummaryCard.tsx
│   │   │   │   ├── TerminalPreview.tsx
│   │   │   │   └── ThemeToggle.tsx
│   │   │   ├── constants/
│   │   │   │   ├── CLAUDE.md
│   │   │   │   ├── api.ts
│   │   │   │   ├── settings.ts
│   │   │   │   ├── timing.ts
│   │   │   │   └── ui.ts
│   │   │   ├── hooks/
│   │   │   │   ├── useContextPreview.ts
│   │   │   │   ├── useGitHubStars.ts
│   │   │   │   ├── usePagination.ts
│   │   │   │   ├── useSSE.ts
│   │   │   │   ├── useSettings.ts
│   │   │   │   ├── useSpinningFavicon.ts
│   │   │   │   ├── useStats.ts
│   │   │   │   └── useTheme.ts
│   │   │   ├── index.tsx
│   │   │   ├── types.ts
│   │   │   └── utils/
│   │   │       ├── data.ts
│   │   │       ├── formatNumber.ts
│   │   │       └── formatters.ts
│   │   └── viewer-template.html
│   └── utils/
│       ├── CLAUDE.md
│       ├── agents-md-utils.ts
│       ├── bun-path.ts
│       ├── claude-md-utils.ts
│       ├── cursor-utils.ts
│       ├── error-messages.ts
│       ├── logger.ts
│       ├── project-filter.ts
│       ├── project-name.ts
│       ├── tag-stripping.ts
│       ├── transcript-parser.ts
│       └── worktree.ts
├── tests/
│   ├── CLAUDE.md
│   ├── context/
│   │   ├── formatters/
│   │   │   └── markdown-formatter.test.ts
│   │   ├── observation-compiler.test.ts
│   │   └── token-calculator.test.ts
│   ├── cursor-context-update.test.ts
│   ├── cursor-hooks-json-utils.test.ts
│   ├── cursor-mcp-config.test.ts
│   ├── cursor-registry.test.ts
│   ├── fk-constraint-fix.test.ts
│   ├── gemini_agent.test.ts
│   ├── hook-command.test.ts
│   ├── hook-constants.test.ts
│   ├── hook-lifecycle.test.ts
│   ├── hooks/
│   │   └── context-reinjection-guard.test.ts
│   ├── infrastructure/
│   │   ├── CLAUDE.md
│   │   ├── graceful-shutdown.test.ts
│   │   ├── health-monitor.test.ts
│   │   ├── plugin-disabled-check.test.ts
│   │   ├── plugin-distribution.test.ts
│   │   ├── process-manager.test.ts
│   │   ├── version-consistency.test.ts
│   │   ├── wmic-parsing.test.ts
│   │   └── worker-json-status.test.ts
│   ├── integration/
│   │   ├── chroma-vector-sync.test.ts
│   │   ├── hook-execution-e2e.test.ts
│   │   └── worker-api-endpoints.test.ts
│   ├── log-level-audit.test.ts
│   ├── logger-usage-standards.test.ts
│   ├── sdk-agent-resume.test.ts
│   ├── server/
│   │   ├── error-handler.test.ts
│   │   └── server.test.ts
│   ├── services/
│   │   ├── logs-routes-tail-read.test.ts
│   │   ├── queue/
│   │   │   └── SessionQueueProcessor.test.ts
│   │   ├── sqlite/
│   │   │   ├── PendingMessageStore.test.ts
│   │   │   ├── migration-runner.test.ts
│   │   │   ├── schema-repair.test.ts
│   │   │   └── session-search-path-matching.test.ts
│   │   ├── stale-abort-controller-guard.test.ts
│   │   └── sync/
│   │       └── chroma-mcp-manager-ssl.test.ts
│   ├── session_id_usage_validation.test.ts
│   ├── session_store.test.ts
│   ├── shared/
│   │   ├── settings-defaults-manager.test.ts
│   │   └── timeline-formatting.test.ts
│   ├── smart-install.test.ts
│   ├── sqlite/
│   │   ├── data-integrity.test.ts
│   │   ├── observations.test.ts
│   │   ├── prompts.test.ts
│   │   ├── sessions.test.ts
│   │   ├── summaries.test.ts
│   │   └── transactions.test.ts
│   ├── supervisor/
│   │   ├── env-sanitizer.test.ts
│   │   ├── health-checker.test.ts
│   │   ├── index.test.ts
│   │   ├── process-registry.test.ts
│   │   └── shutdown.test.ts
│   ├── utils/
│   │   ├── CLAUDE.md
│   │   ├── claude-md-utils.test.ts
│   │   ├── logger-format-tool.test.ts
│   │   ├── project-filter.test.ts
│   │   └── tag-stripping.test.ts
│   ├── worker/
│   │   ├── agents/
│   │   │   ├── fallback-error-handler.test.ts
│   │   │   ├── response-processor.test.ts
│   │   │   └── session-cleanup-helper.test.ts
│   │   ├── http/
│   │   │   └── routes/
│   │   │       └── data-routes-coercion.test.ts
│   │   ├── middleware/
│   │   │   └── cors-restriction.test.ts
│   │   ├── process-registry.test.ts
│   │   └── search/
│   │       ├── result-formatter.test.ts
│   │       ├── search-orchestrator.test.ts
│   │       └── strategies/
│   │           ├── chroma-search-strategy.test.ts
│   │           ├── hybrid-search-strategy.test.ts
│   │           └── sqlite-search-strategy.test.ts
│   ├── worker-spawn.test.ts
│   └── zombie-prevention.test.ts
├── transcript-watch.example.json
└── tsconfig.json
Download .txt
Showing preview only (739K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (6898 symbols across 271 files)

FILE: docs/context/agent-sdk-v2-examples.ts
  function main (line 14) | async function main() {
  function basicSession (line 36) | async function basicSession() {
  function multiTurn (line 51) | async function multiTurn() {
  function oneShot (line 76) | async function oneShot() {
  function sessionResume (line 88) | async function sessionResume() {

FILE: install/public/installer.js
  method "node_modules/picocolors/picocolors.js" (line 30) | "node_modules/picocolors/picocolors.js"(exports, module) {
  method "node_modules/sisteransi/src/index.js" (line 102) | "node_modules/sisteransi/src/index.js"(exports, module) {
  function B (line 163) | function B(t, e2, s) {
  function K (line 327) | function K(t, e2, s) {
  function H (line 336) | function H(t, e2) {
  function _t (line 341) | function _t(t, e2) {
  function Ct (line 351) | function Ct(t) {
  function T (line 354) | function T(t, e2) {
  function Bt (line 358) | function Bt({ input: t = q, output: e2 = R, overwrite: s = true, hideCur...
  function xt (line 381) | function xt(t, e2, s, i = s) {
  method constructor (line 402) | constructor(e2, s = true) {
  method unsubscribe (line 406) | unsubscribe() {
  method setSubscriber (line 409) | setSubscriber(e2, s) {
  method on (line 413) | on(e2, s) {
  method once (line 416) | once(e2, s) {
  method emit (line 419) | emit(e2, ...s) {
  method prompt (line 424) | prompt() {
  method _isActionKey (line 439) | _isActionKey(e2, s) {
  method _setValue (line 442) | _setValue(e2) {
  method _setUserInput (line 445) | _setUserInput(e2, s) {
  method _clearUserInput (line 448) | _clearUserInput() {
  method onKeypress (line 451) | onKeypress(e2, s) {
  method close (line 461) | close() {
  method restoreCursor (line 465) | restoreCursor() {
  method render (line 470) | render() {
  method cursor (line 510) | get cursor() {
  method _value (line 513) | get _value() {
  method constructor (line 516) | constructor(e2) {
  method _value (line 529) | get _value() {
  method _enabledOptions (line 532) | get _enabledOptions() {
  method toggleAll (line 535) | toggleAll() {
  method toggleInvert (line 539) | toggleInvert() {
  method toggleValue (line 545) | toggleValue() {
  method constructor (line 550) | constructor(e2) {
  method cursor (line 574) | get cursor() {
  method masked (line 577) | get masked() {
  method userInputWithCursor (line 580) | get userInputWithCursor() {
  method clear (line 587) | clear() {
  method constructor (line 590) | constructor({ mask: e2, ...s }) {
  method _selectedValue (line 599) | get _selectedValue() {
  method changeValue (line 602) | changeValue() {
  method constructor (line 605) | constructor(e2) {
  method userInputWithCursor (line 624) | get userInputWithCursor() {
  method cursor (line 631) | get cursor() {
  method constructor (line 634) | constructor(e2) {
  function me (line 647) | function me() {
  function J2 (line 863) | function J2(t, r, s) {
  method render (line 904) | render() {
  method validate (line 978) | validate(i) {
  method render (line 981) | render() {
  method render (line 1042) | render() {
  method isCancelled (line 1120) | get isCancelled() {
  method render (line 1145) | render() {
  method render (line 1180) | render() {
  function detectOS (line 1218) | function detectOS() {
  function commandExists (line 1228) | function commandExists(command) {
  function runCommand (line 1236) | function runCommand(command, args = []) {
  function expandHome (line 1249) | function expandHome(filepath) {
  function runWelcome (line 1257) | async function runWelcome() {
  function findBinary (line 1291) | function findBinary(name, extraPaths = []) {
  function parseVersion (line 1314) | function parseVersion(output) {
  function compareVersions (line 1319) | function compareVersions(current, minimum) {
  function installBun (line 1330) | function installBun() {
  function installUv (line 1338) | function installUv() {
  function runDependencyChecks (line 1350) | async function runDependencyChecks() {
  function runIdeSelection (line 1492) | async function runIdeSelection() {
  function runProviderConfiguration (line 1518) | async function runProviderConfiguration() {
  function runSettingsConfiguration (line 1623) | async function runSettingsConfiguration() {
  function expandDataDir (line 1797) | function expandDataDir(dataDir) {
  function buildSettingsObject (line 1803) | function buildSettingsObject(providerConfig, settingsConfig) {
  function writeSettings (line 1835) | function writeSettings(providerConfig, settingsConfig) {
  function ensureDir (line 1860) | function ensureDir(directoryPath) {
  function readJsonFile (line 1865) | function readJsonFile(filepath) {
  function writeJsonFile (line 1869) | function writeJsonFile(filepath, data) {
  function registerMarketplace (line 1873) | function registerMarketplace() {
  function registerPlugin (line 1888) | function registerPlugin(version) {
  function enablePluginInClaudeSettings (line 1911) | function enablePluginInClaudeSettings() {
  function getPluginVersion (line 1917) | function getPluginVersion() {
  function runInstallation (line 1925) | async function runInstallation(selectedIDEs) {
  function pollHealthEndpoint (line 1995) | async function pollHealthEndpoint(port, maxAttempts = HEALTH_CHECK_MAX_A...
  function runWorkerStartup (line 2006) | async function runWorkerStartup(workerPort, dataDir) {
  function getProviderLabel (line 2041) | function getProviderLabel(config) {
  function getIDELabels (line 2051) | function getIDELabels(ides) {
  function runCompletion (line 2061) | function runCompletion(providerConfig, settingsConfig, selectedIDEs) {
  function runInstaller (line 2084) | async function runInstaller() {

FILE: installer/dist/index.js
  method "node_modules/picocolors/picocolors.js" (line 30) | "node_modules/picocolors/picocolors.js"(exports, module) {
  method "node_modules/sisteransi/src/index.js" (line 102) | "node_modules/sisteransi/src/index.js"(exports, module) {
  function B (line 163) | function B(t, e2, s) {
  function K (line 327) | function K(t, e2, s) {
  function H (line 336) | function H(t, e2) {
  function _t (line 341) | function _t(t, e2) {
  function Ct (line 351) | function Ct(t) {
  function T (line 354) | function T(t, e2) {
  function Bt (line 358) | function Bt({ input: t = q, output: e2 = R, overwrite: s = true, hideCur...
  function xt (line 381) | function xt(t, e2, s, i = s) {
  method constructor (line 402) | constructor(e2, s = true) {
  method unsubscribe (line 406) | unsubscribe() {
  method setSubscriber (line 409) | setSubscriber(e2, s) {
  method on (line 413) | on(e2, s) {
  method once (line 416) | once(e2, s) {
  method emit (line 419) | emit(e2, ...s) {
  method prompt (line 424) | prompt() {
  method _isActionKey (line 439) | _isActionKey(e2, s) {
  method _setValue (line 442) | _setValue(e2) {
  method _setUserInput (line 445) | _setUserInput(e2, s) {
  method _clearUserInput (line 448) | _clearUserInput() {
  method onKeypress (line 451) | onKeypress(e2, s) {
  method close (line 461) | close() {
  method restoreCursor (line 465) | restoreCursor() {
  method render (line 470) | render() {
  method cursor (line 510) | get cursor() {
  method _value (line 513) | get _value() {
  method constructor (line 516) | constructor(e2) {
  method _value (line 529) | get _value() {
  method _enabledOptions (line 532) | get _enabledOptions() {
  method toggleAll (line 535) | toggleAll() {
  method toggleInvert (line 539) | toggleInvert() {
  method toggleValue (line 545) | toggleValue() {
  method constructor (line 550) | constructor(e2) {
  method cursor (line 574) | get cursor() {
  method masked (line 577) | get masked() {
  method userInputWithCursor (line 580) | get userInputWithCursor() {
  method clear (line 587) | clear() {
  method constructor (line 590) | constructor({ mask: e2, ...s }) {
  method _selectedValue (line 599) | get _selectedValue() {
  method changeValue (line 602) | changeValue() {
  method constructor (line 605) | constructor(e2) {
  method userInputWithCursor (line 624) | get userInputWithCursor() {
  method cursor (line 631) | get cursor() {
  method constructor (line 634) | constructor(e2) {
  function me (line 647) | function me() {
  function J2 (line 863) | function J2(t, r, s) {
  method render (line 904) | render() {
  method validate (line 978) | validate(i) {
  method render (line 981) | render() {
  method render (line 1042) | render() {
  method isCancelled (line 1120) | get isCancelled() {
  method render (line 1145) | render() {
  method render (line 1180) | render() {
  function detectOS (line 1218) | function detectOS() {
  function commandExists (line 1228) | function commandExists(command) {
  function runCommand (line 1236) | function runCommand(command, args = []) {
  function expandHome (line 1249) | function expandHome(filepath) {
  function runWelcome (line 1257) | async function runWelcome() {
  function findBinary (line 1291) | function findBinary(name, extraPaths = []) {
  function parseVersion (line 1314) | function parseVersion(output) {
  function compareVersions (line 1319) | function compareVersions(current, minimum) {
  function installBun (line 1330) | function installBun() {
  function installUv (line 1338) | function installUv() {
  function runDependencyChecks (line 1350) | async function runDependencyChecks() {
  function runIdeSelection (line 1492) | async function runIdeSelection() {
  function runProviderConfiguration (line 1518) | async function runProviderConfiguration() {
  function runSettingsConfiguration (line 1623) | async function runSettingsConfiguration() {
  function expandDataDir (line 1797) | function expandDataDir(dataDir) {
  function buildSettingsObject (line 1803) | function buildSettingsObject(providerConfig, settingsConfig) {
  function writeSettings (line 1835) | function writeSettings(providerConfig, settingsConfig) {
  function ensureDir (line 1860) | function ensureDir(directoryPath) {
  function readJsonFile (line 1865) | function readJsonFile(filepath) {
  function writeJsonFile (line 1869) | function writeJsonFile(filepath, data) {
  function registerMarketplace (line 1873) | function registerMarketplace() {
  function registerPlugin (line 1888) | function registerPlugin(version) {
  function enablePluginInClaudeSettings (line 1911) | function enablePluginInClaudeSettings() {
  function getPluginVersion (line 1917) | function getPluginVersion() {
  function runInstallation (line 1925) | async function runInstallation(selectedIDEs) {
  function pollHealthEndpoint (line 1995) | async function pollHealthEndpoint(port, maxAttempts = HEALTH_CHECK_MAX_A...
  function runWorkerStartup (line 2006) | async function runWorkerStartup(workerPort, dataDir) {
  function getProviderLabel (line 2041) | function getProviderLabel(config) {
  function getIDELabels (line 2051) | function getIDELabels(ides) {
  function runCompletion (line 2061) | function runCompletion(providerConfig, settingsConfig, selectedIDEs) {
  function runInstaller (line 2084) | async function runInstaller() {

FILE: installer/src/index.ts
  function runInstaller (line 12) | async function runInstaller(): Promise<void> {

FILE: installer/src/steps/complete.ts
  function getProviderLabel (line 7) | function getProviderLabel(config: ProviderConfig): string {
  function getIDELabels (line 18) | function getIDELabels(ides: IDE[]): string {
  function runCompletion (line 27) | function runCompletion(

FILE: installer/src/steps/dependencies.ts
  constant BUN_EXTRA_PATHS (line 6) | const BUN_EXTRA_PATHS = ['~/.bun/bin/bun', '/usr/local/bin/bun', '/opt/h...
  constant UV_EXTRA_PATHS (line 7) | const UV_EXTRA_PATHS = ['~/.local/bin/uv', '~/.cargo/bin/uv'];
  type DependencyStatus (line 9) | interface DependencyStatus {
  function runDependencyChecks (line 18) | async function runDependencyChecks(): Promise<DependencyStatus> {

FILE: installer/src/steps/ide-selection.ts
  type IDE (line 3) | type IDE = 'claude-code' | 'cursor';
  function runIdeSelection (line 5) | async function runIdeSelection(): Promise<IDE[]> {

FILE: installer/src/steps/install.ts
  constant MARKETPLACE_DIR (line 9) | const MARKETPLACE_DIR = join(homedir(), '.claude', 'plugins', 'marketpla...
  constant PLUGINS_DIR (line 10) | const PLUGINS_DIR = join(homedir(), '.claude', 'plugins');
  constant CLAUDE_SETTINGS_PATH (line 11) | const CLAUDE_SETTINGS_PATH = join(homedir(), '.claude', 'settings.json');
  function ensureDir (line 13) | function ensureDir(directoryPath: string): void {
  function readJsonFile (line 19) | function readJsonFile(filepath: string): any {
  function writeJsonFile (line 24) | function writeJsonFile(filepath: string, data: any): void {
  function registerMarketplace (line 29) | function registerMarketplace(): void {
  function registerPlugin (line 47) | function registerPlugin(version: string): void {
  function enablePluginInClaudeSettings (line 77) | function enablePluginInClaudeSettings(): void {
  function getPluginVersion (line 86) | function getPluginVersion(): string {
  function runInstallation (line 95) | async function runInstallation(selectedIDEs: IDE[]): Promise<void> {

FILE: installer/src/steps/provider.ts
  type ProviderType (line 4) | type ProviderType = 'claude' | 'gemini' | 'openrouter';
  type ClaudeAuthMethod (line 5) | type ClaudeAuthMethod = 'cli' | 'api';
  type ProviderConfig (line 7) | interface ProviderConfig {
  function runProviderConfiguration (line 15) | async function runProviderConfiguration(): Promise<ProviderConfig> {

FILE: installer/src/steps/settings.ts
  type SettingsConfig (line 4) | interface SettingsConfig {
  function runSettingsConfiguration (line 17) | async function runSettingsConfiguration(): Promise<SettingsConfig> {

FILE: installer/src/steps/welcome.ts
  type InstallMode (line 6) | type InstallMode = 'fresh' | 'upgrade' | 'configure';
  function runWelcome (line 8) | async function runWelcome(): Promise<InstallMode> {

FILE: installer/src/steps/worker.ts
  constant MARKETPLACE_DIR (line 9) | const MARKETPLACE_DIR = join(homedir(), '.claude', 'plugins', 'marketpla...
  constant HEALTH_CHECK_INTERVAL_MS (line 11) | const HEALTH_CHECK_INTERVAL_MS = 1000;
  constant HEALTH_CHECK_MAX_ATTEMPTS (line 12) | const HEALTH_CHECK_MAX_ATTEMPTS = 30;
  function pollHealthEndpoint (line 14) | async function pollHealthEndpoint(port: string, maxAttempts: number = HE...
  function runWorkerStartup (line 27) | async function runWorkerStartup(workerPort: string, dataDir: string): Pr...

FILE: installer/src/utils/dependencies.ts
  type BinaryInfo (line 5) | interface BinaryInfo {
  function findBinary (line 11) | function findBinary(name: string, extraPaths: string[] = []): BinaryInfo {
  function parseVersion (line 39) | function parseVersion(output: string): string | null {
  function compareVersions (line 45) | function compareVersions(current: string, minimum: string): boolean {
  function installBun (line 58) | function installBun(): void {
  function installUv (line 67) | function installUv(): void {

FILE: installer/src/utils/settings-writer.ts
  function expandDataDir (line 7) | function expandDataDir(dataDir: string): string {
  function buildSettingsObject (line 14) | function buildSettingsObject(
  function writeSettings (line 57) | function writeSettings(

FILE: installer/src/utils/system.ts
  type OSType (line 5) | type OSType = 'macos' | 'linux' | 'windows';
  function detectOS (line 7) | function detectOS(): OSType {
  function commandExists (line 15) | function commandExists(command: string): boolean {
  type CommandResult (line 24) | interface CommandResult {
  function runCommand (line 30) | function runCommand(command: string, args: string[] = []): CommandResult {
  function expandHome (line 44) | function expandHome(filepath: string): string {

FILE: openclaw/src/index.test.ts
  function createMockApi (line 9) | function createMockApi(pluginConfigOverride: Record<string, any> = {}) {
  function startWorkerMock (line 229) | function startWorkerMock(): Promise<number> {
  function startWorkerMock (line 547) | function startWorkerMock(): Promise<number> {
  function startSSEServer (line 780) | function startSSEServer(): Promise<number> {

FILE: openclaw/src/index.ts
  type PluginLogger (line 8) | interface PluginLogger {
  type PluginServiceContext (line 15) | interface PluginServiceContext {
  type PluginCommandContext (line 22) | interface PluginCommandContext {
  type PluginCommandResult (line 31) | type PluginCommandResult = string | { text: string } | { text: string; f...
  type BeforeAgentStartEvent (line 34) | interface BeforeAgentStartEvent {
  type BeforePromptBuildEvent (line 38) | interface BeforePromptBuildEvent {
  type BeforePromptBuildResult (line 43) | interface BeforePromptBuildResult {
  type ToolResultPersistEvent (line 50) | interface ToolResultPersistEvent {
  type AgentEndEvent (line 58) | interface AgentEndEvent {
  type SessionStartEvent (line 65) | interface SessionStartEvent {
  type AfterCompactionEvent (line 70) | interface AfterCompactionEvent {
  type SessionEndEvent (line 76) | interface SessionEndEvent {
  type MessageReceivedEvent (line 82) | interface MessageReceivedEvent {
  type EventContext (line 89) | interface EventContext {
  type MessageContext (line 95) | interface MessageContext {
  type EventCallback (line 101) | type EventCallback<T> = (event: T, ctx: EventContext) => void | Promise<...
  type PromptBuildCallback (line 102) | type PromptBuildCallback = (event: BeforePromptBuildEvent, ctx: EventCon...
  type MessageEventCallback (line 103) | type MessageEventCallback<T> = (event: T, ctx: MessageContext) => void |...
  type OpenClawPluginApi (line 105) | interface OpenClawPluginApi {
  type ObservationSSEPayload (line 143) | interface ObservationSSEPayload {
  type SSENewObservationEvent (line 161) | interface SSENewObservationEvent {
  type ConnectionState (line 167) | type ConnectionState = "disconnected" | "connected" | "reconnecting";
  type FeedEmojiConfig (line 173) | interface FeedEmojiConfig {
  type ClaudeMemPluginConfig (line 181) | interface ClaudeMemPluginConfig {
  constant MAX_SSE_BUFFER_SIZE (line 199) | const MAX_SSE_BUFFER_SIZE = 1024 * 1024;
  constant DEFAULT_WORKER_PORT (line 200) | const DEFAULT_WORKER_PORT = 37777;
  constant EMOJI_POOL (line 204) | const EMOJI_POOL = [
  function poolEmojiForAgent (line 209) | function poolEmojiForAgent(agentId: string): string {
  constant DEFAULT_PRIMARY_EMOJI (line 218) | const DEFAULT_PRIMARY_EMOJI = "🦞";
  constant DEFAULT_CLAUDE_CODE_EMOJI (line 219) | const DEFAULT_CLAUDE_CODE_EMOJI = "⌨️";
  constant DEFAULT_CLAUDE_CODE_LABEL (line 220) | const DEFAULT_CLAUDE_CODE_LABEL = "Claude Code Session";
  constant DEFAULT_FALLBACK_EMOJI (line 221) | const DEFAULT_FALLBACK_EMOJI = "🦀";
  function buildGetSourceLabel (line 223) | function buildGetSourceLabel(
  function workerBaseUrl (line 259) | function workerBaseUrl(port: number): string {
  function workerPost (line 263) | async function workerPost(
  function workerPostFireAndForget (line 287) | function workerPostFireAndForget(
  function workerGetText (line 303) | async function workerGetText(
  function workerGetJson (line 322) | async function workerGetJson(
  function formatObservationMessage (line 342) | function formatObservationMessage(
  constant CHANNEL_SEND_MAP (line 357) | const CHANNEL_SEND_MAP: Record<string, { namespace: string; functionName...
  function sendDirectTelegram (line 367) | async function sendDirectTelegram(
  function sendToChannel (line 393) | function sendToChannel(
  function connectToSSEStream (line 434) | async function connectToSSEStream(
  function claudeMemPlugin (line 533) | function claudeMemPlugin(api: OpenClawPluginApi): void {

FILE: plugin/scripts/bun-runner.js
  constant IS_WINDOWS (line 20) | const IS_WINDOWS = process.platform === 'win32';
  constant RESOLVED_PLUGIN_ROOT (line 28) | const RESOLVED_PLUGIN_ROOT = process.env.CLAUDE_PLUGIN_ROOT || resolve(_...
  function fixBrokenScriptPath (line 36) | function fixBrokenScriptPath(argPath) {
  function findBun (line 49) | function findBun() {
  function isPluginDisabledInClaudeSettings (line 84) | function isPluginDisabledInClaudeSettings() {
  function collectStdin (line 124) | function collectStdin() {

FILE: plugin/scripts/context-generator.cjs
  method constructor (line 1) | constructor(){this.useColor=process.stdout.isTTY??!1}
  method ensureLogFileInitialized (line 1) | ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInit...
  method getLevel (line 1) | getLevel(){if(this.level===null)try{let e=(0,v.join)(ce,"settings.json")...
  method correlationId (line 1) | correlationId(e,t){return`obs-${e}-${t}`}
  method sessionId (line 1) | sessionId(e){return`session-${e}`}
  method formatData (line 1) | formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(type...
  method formatTool (line 2) | formatTool(e,t){if(!t)return e;let s=t;if(typeof t=="string")try{s=JSON....
  method formatTimestamp (line 2) | formatTimestamp(e){let t=e.getFullYear(),s=String(e.getMonth()+1).padSta...
  method log (line 2) | log(e,t,s,n,o){if(e<this.getLevel())return;this.ensureLogFileInitialized...
  method debug (line 8) | debug(e,t,s,n){this.log(0,e,t,s,n)}
  method info (line 8) | info(e,t,s,n){this.log(1,e,t,s,n)}
  method warn (line 8) | warn(e,t,s,n){this.log(2,e,t,s,n)}
  method error (line 8) | error(e,t,s,n){this.log(3,e,t,s,n)}
  method dataIn (line 8) | dataIn(e,t,s,n){this.info(e,`\u2192 ${t}`,s,n)}
  method dataOut (line 8) | dataOut(e,t,s,n){this.info(e,`\u2190 ${t}`,s,n)}
  method success (line 8) | success(e,t,s,n){this.info(e,`\u2713 ${t}`,s,n)}
  method failure (line 8) | failure(e,t,s,n){this.error(e,`\u2717 ${t}`,s,n)}
  method timing (line 8) | timing(e,t,s,n){this.info(e,`\u23F1 ${t}`,n,{duration:`${s}ms`})}
  method happyPathError (line 8) | happyPathError(e,t,s,n,o=""){let p=((new Error().stack||"").split(`
  function Rt (line 9) | function Rt(){return typeof __dirname<"u"?__dirname:(0,S.dirname)((0,me....
  function Nt (line 9) | function Nt(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAU...
  function ue (line 9) | function ue(r){(0,k.mkdirSync)(r,{recursive:!0})}
  function le (line 9) | function le(){return(0,S.join)(Ct,"..")}
  function w (line 9) | function w(r,e,t){return(0,Ee.createHash)("sha256").update((r||"")+(e||"...
  function $ (line 9) | function $(r,e,t){let s=t-It;return r.prepare("SELECT id, created_at_epo...
  method constructor (line 9) | constructor(e=_e){e!==":memory:"&&ue(C),this.db=new Te.Database(e),this....
  method initializeSchema (line 9) | initializeSchema(){this.db.run(`
  method ensureWorkerPortColumn (line 71) | ensureWorkerPortColumn(){this.db.query("PRAGMA table_info(sdk_sessions)"...
  method ensurePromptTrackingColumns (line 71) | ensurePromptTrackingColumns(){this.db.query("PRAGMA table_info(sdk_sessi...
  method removeSessionSummariesUniqueConstraint (line 71) | removeSessionSummariesUniqueConstraint(){if(!this.db.query("PRAGMA index...
  method addObservationHierarchicalFields (line 99) | addObservationHierarchicalFields(){if(this.db.prepare("SELECT version FR...
  method makeObservationsTextNullable (line 107) | makeObservationsTextNullable(){if(this.db.prepare("SELECT version FROM s...
  method createUserPromptsTable (line 137) | createUserPromptsTable(){if(this.db.prepare("SELECT version FROM schema_...
  method ensureDiscoveryTokensColumn (line 175) | ensureDiscoveryTokensColumn(){if(this.db.prepare("SELECT version FROM sc...
  method createPendingMessagesTable (line 175) | createPendingMessagesTable(){if(this.db.prepare("SELECT version FROM sch...
  method renameSessionIdColumns (line 195) | renameSessionIdColumns(){if(this.db.prepare("SELECT version FROM schema_...
  method repairSessionIdColumnRename (line 195) | repairSessionIdColumnRename(){this.db.prepare("SELECT version FROM schem...
  method addFailedAtEpochColumn (line 195) | addFailedAtEpochColumn(){if(this.db.prepare("SELECT version FROM schema_...
  method addOnUpdateCascadeToForeignKeys (line 195) | addOnUpdateCascadeToForeignKeys(){if(!this.db.prepare("SELECT version FR...
  method addObservationContentHashColumn (line 289) | addObservationContentHashColumn(){if(this.db.query("PRAGMA table_info(ob...
  method addSessionCustomTitleColumn (line 289) | addSessionCustomTitleColumn(){if(this.db.prepare("SELECT version FROM sc...
  method updateMemorySessionId (line 289) | updateMemorySessionId(e,t){this.db.prepare(`
  method ensureMemorySessionIdRegistered (line 293) | ensureMemorySessionIdRegistered(e,t){let s=this.db.prepare(`
  method getRecentSummaries (line 297) | getRecentSummaries(e,t=10){return this.db.prepare(`
  method getRecentSummariesWithSessionInfo (line 305) | getRecentSummariesWithSessionInfo(e,t=3){return this.db.prepare(`
  method getRecentObservations (line 313) | getRecentObservations(e,t=20){return this.db.prepare(`
  method getAllRecentObservations (line 319) | getAllRecentObservations(e=100){return this.db.prepare(`
  method getAllRecentSummaries (line 324) | getAllRecentSummaries(e=50){return this.db.prepare(`
  method getAllRecentUserPrompts (line 331) | getAllRecentUserPrompts(e=100){return this.db.prepare(`
  method getAllProjects (line 344) | getAllProjects(){return this.db.prepare(`
  method getLatestUserPrompt (line 349) | getLatestUserPrompt(e){return this.db.prepare(`
  method getRecentSessionsWithStatus (line 359) | getRecentSessionsWithStatus(e,t=3){return this.db.prepare(`
  method getObservationsForSession (line 376) | getObservationsForSession(e){return this.db.prepare(`
  method getObservationById (line 381) | getObservationById(e){return this.db.prepare(`
  method getObservationsByIds (line 385) | getObservationsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="dat...
  method getSummaryForSession (line 391) | getSummaryForSession(e){return this.db.prepare(`
  method getFilesForSession (line 400) | getFilesForSession(e){let s=this.db.prepare(`
  method getSessionById (line 404) | getSessionById(e){return this.db.prepare(`
  method getSdkSessionsBySessionIds (line 409) | getSdkSessionsBySessionIds(e){if(e.length===0)return[];let t=e.map(()=>"...
  method getPromptNumberFromUserPrompts (line 415) | getPromptNumberFromUserPrompts(e){return this.db.prepare(`
  method createSDKSession (line 417) | createSDKSession(e,t,s,n){let o=new Date,i=o.getTime(),a=this.db.prepare(`
  method saveUserPrompt (line 429) | saveUserPrompt(e,t,s){let n=new Date,o=n.getTime();return this.db.prepare(`
  method getUserPrompt (line 433) | getUserPrompt(e,t){return this.db.prepare(`
  method storeObservation (line 438) | storeObservation(e,t,s,n,o=0,i){let a=i??Date.now(),d=new Date(a).toISOS...
  method storeSummary (line 443) | storeSummary(e,t,s,n,o=0,i){let a=i??Date.now(),d=new Date(a).toISOStrin...
  method storeObservations (line 448) | storeObservations(e,t,s,n,o,i=0,a){let d=a??Date.now(),p=new Date(d).toI...
  method storeObservationsAndMarkComplete (line 458) | storeObservationsAndMarkComplete(e,t,s,n,o,i,a,d=0,p){let _=p??Date.now(...
  method getSessionSummariesByIds (line 476) | getSessionSummariesByIds(e,t={}){if(e.length===0)return[];let{orderBy:s=...
  method getUserPromptsByIds (line 481) | getUserPromptsByIds(e,t={}){if(e.length===0)return[];let{orderBy:s="date...
  method getTimelineAroundTimestamp (line 491) | getTimelineAroundTimestamp(e,t=10,s=10,n){return this.getTimelineAroundO...
  method getTimelineAroundObservation (line 491) | getTimelineAroundObservation(e,t,s=10,n=10,o){let i=o?"AND project = ?":...
  method getPromptById (line 531) | getPromptById(e){return this.db.prepare(`
  method getPromptsByIds (line 544) | getPromptsByIds(e){if(e.length===0)return[];let t=e.map(()=>"?").join(",...
  method getSessionSummaryById (line 557) | getSessionSummaryById(e){return this.db.prepare(`
  method getOrCreateManualSession (line 572) | getOrCreateManualSession(e){let t=`manual-${e}`,s=`manual-content-${e}`;...
  method close (line 575) | close(){this.db.close()}
  method importSdkSession (line 575) | importSdkSession(e){let t=this.db.prepare("SELECT id FROM sdk_sessions W...
  method importSessionSummary (line 580) | importSessionSummary(e){let t=this.db.prepare("SELECT id FROM session_su...
  method importObservation (line 586) | importObservation(e){let t=this.db.prepare(`
  method importUserPrompt (line 595) | importUserPrompt(e){let t=this.db.prepare(`
  function fe (line 603) | function fe(r){if(!r||r.trim()==="")return m.warn("PROJECT_NAME","Empty ...
  method getAllDefaults (line 603) | static getAllDefaults(){return{...this.DEFAULTS}}
  method get (line 603) | static get(e){return process.env[e]??this.DEFAULTS[e]}
  method getInt (line 603) | static getInt(e){let t=this.get(e);return parseInt(t,10)}
  method getBool (line 603) | static getBool(e){let t=this.get(e);return t==="true"||t===!0}
  method applyEnvOverrides (line 603) | static applyEnvOverrides(e){let t={...e};for(let s of Object.keys(this.D...
  method loadFromFile (line 603) | static loadFromFile(e){try{if(!(0,N.existsSync)(e)){let i=this.getAllDef...
  method constructor (line 603) | constructor(){let e=le(),t=[(0,j.join)(e,"modes"),(0,j.join)(e,"..","plu...
  method getInstance (line 603) | static getInstance(){return r.instance||(r.instance=new r),r.instance}
  method parseInheritance (line 603) | parseInheritance(e){let t=e.split("--");if(t.length===1)return{hasParent...
  method isPlainObject (line 603) | isPlainObject(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}
  method deepMerge (line 603) | deepMerge(e,t){let s={...e};for(let n in t){let o=t[n],i=e[n];this.isPla...
  method loadModeFile (line 603) | loadModeFile(e){let t=(0,j.join)(this.modesDir,`${e}.json`);if(!(0,L.exi...
  method loadMode (line 603) | loadMode(e){let t=this.parseInheritance(e);if(!t.hasParent)try{let d=thi...
  method getActiveMode (line 603) | getActiveMode(){if(!this.activeMode)throw new Error("No mode loaded. Cal...
  method getObservationTypes (line 603) | getObservationTypes(){return this.getActiveMode().observation_types}
  method getObservationConcepts (line 603) | getObservationConcepts(){return this.getActiveMode().observation_concepts}
  method getTypeIcon (line 603) | getTypeIcon(e){return this.getObservationTypes().find(s=>s.id===e)?.emoj...
  method getWorkEmoji (line 603) | getWorkEmoji(e){return this.getObservationTypes().find(s=>s.id===e)?.wor...
  method validateType (line 603) | validateType(e){return this.getObservationTypes().some(t=>t.id===e)}
  method getTypeLabel (line 603) | getTypeLabel(e){return this.getObservationTypes().find(s=>s.id===e)?.lab...
  function J (line 603) | function J(){let r=Se.default.join((0,he.homedir)(),".claude-mem","setti...
  function z (line 603) | function z(r){let e=(r.title?.length||0)+(r.subtitle?.length||0)+(r.narr...
  function Z (line 603) | function Z(r){let e=r.length,t=r.reduce((i,a)=>i+z(a),0),s=r.reduce((i,a...
  function yt (line 603) | function yt(r){return O.getInstance().getWorkEmoji(r)}
  function M (line 603) | function M(r,e){let t=z(r),s=r.discovery_tokens||0,n=yt(r.type),o=s>0?`$...
  function G (line 603) | function G(r){return r.showReadTokens||r.showWorkTokens||r.showSavingsAm...
  function ee (line 603) | function ee(r,e,t){let s=Array.from(t.observationTypes),n=s.map(()=>"?")...
  function te (line 617) | function te(r,e,t){return r.db.prepare(`
  function Ce (line 623) | function Ce(r,e,t){let s=Array.from(t.observationTypes),n=s.map(()=>"?")...
  function Ne (line 637) | function Ne(r,e,t){let s=e.map(()=>"?").join(",");return r.db.prepare(`
  function vt (line 643) | function vt(r){return r.replace(/\//g,"-")}
  function Lt (line 643) | function Lt(r){try{if(!(0,H.existsSync)(r))return{userMessage:"",assista...
  function se (line 644) | function se(r,e,t,s){if(!e.showLastMessage||r.length===0)return{userMess...
  function Ae (line 644) | function Ae(r,e){let t=e[0]?.id;return r.map((s,n)=>{let o=n===0?null:e[...
  function re (line 644) | function re(r,e){let t=[...r.map(s=>({type:"observation",data:s})),...e....
  function Ie (line 644) | function Ie(r,e){return new Set(r.slice(0,e).map(t=>t.id))}
  function ye (line 644) | function ye(){let r=new Date,e=r.toLocaleDateString("en-CA"),t=r.toLocal...
  function ve (line 644) | function ve(r){return[`# $CMEM ${r} ${ye()}`,""]}
  function Le (line 644) | function Le(){return[`Legend: \u{1F3AF}session ${O.getInstance().getActi...
  function Me (line 644) | function Me(){return[]}
  function De (line 644) | function De(){return[]}
  function xe (line 644) | function xe(r,e){let t=[],s=[`${r.totalObservations} obs (${r.totalReadT...
  function Ue (line 644) | function Ue(r){return[`### ${r}`]}
  function ke (line 644) | function ke(r){return r.toLowerCase().replace(" am","a").replace(" pm","...
  function we (line 644) | function we(r,e,t){let s=r.title||"Untitled",n=O.getInstance().getTypeIc...
  function $e (line 644) | function $e(r,e,t,s){let n=[],o=r.title||"Untitled",i=O.getInstance().ge...
  function Fe (line 644) | function Fe(r,e){return[`S${r.id} ${r.request||"Session started"} (${e})`]}
  function D (line 644) | function D(r,e){return e?[`**${r}**: ${e}`,""]:[]}
  function Pe (line 644) | function Pe(r){return r.assistantMessage?["","---","","**Previously**","...
  function Xe (line 644) | function Xe(r,e){return["",`Access ${Math.round(r/1e3)}k tokens of past ...
  function je (line 644) | function je(r){return`# $CMEM ${r} ${ye()}
  function Ge (line 646) | function Ge(){let r=new Date,e=r.toLocaleDateString("en-CA"),t=r.toLocal...
  function He (line 646) | function He(r){return["",`${c.bright}${c.cyan}[${r}] recent context, ${G...
  function Be (line 646) | function Be(){let e=O.getInstance().getActiveMode().observation_types.ma...
  function We (line 646) | function We(){return[`${c.bright}Column Key${c.reset}`,`${c.dim}  Read: ...
  function Ye (line 646) | function Ye(){return[`${c.dim}Context Index: This semantic index (titles...
  function qe (line 646) | function qe(r,e){let t=[];if(t.push(`${c.bright}${c.cyan}Context Economi...
  function Ve (line 646) | function Ve(r){return[`${c.bright}${c.cyan}${r}${c.reset}`,""]}
  function Ke (line 646) | function Ke(r){return[`${c.dim}${r}${c.reset}`]}
  function Je (line 646) | function Je(r,e,t,s){let n=r.title||"Untitled",o=O.getInstance().getType...
  function Qe (line 646) | function Qe(r,e,t,s,n){let o=[],i=r.title||"Untitled",a=O.getInstance()....
  function ze (line 646) | function ze(r,e){let t=`${r.request||"Session started"} (${e})`;return[`...
  function x (line 646) | function x(r,e,t){return e?[`${t}${r}:${c.reset} ${e}`,""]:[]}
  function Ze (line 646) | function Ze(r){return r.assistantMessage?["","---","",`${c.bright}${c.ma...
  function et (line 646) | function et(r,e){let t=Math.round(r/1e3);return["",`${c.dim}Access ${t}k...
  function tt (line 646) | function tt(r){return`
  function st (line 651) | function st(r,e,t,s){let n=[];return s?n.push(...He(r)):n.push(...ve(r))...
  function Y (line 651) | function Y(r){if(!r)return[];try{let e=JSON.parse(r);return Array.isArra...
  function oe (line 651) | function oe(r){return new Date(r).toLocaleString("en-US",{month:"short",...
  function ie (line 651) | function ie(r){return new Date(r).toLocaleString("en-US",{hour:"numeric"...
  function nt (line 651) | function nt(r){return new Date(r).toLocaleString("en-US",{month:"short",...
  function rt (line 651) | function rt(r,e){return ne.default.isAbsolute(r)?ne.default.relative(e,r...
  function ot (line 651) | function ot(r,e,t){let s=Y(r);if(s.length>0)return rt(s[0],e);if(t){let ...
  function Mt (line 651) | function Mt(r){let e=new Map;for(let s of r){let n=s.type==="observation...
  function it (line 651) | function it(r,e){return e.fullObservationField==="narrative"?r.narrative...
  function Dt (line 652) | function Dt(r,e,t,s){let n=[];n.push(...Ue(r));let o="";for(let i of e)i...
  function xt (line 652) | function xt(r,e,t,s,n){let o=[];o.push(...Ve(r));let i=null,a="";for(let...
  function Ut (line 652) | function Ut(r,e,t,s,n,o){return o?xt(r,e,t,s,n):Dt(r,e,t,s)}
  function at (line 652) | function at(r,e,t,s,n){let o=[],i=Mt(r);for(let[a,d]of i)o.push(...Ut(a,...
  function dt (line 652) | function dt(r,e,t){return!(!r.showLastSummary||!e||!!!(e.investigated||e...
  function ct (line 652) | function ct(r,e){let t=[];return e?(t.push(...x("Investigated",r.investi...
  function pt (line 652) | function pt(r,e){return e?Ze(r):Pe(r)}
  function mt (line 652) | function mt(r,e,t){return!G(e)||r.totalDiscoveryTokens<=0||r.savings<=0?...
  function wt (line 652) | function wt(){try{return new F}catch(r){if(r.code==="ERR_DLOPEN_FAILED")...
  function $t (line 652) | function $t(r,e){return e?tt(r):je(r)}
  function Ft (line 652) | function Ft(r,e,t,s,n,o,i){let a=[],d=Z(e);a.push(...st(r,d,s,i));let p=...
  function ae (line 653) | async function ae(r,e=!1){let t=J(),s=r?.cwd??process.cwd(),n=fe(s),o=r?...

FILE: plugin/scripts/mcp-server.cjs
  method constructor (line 2) | constructor(e){if(super(),!re.IDENTIFIER.test(e))throw new Error("CodeGe...
  method toString (line 2) | toString(){return this.str}
  method emptyStr (line 2) | emptyStr(){return!1}
  method names (line 2) | get names(){return{[this.str]:1}}
  method constructor (line 2) | constructor(e){super(),this._items=typeof e=="string"?[e]:e}
  method toString (line 2) | toString(){return this.str}
  method emptyStr (line 2) | emptyStr(){if(this._items.length>1)return!1;let e=this._items[0];return ...
  method str (line 2) | get str(){var e;return(e=this._str)!==null&&e!==void 0?e:this._str=this....
  method names (line 2) | get names(){var e;return(e=this._names)!==null&&e!==void 0?e:this._names...
  function ov (line 2) | function ov(t,...e){let r=[t[0]],n=0;for(;n<e.length;)Od(r,e[n]),r.push(...
  function iv (line 2) | function iv(t,...e){let r=[Zo(t[0])],n=0;for(;n<e.length;)r.push(Pd),Od(...
  function Od (line 2) | function Od(t,e){e instanceof it?t.push(...e._items):e instanceof xr?t.p...
  function cw (line 2) | function cw(t){let e=1;for(;e<t.length-1;){if(t[e]===Pd){let r=uw(t[e-1]...
  function uw (line 2) | function uw(t,e){if(e==='""')return t;if(t==='""')return e;if(typeof t==...
  function lw (line 2) | function lw(t,e){return e.emptyStr()?t:t.emptyStr()?e:iv`${t}${e}`}
  function dw (line 2) | function dw(t){return typeof t=="number"||typeof t=="boolean"||t===null?...
  function pw (line 2) | function pw(t){return new it(Zo(t))}
  function Zo (line 2) | function Zo(t){return JSON.stringify(t).replace(/\u2028/g,"\\u2028").rep...
  function fw (line 2) | function fw(t){return typeof t=="string"&&re.IDENTIFIER.test(t)?new it(`...
  function mw (line 2) | function mw(t){if(typeof t=="string"&&re.IDENTIFIER.test(t))return new i...
  function hw (line 2) | function hw(t){return new it(t.toString())}
  method constructor (line 2) | constructor(e){super(`CodeGen: "code" for ${e} not defined`),this.value=...
  method constructor (line 2) | constructor({prefixes:e,parent:r}={}){this._names={},this._prefixes=e,th...
  method toName (line 2) | toName(e){return e instanceof Fe.Name?e:this.name(e)}
  method name (line 2) | name(e){return new Fe.Name(this._newName(e))}
  method _newName (line 2) | _newName(e){let r=this._names[e]||this._nameGroup(e);return`${e}${r.inde...
  method _nameGroup (line 2) | _nameGroup(e){var r,n;if(!((n=(r=this._parent)===null||r===void 0?void 0...
  method constructor (line 2) | constructor(e,r){super(r),this.prefix=e}
  method setValue (line 2) | setValue(e,{property:r,itemIndex:n}){this.value=e,this.scopePath=(0,Fe._...
  method constructor (line 2) | constructor(e){super(e),this._values={},this._scope=e.scope,this.opts={....
  method get (line 2) | get(){return this._scope}
  method name (line 2) | name(e){return new qa(e,this._newName(e))}
  method value (line 2) | value(e,r){var n;if(r.ref===void 0)throw new Error("CodeGen: ref must be...
  method getValue (line 2) | getValue(e,r){let n=this._values[e];if(n)return n.get(r)}
  method scopeRefs (line 2) | scopeRefs(e,r=this._values){return this._reduceValues(r,n=>{if(n.scopePa...
  method scopeCode (line 2) | scopeCode(e=this._values,r,n){return this._reduceValues(e,o=>{if(o.value...
  method _reduceValues (line 2) | _reduceValues(e,r,n={},o){let i=Fe.nil;for(let a in e){let s=e[a];if(!s)...
  method optimizeNodes (line 2) | optimizeNodes(){return this}
  method optimizeNames (line 2) | optimizeNames(e,r){return this}
  method constructor (line 2) | constructor(e,r,n){super(),this.varKind=e,this.name=r,this.rhs=n}
  method render (line 2) | render({es5:e,_n:r}){let n=e?pt.varKinds.var:this.varKind,o=this.rhs===v...
  method optimizeNames (line 2) | optimizeNames(e,r){if(e[this.name.str])return this.rhs&&(this.rhs=un(thi...
  method names (line 2) | get names(){return this.rhs instanceof Q._CodeOrName?this.rhs.names:{}}
  method constructor (line 2) | constructor(e,r,n){super(),this.lhs=e,this.rhs=r,this.sideEffects=n}
  method render (line 2) | render({_n:e}){return`${this.lhs} = ${this.rhs};`+e}
  method optimizeNames (line 2) | optimizeNames(e,r){if(!(this.lhs instanceof Q.Name&&!e[this.lhs.str]&&!t...
  method names (line 2) | get names(){let e=this.lhs instanceof Q.Name?{}:{...this.lhs.names};retu...
  method constructor (line 2) | constructor(e,r,n,o){super(e,n,o),this.op=r}
  method render (line 2) | render({_n:e}){return`${this.lhs} ${this.op}= ${this.rhs};`+e}
  method constructor (line 2) | constructor(e){super(),this.label=e,this.names={}}
  method render (line 2) | render({_n:e}){return`${this.label}:`+e}
  method constructor (line 2) | constructor(e){super(),this.label=e,this.names={}}
  method render (line 2) | render({_n:e}){return`break${this.label?` ${this.label}`:""};`+e}
  method constructor (line 2) | constructor(e){super(),this.error=e}
  method render (line 2) | render({_n:e}){return`throw ${this.error};`+e}
  method names (line 2) | get names(){return this.error.names}
  method constructor (line 2) | constructor(e){super(),this.code=e}
  method render (line 2) | render({_n:e}){return`${this.code};`+e}
  method optimizeNodes (line 2) | optimizeNodes(){return`${this.code}`?this:void 0}
  method optimizeNames (line 2) | optimizeNames(e,r){return this.code=un(this.code,e,r),this}
  method names (line 2) | get names(){return this.code instanceof Q._CodeOrName?this.code.names:{}}
  method constructor (line 2) | constructor(e=[]){super(),this.nodes=e}
  method render (line 2) | render(e){return this.nodes.reduce((r,n)=>r+n.render(e),"")}
  method optimizeNodes (line 2) | optimizeNodes(){let{nodes:e}=this,r=e.length;for(;r--;){let n=e[r].optim...
  method optimizeNames (line 2) | optimizeNames(e,r){let{nodes:n}=this,o=n.length;for(;o--;){let i=n[o];i....
  method names (line 2) | get names(){return this.nodes.reduce((e,r)=>wr(e,r.names),{})}
  method render (line 2) | render(e){return"{"+e._n+super.render(e)+"}"+e._n}
  method constructor (line 2) | constructor(e,r){super(r),this.condition=e}
  method render (line 2) | render(e){let r=`if(${this.condition})`+super.render(e);return this.else...
  method optimizeNodes (line 2) | optimizeNodes(){super.optimizeNodes();let e=this.condition;if(e===!0)ret...
  method optimizeNames (line 2) | optimizeNames(e,r){var n;if(this.else=(n=this.else)===null||n===void 0?v...
  method names (line 2) | get names(){let e=super.names;return Ja(e,this.condition),this.else&&wr(...
  method constructor (line 2) | constructor(e){super(),this.iteration=e}
  method render (line 2) | render(e){return`for(${this.iteration})`+super.render(e)}
  method optimizeNames (line 2) | optimizeNames(e,r){if(super.optimizeNames(e,r))return this.iteration=un(...
  method names (line 2) | get names(){return wr(super.names,this.iteration.names)}
  method constructor (line 2) | constructor(e,r,n,o){super(),this.varKind=e,this.name=r,this.from=n,this...
  method render (line 2) | render(e){let r=e.es5?pt.varKinds.var:this.varKind,{name:n,from:o,to:i}=...
  method names (line 2) | get names(){let e=Ja(super.names,this.from);return Ja(e,this.to)}
  method constructor (line 2) | constructor(e,r,n,o){super(),this.loop=e,this.varKind=r,this.name=n,this...
  method render (line 2) | render(e){return`for(${this.varKind} ${this.name} ${this.loop} ${this.it...
  method optimizeNames (line 2) | optimizeNames(e,r){if(super.optimizeNames(e,r))return this.iterable=un(t...
  method names (line 2) | get names(){return wr(super.names,this.iterable.names)}
  method constructor (line 2) | constructor(e,r,n){super(),this.name=e,this.args=r,this.async=n}
  method render (line 2) | render(e){return`${this.async?"async ":""}function ${this.name}(${this.a...
  method render (line 2) | render(e){return"return "+super.render(e)}
  method render (line 2) | render(e){let r="try"+super.render(e);return this.catch&&(r+=this.catch....
  method optimizeNodes (line 2) | optimizeNodes(){var e,r;return super.optimizeNodes(),(e=this.catch)===nu...
  method optimizeNames (line 2) | optimizeNames(e,r){var n,o;return super.optimizeNames(e,r),(n=this.catch...
  method names (line 2) | get names(){let e=super.names;return this.catch&&wr(e,this.catch.names),...
  method constructor (line 2) | constructor(e){super(),this.error=e}
  method render (line 2) | render(e){return`catch(${this.error})`+super.render(e)}
  method render (line 2) | render(e){return"finally"+super.render(e)}
  method constructor (line 2) | constructor(e,r={}){this._values={},this._blockStarts=[],this._constants...
  method toString (line 3) | toString(){return this._root.render(this.opts)}
  method name (line 3) | name(e){return this._scope.name(e)}
  method scopeName (line 3) | scopeName(e){return this._extScope.name(e)}
  method scopeValue (line 3) | scopeValue(e,r){let n=this._extScope.value(e,r);return(this._values[n.pr...
  method getScopeValue (line 3) | getScopeValue(e,r){return this._extScope.getValue(e,r)}
  method scopeRefs (line 3) | scopeRefs(e){return this._extScope.scopeRefs(e,this._values)}
  method scopeCode (line 3) | scopeCode(){return this._extScope.scopeCode(this._values)}
  method _def (line 3) | _def(e,r,n,o){let i=this._scope.toName(r);return n!==void 0&&o&&(this._c...
  method const (line 3) | const(e,r,n){return this._def(pt.varKinds.const,e,r,n)}
  method let (line 3) | let(e,r,n){return this._def(pt.varKinds.let,e,r,n)}
  method var (line 3) | var(e,r,n){return this._def(pt.varKinds.var,e,r,n)}
  method assign (line 3) | assign(e,r,n){return this._leafNode(new Fa(e,r,n))}
  method add (line 3) | add(e,r){return this._leafNode(new Ad(e,H.operators.ADD,r))}
  method code (line 3) | code(e){return typeof e=="function"?e():e!==Q.nil&&this._leafNode(new Zd...
  method object (line 3) | object(...e){let r=["{"];for(let[n,o]of e)r.length>1&&r.push(","),r.push...
  method if (line 3) | if(e,r,n){if(this._blockNode(new kr(e)),r&&n)this.code(r).else().code(n)...
  method elseIf (line 3) | elseIf(e){return this._elseNode(new kr(e))}
  method else (line 3) | else(){return this._elseNode(new cn)}
  method endIf (line 3) | endIf(){return this._endBlockNode(kr,cn)}
  method _for (line 3) | _for(e,r){return this._blockNode(e),r&&this.code(r).endFor(),this}
  method for (line 3) | for(e,r){return this._for(new qd(e),r)}
  method forRange (line 3) | forRange(e,r,n,o,i=this.opts.es5?pt.varKinds.var:pt.varKinds.let){let a=...
  method forOf (line 3) | forOf(e,r,n,o=pt.varKinds.const){let i=this._scope.toName(e);if(this.opt...
  method forIn (line 3) | forIn(e,r,n,o=this.opts.es5?pt.varKinds.var:pt.varKinds.const){if(this.o...
  method endFor (line 3) | endFor(){return this._endBlockNode(Sr)}
  method label (line 3) | label(e){return this._leafNode(new Md(e))}
  method break (line 3) | break(e){return this._leafNode(new Cd(e))}
  method return (line 3) | return(e){let r=new Vo;if(this._blockNode(r),this.code(e),r.nodes.length...
  method try (line 3) | try(e,r,n){if(!r&&!n)throw new Error('CodeGen: "try" without "catch" and...
  method throw (line 3) | throw(e){return this._leafNode(new Ud(e))}
  method block (line 3) | block(e,r){return this._blockStarts.push(this._nodes.length),e&&this.cod...
  method endBlock (line 3) | endBlock(e){let r=this._blockStarts.pop();if(r===void 0)throw new Error(...
  method func (line 3) | func(e,r=Q.nil,n,o){return this._blockNode(new Fo(e,r,n)),o&&this.code(o...
  method endFunc (line 3) | endFunc(){return this._endBlockNode(Fo)}
  method optimize (line 3) | optimize(e=1){for(;e-- >0;)this._root.optimizeNodes(),this._root.optimiz...
  method _leafNode (line 3) | _leafNode(e){return this._currNode.nodes.push(e),this}
  method _blockNode (line 3) | _blockNode(e){this._currNode.nodes.push(e),this._nodes.push(e)}
  method _endBlockNode (line 3) | _endBlockNode(e,r){let n=this._currNode;if(n instanceof e||r&&n instance...
  method _elseNode (line 3) | _elseNode(e){let r=this._currNode;if(!(r instanceof kr))throw new Error(...
  method _root (line 3) | get _root(){return this._nodes[0]}
  method _currNode (line 3) | get _currNode(){let e=this._nodes;return e[e.length-1]}
  method _currNode (line 3) | set _currNode(e){let r=this._nodes;r[r.length-1]=e}
  function wr (line 3) | function wr(t,e){for(let r in e)t[r]=(t[r]||0)+(e[r]||0);return t}
  function Ja (line 3) | function Ja(t,e){return e instanceof Q._CodeOrName?wr(t,e.names):t}
  function un (line 3) | function un(t,e,r){if(t instanceof Q.Name)return n(t);if(!o(t))return t;...
  function vw (line 3) | function vw(t,e){for(let r in e)t[r]=(t[r]||0)-(e[r]||0)}
  function av (line 3) | function av(t){return typeof t=="boolean"||typeof t=="number"||t===null?...
  function yw (line 3) | function yw(...t){return t.reduce(_w)}
  function bw (line 3) | function bw(...t){return t.reduce($w)}
  function sv (line 3) | function sv(t){return(e,r)=>e===Q.nil?r:r===Q.nil?e:(0,Q._)`${Wd(e)} ${t...
  function Wd (line 3) | function Wd(t){return t instanceof Q.Name?t:(0,Q._)`(${t})`}
  function kw (line 3) | function kw(t){let e={};for(let r of t)e[r]=!0;return e}
  function Sw (line 3) | function Sw(t,e){return typeof e=="boolean"?e:Object.keys(e).length===0?...
  function lv (line 3) | function lv(t,e=t.schema){let{opts:r,self:n}=t;if(!r.strictSchema||typeo...
  function dv (line 3) | function dv(t,e){if(typeof t=="boolean")return!t;for(let r in t)if(e[r])...
  function ww (line 3) | function ww(t,e){if(typeof t=="boolean")return!t;for(let r in t)if(r!=="...
  function zw (line 3) | function zw({topSchemaRef:t,schemaPath:e},r,n,o){if(!o){if(typeof r=="nu...
  function Iw (line 3) | function Iw(t){return pv(decodeURIComponent(t))}
  function Ew (line 3) | function Ew(t){return encodeURIComponent(Hd(t))}
  function Hd (line 3) | function Hd(t){return typeof t=="number"?`${t}`:t.replace(/~/g,"~0").rep...
  function pv (line 3) | function pv(t){return t.replace(/~1/g,"/").replace(/~0/g,"~")}
  function Tw (line 3) | function Tw(t,e){if(Array.isArray(t))for(let r of t)e(r);else e(t)}
  function cv (line 3) | function cv({mergeNames:t,mergeToName:e,mergeValues:r,resultToName:n}){r...
  function fv (line 3) | function fv(t,e){if(e===!0)return t.var("props",!0);let r=t.var("props",...
  function Gd (line 3) | function Gd(t,e,r){Object.keys(r).forEach(n=>t.assign((0,le._)`${e}${(0,...
  function Pw (line 3) | function Pw(t,e){return t.scopeValue("func",{ref:e,code:uv[e.code]||(uv[...
  function Ow (line 3) | function Ow(t,e,r){if(t instanceof le.Name){let n=e===Kd.Num;return r?n?...
  function mv (line 3) | function mv(t,e,r=t.opts.strictSchema){if(r){if(e=`strict mode: ${e}`,r=...
  function Dw (line 3) | function Dw(t,e=je.keywordError,r,n){let{it:o}=t,{gen:i,compositeRule:a,...
  function Nw (line 3) | function Nw(t,e=je.keywordError,r){let{it:n}=t,{gen:o,compositeRule:i,al...
  function Rw (line 3) | function Rw(t,e){t.assign(Ue.default.errors,e),t.if((0,te._)`${Ue.defaul...
  function Aw (line 3) | function Aw({gen:t,keyword:e,schemaValue:r,data:n,errsCount:o,it:i}){if(...
  function hv (line 3) | function hv(t,e){let r=t.const("err",e);t.if((0,te._)`${Ue.default.vErro...
  function gv (line 3) | function gv(t,e){let{gen:r,validateName:n,schemaEnv:o}=t;o.$async?r.thro...
  function vv (line 3) | function vv(t,e,r){let{createErrors:n}=t.it;return n===!1?(0,te._)`{}`:M...
  function Mw (line 3) | function Mw(t,e,r={}){let{gen:n,it:o}=t,i=[Cw(o,r),Uw(t,r)];return Zw(t,...
  function Cw (line 3) | function Cw({errorPath:t},{instancePath:e}){let r=e?(0,te.str)`${t}${(0,...
  function Uw (line 3) | function Uw({keyword:t,it:{errSchemaPath:e}},{schemaPath:r,parentSchema:...
  function Zw (line 3) | function Zw(t,{params:e,message:r},n){let{keyword:o,data:i,schemaValue:a...
  function Jw (line 3) | function Jw(t){let{gen:e,schema:r,validateName:n}=t;r===!1?_v(t,!1):type...
  function Ww (line 3) | function Ww(t,e){let{gen:r,schema:n}=t;n===!1?(r.var(e,!1),_v(t)):r.var(...
  function _v (line 3) | function _v(t,e){let{gen:r,data:n}=t,o={gen:r,keyword:"false schema",dat...
  function Gw (line 3) | function Gw(t){return typeof t=="string"&&Hw.has(t)}
  function Bw (line 3) | function Bw(){let t={number:{type:"number",rules:[]},string:{type:"strin...
  function Xw (line 3) | function Xw({schema:t,self:e},r){let n=e.RULES.types[r];return n&&n!==!0...
  function $v (line 3) | function $v(t,e){return e.rules.some(r=>bv(t,r))}
  function bv (line 3) | function bv(t,e){var r;return t[e.keyword]!==void 0||((r=e.definition.im...
  function t0 (line 3) | function t0(t){let e=kv(t.type);if(e.includes("null")){if(t.nullable===!...
  function kv (line 3) | function kv(t){let e=Array.isArray(t)?t:t?[t]:[];if(e.every(Yw.isJSONTyp...
  function r0 (line 3) | function r0(t,e){let{gen:r,data:n,opts:o}=t,i=n0(e,o.coerceTypes),a=e.le...
  function n0 (line 3) | function n0(t,e){return e?t.filter(r=>Sv.has(r)||e==="array"&&r==="array...
  function o0 (line 3) | function o0(t,e,r){let{gen:n,data:o,opts:i}=t,a=n.let("dataType",(0,J._)...
  function i0 (line 6) | function i0({gen:t,parentData:e,parentDataProperty:r},n){t.if((0,J._)`${...
  function Qd (line 6) | function Qd(t,e,r,n=pn.Correct){let o=n===pn.Correct?J.operators.EQ:J.op...
  function ep (line 6) | function ep(t,e,r,n){if(t.length===1)return Qd(t[0],e,r,n);let o,i=(0,xv...
  function tp (line 6) | function tp(t){let e=s0(t);(0,e0.reportError)(e,a0)}
  function s0 (line 6) | function s0(t){let{gen:e,data:r,schema:n}=t,o=(0,xv.schemaRefOrVal)(t,n,...
  function u0 (line 6) | function u0(t,e){let{properties:r,items:n}=t.schema;if(e==="object"&&r)f...
  function wv (line 6) | function wv(t,e,r){let{gen:n,compositeRule:o,data:i,opts:a}=t;if(r===voi...
  function d0 (line 6) | function d0(t,e){let{gen:r,data:n,it:o}=t;r.if(op(r,n,e,o.opts.ownProper...
  function p0 (line 6) | function p0({gen:t,data:e,it:{opts:r}},n,o){return(0,he.or)(...n.map(i=>...
  function f0 (line 6) | function f0(t,e){t.setParams({missingProperty:e},!0),t.error()}
  function Iv (line 6) | function Iv(t){return t.scopeValue("func",{ref:Object.prototype.hasOwnPr...
  function np (line 6) | function np(t,e,r){return(0,he._)`${Iv(t)}.call(${e}, ${r})`}
  function m0 (line 6) | function m0(t,e,r,n){let o=(0,he._)`${e}${(0,he.getProperty)(r)} !== und...
  function op (line 6) | function op(t,e,r,n){let o=(0,he._)`${e}${(0,he.getProperty)(r)} === und...
  function Ev (line 6) | function Ev(t){return t?Object.keys(t).filter(e=>e!=="__proto__"):[]}
  function h0 (line 6) | function h0(t,e){return Ev(e).filter(r=>!(0,rp.alwaysValidSchema)(t,e[r]))}
  function g0 (line 6) | function g0({schemaCode:t,data:e,it:{gen:r,topSchemaRef:n,schemaPath:o,e...
  function _0 (line 6) | function _0({gen:t,it:{opts:e}},r){let n=e.unicodeRegExp?"u":"",{regExp:...
  function y0 (line 6) | function y0(t){let{gen:e,data:r,keyword:n,it:o}=t,i=e.name("valid");if(o...
  function $0 (line 6) | function $0(t){let{gen:e,schema:r,keyword:n,it:o}=t;if(!Array.isArray(r)...
  function k0 (line 6) | function k0(t,e){let{gen:r,keyword:n,schema:o,parentSchema:i,it:a}=t,s=e...
  function S0 (line 6) | function S0(t,e){var r;let{gen:n,keyword:o,schema:i,parentSchema:a,$data...
  function Tv (line 6) | function Tv(t){let{gen:e,data:r,it:n}=t;e.if(n.parentData,()=>e.assign(r...
  function w0 (line 6) | function w0(t,e){let{gen:r}=t;r.if((0,Ze._)`Array.isArray(${e})`,()=>{r....
  function z0 (line 6) | function z0({schemaEnv:t},e){if(e.async&&!t.$async)throw new Error("asyn...
  function Pv (line 6) | function Pv(t,e,r){if(r===void 0)throw new Error(`keyword "${e}" failed ...
  function I0 (line 6) | function I0(t,e,r=!1){return!e.length||e.some(n=>n==="array"?Array.isArr...
  function E0 (line 6) | function E0({schema:t,opts:e,self:r,errSchemaPath:n},o,i){if(Array.isArr...
  function T0 (line 6) | function T0(t,{keyword:e,schemaProp:r,schema:n,schemaPath:o,errSchemaPat...
  function P0 (line 6) | function P0(t,e,{dataProp:r,dataPropType:n,data:o,dataTypes:i,propertyNa...
  function O0 (line 6) | function O0(t,{jtdDiscriminator:e,jtdMetadata:r,compositeRule:n,createEr...
  function Ga (line 6) | function Ga(t,e,r,n,o,i,a,s,c,u){if(n&&typeof n=="object"&&!Array.isArra...
  function j0 (line 6) | function j0(t){return t.replace(/~/g,"~0").replace(/\//g,"~1")}
  function M0 (line 6) | function M0(t,e=!0){return typeof t=="boolean"?!0:e===!0?!ap(t):e?Mv(t)<...
  function ap (line 6) | function ap(t){for(let e in t){if(C0.has(e))return!0;let r=t[e];if(Array...
  function Mv (line 6) | function Mv(t){let e=0;for(let r in t){if(r==="$ref")return 1/0;if(e++,!...
  function Cv (line 6) | function Cv(t,e="",r){r!==!1&&(e=mn(e));let n=t.parse(e);return Uv(t,n)}
  function Uv (line 6) | function Uv(t,e){return t.serialize(e).split("#")[0]+"#"}
  function mn (line 6) | function mn(t){return t?t.replace(U0,""):""}
  function Z0 (line 6) | function Z0(t,e,r){return r=mn(r),t.resolve(e,r)}
  function q0 (line 6) | function q0(t,e){if(typeof t=="boolean")return{};let{schemaId:r,uriResol...
  function J0 (line 6) | function J0(t){if(Kv(t)&&(Hv(t),Wv(t))){H0(t);return}Jv(t,()=>(0,Vv.topB...
  function Jv (line 6) | function Jv({gen:t,validateName:e,schema:r,schemaEnv:n,opts:o},i){o.code...
  function W0 (line 6) | function W0(t){return(0,O._)`{${U.default.instancePath}="", ${U.default....
  function K0 (line 6) | function K0(t,e){t.if(U.default.valCxt,()=>{t.var(U.default.instancePath...
  function H0 (line 6) | function H0(t){let{schema:e,opts:r,gen:n}=t;Jv(t,()=>{r.$comment&&e.$com...
  function G0 (line 6) | function G0(t){let{gen:e,validateName:r}=t;t.evaluated=e.const("evaluate...
  function Lv (line 6) | function Lv(t,e){let r=typeof t=="object"&&t[e.schemaId];return r&&(e.co...
  function B0 (line 6) | function B0(t,e){if(Kv(t)&&(Hv(t),Wv(t))){X0(t,e);return}(0,Vv.boolOrEmp...
  function Wv (line 6) | function Wv({schema:t,self:e}){if(typeof t=="boolean")return!t;for(let r...
  function Kv (line 6) | function Kv(t){return typeof t.schema!="boolean"}
  function X0 (line 6) | function X0(t,e){let{schema:r,gen:n,opts:o}=t;o.$comment&&r.$comment&&Bv...
  function Hv (line 6) | function Hv(t){(0,qt.checkUnknownRules)(t),Y0(t)}
  function Gv (line 6) | function Gv(t,e){if(t.opts.jtd)return qv(t,[],!1,e);let r=(0,Zv.getSchem...
  function Y0 (line 6) | function Y0(t){let{schema:e,errSchemaPath:r,opts:n,self:o}=t;e.$ref&&n.i...
  function Q0 (line 6) | function Q0(t){let{schema:e,opts:r}=t;e.default!==void 0&&r.useDefaults&...
  function ez (line 6) | function ez(t){let e=t.schema[t.opts.schemaId];e&&(t.baseId=(0,V0.resolv...
  function tz (line 6) | function tz(t){if(t.schema.$async&&!t.schemaEnv.$async)throw new Error("...
  function Bv (line 6) | function Bv({gen:t,schemaEnv:e,schema:r,errSchemaPath:n,opts:o}){let i=r...
  function rz (line 6) | function rz(t){let{gen:e,schemaEnv:r,validateName:n,ValidationError:o,op...
  function nz (line 6) | function nz({gen:t,evaluated:e,props:r,items:n}){r instanceof O.Name&&t....
  function qv (line 6) | function qv(t,e,r,n){let{gen:o,schema:i,data:a,allErrors:s,opts:c,self:u...
  function Fv (line 6) | function Fv(t,e){let{gen:r,schema:n,opts:{useDefaults:o}}=t;o&&(0,F0.ass...
  function oz (line 6) | function oz(t,e){t.schemaEnv.meta||!t.opts.strictTypes||(iz(t,e),t.opts....
  function iz (line 6) | function iz(t,e){if(e.length){if(!t.dataTypes.length){t.dataTypes=e;retu...
  function az (line 6) | function az(t,e){e.length>1&&!(e.length===2&&e.includes("null"))&&up(t,"...
  function sz (line 6) | function sz(t,e){let r=t.self.RULES.all;for(let n in r){let o=r[n];if(ty...
  function cz (line 6) | function cz(t,e){return t.includes(e)||e==="number"&&t.includes("integer")}
  function Xv (line 6) | function Xv(t,e){return t.includes(e)||e==="integer"&&t.includes("number")}
  function uz (line 6) | function uz(t,e){let r=[];for(let n of t.dataTypes)Xv(e,n)?r.push(n):e.i...
  function up (line 6) | function up(t,e){let r=t.schemaEnv.baseId+t.errSchemaPath;e+=` at "${r}"...
  method constructor (line 6) | constructor(e,r,n){if((0,Xo.validateKeywordUsage)(e,r,n),this.gen=e.gen,...
  method result (line 6) | result(e,r,n){this.failResult((0,O.not)(e),r,n)}
  method failResult (line 6) | failResult(e,r,n){this.gen.if(e),n?n():this.error(),r?(this.gen.else(),r...
  method pass (line 6) | pass(e,r){this.failResult((0,O.not)(e),void 0,r)}
  method fail (line 6) | fail(e){if(e===void 0){this.error(),this.allErrors||this.gen.if(!1);retu...
  method fail$data (line 6) | fail$data(e){if(!this.$data)return this.fail(e);let{schemaCode:r}=this;t...
  method error (line 6) | error(e,r,n){if(r){this.setParams(r),this._error(e,n),this.setParams({})...
  method _error (line 6) | _error(e,r){(e?Bo.reportExtraError:Bo.reportError)(this,this.def.error,r)}
  method $dataError (line 6) | $dataError(){(0,Bo.reportError)(this,this.def.$dataError||Bo.keyword$Dat...
  method reset (line 6) | reset(){if(this.errsCount===void 0)throw new Error('add "trackErrors" to...
  method ok (line 6) | ok(e){this.allErrors||this.gen.if(e)}
  method setParams (line 6) | setParams(e,r){r?Object.assign(this.params,e):this.params=e}
  method block$data (line 6) | block$data(e,r,n=O.nil){this.gen.block(()=>{this.check$data(e,n),r()})}
  method check$data (line 6) | check$data(e=O.nil,r=O.nil){if(!this.$data)return;let{gen:n,schemaCode:o...
  method invalid$data (line 6) | invalid$data(){let{gen:e,schemaCode:r,schemaType:n,def:o,it:i}=this;retu...
  method subschema (line 6) | subschema(e,r){let n=(0,sp.getSubschema)(this.it,e);(0,sp.extendSubschem...
  method mergeEvaluated (line 6) | mergeEvaluated(e,r){let{it:n,gen:o}=this;n.opts.unevaluated&&(n.props!==...
  method mergeValidEvaluated (line 6) | mergeValidEvaluated(e,r){let{it:n,gen:o}=this;if(n.opts.unevaluated&&(n....
  function Yv (line 6) | function Yv(t,e,r,n){let o=new Xa(t,r,e);"code"in r?r.code(o,n):o.$data&...
  function Qv (line 6) | function Qv(t,{dataLevel:e,dataNames:r,dataPathArr:n}){let o,i;if(t===""...
  method constructor (line 6) | constructor(e){super("validation failed"),this.errors=e,this.ajv=this.va...
  method constructor (line 6) | constructor(e,r,n,o){super(o||`can't resolve reference ${n} from id ${r}...
  method constructor (line 6) | constructor(e){var r;this.refs={},this.dynamicAnchors={};let n;typeof e....
  function gp (line 6) | function gp(t){let e=t_.call(this,t);if(e)return e;let r=(0,mt.getFullPa...
  function mz (line 6) | function mz(t,e,r){var n;r=(0,mt.resolveUrl)(this.opts.uriResolver,e,r);...
  function hz (line 6) | function hz(t){return(0,mt.inlineRef)(t.schema,this.opts.inlineRefs)?t.s...
  function t_ (line 6) | function t_(t){for(let e of this._compilations)if(gz(e,t))return e}
  function gz (line 6) | function gz(t,e){return t.schema===e.schema&&t.root===e.root&&t.baseId==...
  function vz (line 6) | function vz(t,e){let r;for(;typeof(r=this.refs[e])=="string";)e=r;return...
  function Qa (line 6) | function Qa(t,e){let r=this.opts.uriResolver.parse(e),n=(0,mt._getFullPa...
  function hp (line 6) | function hp(t,{baseId:e,schema:r,root:n}){var o;if(((o=t.fragment)===nul...
  function vp (line 6) | function vp(t){let e="",r=0,n=0;for(n=0;n<t.length;n++)if(r=t[n].charCod...
  function n_ (line 6) | function n_(t){return t.length=0,!0}
  function xz (line 6) | function xz(t,e,r){if(t.length){let n=vp(t);if(n!=="")e.push(n);else ret...
  function kz (line 6) | function kz(t){let e=0,r={error:!1,address:"",zone:""},n=[],o=[],i=!1,a=...
  function i_ (line 6) | function i_(t){if(Sz(t,":")<2)return{host:t,isIPV6:!1};let e=kz(t);if(e....
  function Sz (line 6) | function Sz(t,e){let r=0;for(let n=0;n<t.length;n++)t[n]===e&&r++;return r}
  function wz (line 6) | function wz(t){let e=t,r=[],n=-1,o=0;for(;o=e.length;){if(o===1){if(e===...
  function zz (line 6) | function zz(t,e){let r=e!==!0?escape:unescape;return t.scheme!==void 0&&...
  function Iz (line 6) | function Iz(t){let e=[];if(t.userinfo!==void 0&&(e.push(t.userinfo),e.pu...
  function Oz (line 6) | function Oz(t){return Pz.indexOf(t)!==-1}
  function yp (line 6) | function yp(t){return t.secure===!0?!0:t.secure===!1?!1:t.scheme?t.schem...
  function s_ (line 6) | function s_(t){return t.host||(t.error=t.error||"HTTP URIs must have a h...
  function c_ (line 6) | function c_(t){let e=String(t.scheme).toLowerCase()==="https";return(t.p...
  function jz (line 6) | function jz(t){return t.secure=yp(t),t.resourceName=(t.path||"/")+(t.que...
  function Dz (line 6) | function Dz(t){if((t.port===(yp(t)?443:80)||t.port==="")&&(t.port=void 0...
  function Nz (line 6) | function Nz(t,e){if(!t.path)return t.error="URN can not be parsed",t;let...
  function Rz (line 6) | function Rz(t,e){if(t.nid===void 0)throw new Error("URN without nid cann...
  function Az (line 6) | function Az(t,e){let r=t;return r.uuid=r.nss,r.nss=void 0,!e.tolerant&&(...
  function Mz (line 6) | function Mz(t){let e=t;return e.nss=(t.uuid||"").toLowerCase(),e}
  function $p (line 6) | function $p(t){return t&&(rs[t]||rs[t.toLowerCase()])||void 0}
  function Kz (line 6) | function Kz(t,e){return typeof t=="string"?t=xt(Ft(t,e),e):typeof t=="ob...
  function Hz (line 6) | function Hz(t,e,r){let n=r?Object.assign({scheme:"null"},r):{scheme:"nul...
  function f_ (line 6) | function f_(t,e,r,n){let o={};return n||(t=Ft(xt(t,r),r),e=Ft(xt(e,r),r)...
  function Gz (line 6) | function Gz(t,e,r){return typeof t=="string"?(t=unescape(t),t=xt(ns(Ft(t...
  function xt (line 6) | function xt(t,e){let r={host:t.host,scheme:t.scheme,userinfo:t.userinfo,...
  function Ft (line 6) | function Ft(t,e){let r=Object.assign({},e),n={scheme:void 0,userinfo:voi...
  function aI (line 6) | function aI(t){var e,r,n,o,i,a,s,c,u,l,d,p,f,g,h,_,b,E,I,A,j,Le,de,Wt,Qe...
  method constructor (line 6) | constructor(e={}){this.schemas={},this.refs={},this.formats={},this._com...
  method _addVocabularies (line 6) | _addVocabularies(){this.addKeyword("$async")}
  method _addDefaultMetaSchema (line 6) | _addDefaultMetaSchema(){let{$data:e,meta:r,schemaId:n}=this.opts,o=v_;n=...
  method defaultMeta (line 6) | defaultMeta(){let{meta:e,schemaId:r}=this.opts;return this.opts.defaultM...
  method validate (line 6) | validate(e,r){let n;if(typeof e=="string"){if(n=this.getSchema(e),!n)thr...
  method compile (line 6) | compile(e,r){let n=this._addSchema(e,r);return n.validate||this._compile...
  method compileAsync (line 6) | compileAsync(e,r){if(typeof this.opts.loadSchema!="function")throw new E...
  method addSchema (line 6) | addSchema(e,r,n,o=this.opts.validateSchema){if(Array.isArray(e)){for(let...
  method addMetaSchema (line 6) | addMetaSchema(e,r,n=this.opts.validateSchema){return this.addSchema(e,r,...
  method validateSchema (line 6) | validateSchema(e,r){if(typeof e=="boolean")return!0;let n;if(n=e.$schema...
  method getSchema (line 6) | getSchema(e){let r;for(;typeof(r=$_.call(this,e))=="string";)e=r;if(r===...
  method removeSchema (line 6) | removeSchema(e){if(e instanceof RegExp)return this._removeAllSchemas(thi...
  method addVocabulary (line 6) | addVocabulary(e){for(let r of e)this.addKeyword(r);return this}
  method addKeyword (line 6) | addKeyword(e,r){let n;if(typeof e=="string")n=e,typeof r=="object"&&(thi...
  method getKeyword (line 6) | getKeyword(e){let r=this.RULES.all[e];return typeof r=="object"?r.defini...
  method removeKeyword (line 6) | removeKeyword(e){let{RULES:r}=this;delete r.keywords[e],delete r.all[e];...
  method addFormat (line 6) | addFormat(e,r){return typeof r=="string"&&(r=new RegExp(r)),this.formats...
  method errorsText (line 6) | errorsText(e=this.errors,{separator:r=", ",dataVar:n="data"}={}){return!...
  method $dataMetaSchema (line 6) | $dataMetaSchema(e,r){let n=this.RULES.all;e=JSON.parse(JSON.stringify(e)...
  method _removeAllSchemas (line 6) | _removeAllSchemas(e,r){for(let n in e){let o=e[n];(!r||r.test(n))&&(type...
  method _addSchema (line 6) | _addSchema(e,r,n,o=this.opts.validateSchema,i=this.opts.addUsedSchema){l...
  method _checkUnique (line 6) | _checkUnique(e){if(this.schemas[e]||this.refs[e])throw new Error(`schema...
  method _compileSchemaEnv (line 6) | _compileSchemaEnv(e){if(e.meta?this._compileMetaSchema(e):ti.compileSche...
  method _compileMetaSchema (line 6) | _compileMetaSchema(e){let r=this.opts;this.opts=this._metaOpts;try{ti.co...
  function y_ (line 6) | function y_(t,e,r,n="error"){for(let o in t){let i=o;i in e&&this.logger...
  function $_ (line 6) | function $_(t){return t=(0,ri.normalizeId)(t),this.schemas[t]||this.refs...
  function sI (line 6) | function sI(){let t=this.opts.schemas;if(t)if(Array.isArray(t))this.addS...
  function cI (line 6) | function cI(){for(let t in this.opts.formats){let e=this.opts.formats[t]...
  function uI (line 6) | function uI(t){if(Array.isArray(t)){this.addVocabulary(t);return}this.lo...
  function lI (line 6) | function lI(){let t={...this.opts};for(let e of rI)delete t[e];return t}
  method log (line 6) | log(){}
  method warn (line 6) | warn(){}
  method error (line 6) | error(){}
  function pI (line 6) | function pI(t){if(t===!1)return dI;if(t===void 0)return console;if(t.log...
  function mI (line 6) | function mI(t,e){let{RULES:r}=this;if((0,Sp.eachItem)(t,n=>{if(r.keyword...
  function kp (line 6) | function kp(t,e,r){var n;let o=e?.post;if(r&&o)throw new Error('keyword ...
  function hI (line 6) | function hI(t,e,r){let n=t.rules.findIndex(o=>o.keyword===r);n>=0?t.rule...
  function gI (line 6) | function gI(t){let{metaSchema:e}=t;e!==void 0&&(t.$data&&this.opts.$data...
  function k_ (line 6) | function k_(t){return{anyOf:[t,vI]}}
  method code (line 6) | code(){throw new Error('NOT SUPPORTED: keyword "id", use "$id" for schem...
  method code (line 6) | code(t){let{gen:e,schema:r,it:n}=t,{baseId:o,schemaEnv:i,validateName:a,...
  function E_ (line 6) | function E_(t,e){let{gen:r}=t;return e.validate?r.scopeValue("validate",...
  function ss (line 6) | function ss(t,e,r,n){let{gen:o,it:i}=t,{allErrors:a,schemaEnv:s,opts:c}=...
  method code (line 6) | code(t){let{keyword:e,data:r,schemaCode:n}=t;t.fail$data((0,cs._)`${r} $...
  method code (line 6) | code(t){let{gen:e,data:r,schemaCode:n,it:o}=t,i=o.opts.multipleOfPrecisi...
  function D_ (line 6) | function D_(t){let e=t.length,r=0,n=0,o;for(;n<e;)r++,o=t.charCodeAt(n++...
  method message (line 6) | message({keyword:t,schemaCode:e}){let r=t==="maxLength"?"more":"fewer";r...
  method code (line 6) | code(t){let{keyword:e,data:r,schemaCode:n,it:o}=t,i=e==="maxLength"?Pr.o...
  method code (line 6) | code(t){let{gen:e,data:r,$data:n,schema:o,schemaCode:i,it:a}=t,s=a.opts....
  method message (line 6) | message({keyword:t,schemaCode:e}){let r=t==="maxProperties"?"more":"fewe...
  method code (line 6) | code(t){let{keyword:e,data:r,schemaCode:n}=t,o=e==="maxProperties"?ii.op...
  method code (line 6) | code(t){let{gen:e,schema:r,schemaCode:n,data:o,$data:i,it:a}=t,{opts:s}=...
  method message (line 6) | message({keyword:t,schemaCode:e}){let r=t==="maxItems"?"more":"fewer";re...
  method code (line 6) | code(t){let{keyword:e,data:r,schemaCode:n}=t,o=e==="maxItems"?ci.operato...
  method code (line 6) | code(t){let{gen:e,data:r,$data:n,schema:o,parentSchema:i,schemaCode:a,it...
  method code (line 6) | code(t){let{gen:e,data:r,$data:n,schemaCode:o,schema:i}=t;n||i&&typeof i...
  method code (line 6) | code(t){let{gen:e,data:r,$data:n,schema:o,schemaCode:i,it:a}=t;if(!n&&o....
  method code (line 6) | code(t){let{parentSchema:e,it:r}=t,{items:n}=e;if(!Array.isArray(n)){(0,...
  function J_ (line 6) | function J_(t,e){let{gen:r,schema:n,data:o,keyword:i,it:a}=t;a.items=!0;...
  method code (line 6) | code(t){let{schema:e,it:r}=t;if(Array.isArray(e))return K_(t,"additional...
  function K_ (line 6) | function K_(t,e,r=t.schema){let{gen:n,parentSchema:o,data:i,keyword:a,it...
  method code (line 6) | code(t){let{schema:e,parentSchema:r,it:n}=t,{prefixItems:o}=r;n.items=!0...
  method code (line 6) | code(t){let{gen:e,schema:r,parentSchema:n,data:o,it:i}=t,a,s,{minContain...
  method code (line 9) | code(t){let[e,r]=IE(t);Y_(t,e),Q_(t,r)}
  function IE (line 9) | function IE({schema:t}){let e={},r={};for(let n in t){if(n==="__proto__"...
  function Y_ (line 9) | function Y_(t,e=t.schema){let{gen:r,data:n,it:o}=t;if(Object.keys(e).len...
  function Q_ (line 9) | function Q_(t,e=t.schema){let{gen:r,data:n,keyword:o,it:i}=t,a=r.name("v...
  method code (line 9) | code(t){let{gen:e,schema:r,data:n,it:o}=t;if((0,EE.alwaysValidSchema)(o,...
  method code (line 9) | code(t){let{gen:e,schema:r,parentSchema:n,data:o,errsCount:i,it:a}=t;if(...
  method code (line 9) | code(t){let{gen:e,schema:r,parentSchema:n,data:o,it:i}=t;i.opts.removeAd...
  method code (line 9) | code(t){let{gen:e,schema:r,data:n,parentSchema:o,it:i}=t,{opts:a}=i,s=(0...
  method code (line 9) | code(t){let{gen:e,schema:r,it:n}=t;if((0,ME.alwaysValidSchema)(n,r)){t.f...
  method code (line 9) | code(t){let{gen:e,schema:r,parentSchema:n,it:o}=t;if(!Array.isArray(r))t...
  method code (line 9) | code(t){let{gen:e,schema:r,it:n}=t;if(!Array.isArray(r))throw new Error(...
  method code (line 9) | code(t){let{gen:e,parentSchema:r,it:n}=t;r.then===void 0&&r.else===void ...
  function my (line 9) | function my(t,e){let r=t.schema[e];return r!==void 0&&!(0,hy.alwaysValid...
  method code (line 9) | code({keyword:t,parentSchema:e,it:r}){e.if===void 0&&(0,HE.checkStrictMo...
  function pT (line 9) | function pT(t=!1){let e=[aT.default,sT.default,cT.default,uT.default,lT....
  method code (line 9) | code(t,e){let{gen:r,data:n,$data:o,schema:i,schemaCode:a,it:s}=t,{opts:c...
  method code (line 9) | code(t){let{gen:e,data:r,schema:n,parentSchema:o,it:i}=t,{oneOf:a}=o;if(...
  method _addVocabularies (line 9) | _addVocabularies(){super._addVocabularies(),ET.default.forEach(e=>this.a...
  method _addDefaultMetaSchema (line 9) | _addDefaultMetaSchema(){if(super._addDefaultMetaSchema(),!this.opts.meta...
  method defaultMeta (line 9) | defaultMeta(){return this.opts.defaultMeta=super.defaultMeta()||(this.ge...
  function St (line 9) | function St(t,e){return{validate:t,compare:e}}
  function NT (line 9) | function NT(t){return t%4===0&&(t%100!==0||t%400===0)}
  function Dy (line 9) | function Dy(t){let e=RT.exec(t);if(!e)return!1;let r=+e[1],n=+e[2],o=+e[...
  function yf (line 9) | function yf(t,e){if(t&&e)return t>e?1:t<e?-1:0}
  function vf (line 9) | function vf(t){return function(r){let n=gf.exec(r);if(!n)return!1;let o=...
  function $f (line 9) | function $f(t,e){if(!(t&&e))return;let r=new Date("2020-01-01T"+t).value...
  function Ny (line 9) | function Ny(t,e){if(!(t&&e))return;let r=gf.exec(t),n=gf.exec(e);if(r&&n...
  function Py (line 9) | function Py(t){let e=vf(t);return function(n){let o=n.split(_f);return o...
  function Ry (line 9) | function Ry(t,e){if(!(t&&e))return;let r=new Date(t).valueOf(),n=new Dat...
  function Ay (line 9) | function Ay(t,e){if(!(t&&e))return;let[r,n]=t.split(_f),[o,i]=e.split(_f...
  function UT (line 9) | function UT(t){return MT.test(t)&&CT.test(t)}
  function ZT (line 9) | function ZT(t){return Oy.lastIndex=0,Oy.test(t)}
  function FT (line 9) | function FT(t){return Number.isInteger(t)&&t<=qT&&t>=LT}
  function VT (line 9) | function VT(t){return Number.isInteger(t)}
  function jy (line 9) | function jy(){return!0}
  function WT (line 9) | function WT(t){if(JT.test(t))return!1;try{return new RegExp(t),!0}catch{...
  method code (line 9) | code(t){let{gen:e,data:r,schemaCode:n,keyword:o,it:i}=t,{opts:a,self:s}=...
  function Zy (line 9) | function Zy(t,e,r,n){var o,i;(o=(i=t.opts.code).formats)!==null&&o!==voi...
  method constructor (line 9) | constructor(){this.useColor=process.stdout.isTTY??!1}
  method ensureLogFileInitialized (line 9) | ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInit...
  method getLevel (line 9) | getLevel(){if(this.level===null)try{let e=(0,En.join)(Mf,"settings.json"...
  method correlationId (line 9) | correlationId(e,r){return`obs-${e}-${r}`}
  method sessionId (line 9) | sessionId(e){return`session-${e}`}
  method formatData (line 9) | formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(type...
  method formatTool (line 10) | formatTool(e,r){if(!r)return e;let n=r;if(typeof r=="string")try{n=JSON....
  method formatTimestamp (line 10) | formatTimestamp(e){let r=e.getFullYear(),n=String(e.getMonth()+1).padSta...
  method log (line 10) | log(e,r,n,o,i){if(e<this.getLevel())return;this.ensureLogFileInitialized...
  method debug (line 16) | debug(e,r,n,o){this.log(0,e,r,n,o)}
  method info (line 16) | info(e,r,n,o){this.log(1,e,r,n,o)}
  method warn (line 16) | warn(e,r,n,o){this.log(2,e,r,n,o)}
  method error (line 16) | error(e,r,n,o){this.log(3,e,r,n,o)}
  method dataIn (line 16) | dataIn(e,r,n,o){this.info(e,`\u2192 ${r}`,n,o)}
  method dataOut (line 16) | dataOut(e,r,n,o){this.info(e,`\u2190 ${r}`,n,o)}
  method success (line 16) | success(e,r,n,o){this.info(e,`\u2713 ${r}`,n,o)}
  method failure (line 16) | failure(e,r,n,o){this.error(e,`\u2717 ${r}`,n,o)}
  method timing (line 16) | timing(e,r,n,o){this.info(e,`\u23F1 ${r}`,o,{duration:`${n}ms`})}
  method happyPathError (line 16) | happyPathError(e,r,n,o,i=""){let u=((new Error().stack||"").split(`
  function e (line 17) | function e(o){}
  function r (line 17) | function r(o){throw new Error}
  function n (line 17) | function n(o,i=" | "){return o.map(a=>typeof a=="string"?`'${a}'`:a).joi...
  method errors (line 17) | get errors(){return this.issues}
  method constructor (line 17) | constructor(e){super(),this.issues=[],this.addIssue=n=>{this.issues=[......
  method format (line 17) | format(e){let r=e||function(i){return i.message},n={_errors:[]},o=i=>{fo...
  method assert (line 17) | static assert(e){if(!(e instanceof t))throw new Error(`Not a ZodError: $...
  method toString (line 17) | toString(){return this.message}
  method message (line 17) | get message(){return JSON.stringify(this.issues,X.jsonStringifyReplacer,2)}
  method isEmpty (line 17) | get isEmpty(){return this.issues.length===0}
  method flatten (line 17) | flatten(e=r=>r.message){let r=Object.create(null),n=[];for(let o of this...
  method formErrors (line 17) | get formErrors(){return this.flatten()}
  function Tn (line 17) | function Tn(){return k$}
  function x (line 17) | function x(t,e){let r=Tn(),n=_i({issueData:e,data:t.data,path:t.path,err...
  method constructor (line 17) | constructor(){this.value="valid"}
  method dirty (line 17) | dirty(){this.value==="valid"&&(this.value="dirty")}
  method abort (line 17) | abort(){this.value!=="aborted"&&(this.value="aborted")}
  method mergeArray (line 17) | static mergeArray(e,r){let n=[];for(let o of r){if(o.status==="aborted")...
  method mergeObjectAsync (line 17) | static async mergeObjectAsync(e,r){let n=[];for(let o of r){let i=await ...
  method mergeObjectSync (line 17) | static mergeObjectSync(e,r){let n={};for(let o of r){let{key:i,value:a}=...
  method constructor (line 17) | constructor(e,r,n,o){this._cachedPath=[],this.parent=e,this.data=r,this....
  method path (line 17) | get path(){return this._cachedPath.length||(Array.isArray(this._key)?thi...
  method error (line 17) | get error(){if(this._error)return this._error;let r=new Ke(t.common.issu...
  function L (line 17) | function L(t){if(!t)return{};let{errorMap:e,invalid_type_error:r,require...
  method description (line 17) | get description(){return this._def.description}
  method _getType (line 17) | _getType(e){return Tt(e.data)}
  method _getOrReturnCtx (line 17) | _getOrReturnCtx(e,r){return r||{common:e.parent.common,data:e.data,parse...
  method _processInputParams (line 17) | _processInputParams(e){return{status:new Ee,ctx:{common:e.parent.common,...
  method _parseSync (line 17) | _parseSync(e){let r=this._parse(e);if(Pn(r))throw new Error("Synchronous...
  method _parseAsync (line 17) | _parseAsync(e){let r=this._parse(e);return Promise.resolve(r)}
  method parse (line 17) | parse(e,r){let n=this.safeParse(e,r);if(n.success)return n.data;throw n....
  method safeParse (line 17) | safeParse(e,r){let n={common:{issues:[],async:r?.async??!1,contextualErr...
  method "~validate" (line 17) | "~validate"(e){let r={common:{issues:[],async:!!this["~standard"].async}...
  method parseAsync (line 17) | async parseAsync(e,r){let n=await this.safeParseAsync(e,r);if(n.success)...
  method safeParseAsync (line 17) | async safeParseAsync(e,r){let n={common:{issues:[],contextualErrorMap:r?...
  method refine (line 17) | refine(e,r){let n=o=>typeof r=="string"||typeof r>"u"?{message:r}:typeof...
  method refinement (line 17) | refinement(e,r){return this._refinement((n,o)=>e(n)?!0:(o.addIssue(typeo...
  method _refinement (line 17) | _refinement(e){return new lt({schema:this,typeName:D.ZodEffects,effect:{...
  method superRefine (line 17) | superRefine(e){return this._refinement(e)}
  method constructor (line 17) | constructor(e){this.spa=this.safeParseAsync,this._def=e,this.parse=this....
  method optional (line 17) | optional(){return ut.create(this,this._def)}
  method nullable (line 17) | nullable(){return jt.create(this,this._def)}
  method nullish (line 17) | nullish(){return this.nullable().optional()}
  method array (line 17) | array(){return Bt.create(this)}
  method promise (line 17) | promise(){return mr.create(this,this._def)}
  method or (line 17) | or(e){return Cr.create([this,e],this._def)}
  method and (line 17) | and(e){return Ur.create(this,e,this._def)}
  method transform (line 17) | transform(e){return new lt({...L(this._def),schema:this,typeName:D.ZodEf...
  method default (line 17) | default(e){let r=typeof e=="function"?e:()=>e;return new Vr({...L(this._...
  method brand (line 17) | brand(){return new yi({typeName:D.ZodBranded,type:this,...L(this._def)})}
  method catch (line 17) | catch(e){let r=typeof e=="function"?e:()=>e;return new Jr({...L(this._de...
  method describe (line 17) | describe(e){let r=this.constructor;return new r({...this._def,descriptio...
  method pipe (line 17) | pipe(e){return $i.create(this,e)}
  method readonly (line 17) | readonly(){return Wr.create(this)}
  method isOptional (line 17) | isOptional(){return this.safeParse(void 0).success}
  method isNullable (line 17) | isNullable(){return this.safeParse(null).success}
  function qf (line 17) | function qf(t){let e="[0-5]\\d";t.precision?e=`${e}\\.\\d{${t.precision}...
  function Z$ (line 17) | function Z$(t){return new RegExp(`^${qf(t)}$`)}
  function L$ (line 17) | function L$(t){let e=`${Lf}T${qf(t)}`,r=[];return r.push(t.local?"Z?":"Z...
  function q$ (line 17) | function q$(t,e){return!!((e==="v4"||!e)&&D$.test(t)||(e==="v6"||!e)&&R$...
  function F$ (line 17) | function F$(t,e){if(!T$.test(t))return!1;try{let[r]=t.split(".");if(!r)r...
  function V$ (line 17) | function V$(t,e){return!!((e==="v4"||!e)&&N$.test(t)||(e==="v6"||!e)&&A$...
  method _parse (line 17) | _parse(e){if(this._def.coerce&&(e.data=String(e.data)),this._getType(e)!...
  method _regex (line 17) | _regex(e,r,n){return this.refinement(o=>e.test(o),{validation:r,code:y.i...
  method _addCheck (line 17) | _addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}
  method email (line 17) | email(e){return this._addCheck({kind:"email",...T.errToObj(e)})}
  method url (line 17) | url(e){return this._addCheck({kind:"url",...T.errToObj(e)})}
  method emoji (line 17) | emoji(e){return this._addCheck({kind:"emoji",...T.errToObj(e)})}
  method uuid (line 17) | uuid(e){return this._addCheck({kind:"uuid",...T.errToObj(e)})}
  method nanoid (line 17) | nanoid(e){return this._addCheck({kind:"nanoid",...T.errToObj(e)})}
  method cuid (line 17) | cuid(e){return this._addCheck({kind:"cuid",...T.errToObj(e)})}
  method cuid2 (line 17) | cuid2(e){return this._addCheck({kind:"cuid2",...T.errToObj(e)})}
  method ulid (line 17) | ulid(e){return this._addCheck({kind:"ulid",...T.errToObj(e)})}
  method base64 (line 17) | base64(e){return this._addCheck({kind:"base64",...T.errToObj(e)})}
  method base64url (line 17) | base64url(e){return this._addCheck({kind:"base64url",...T.errToObj(e)})}
  method jwt (line 17) | jwt(e){return this._addCheck({kind:"jwt",...T.errToObj(e)})}
  method ip (line 17) | ip(e){return this._addCheck({kind:"ip",...T.errToObj(e)})}
  method cidr (line 17) | cidr(e){return this._addCheck({kind:"cidr",...T.errToObj(e)})}
  method datetime (line 17) | datetime(e){return typeof e=="string"?this._addCheck({kind:"datetime",pr...
  method date (line 17) | date(e){return this._addCheck({kind:"date",message:e})}
  method time (line 17) | time(e){return typeof e=="string"?this._addCheck({kind:"time",precision:...
  method duration (line 17) | duration(e){return this._addCheck({kind:"duration",...T.errToObj(e)})}
  method regex (line 17) | regex(e,r){return this._addCheck({kind:"regex",regex:e,...T.errToObj(r)})}
  method includes (line 17) | includes(e,r){return this._addCheck({kind:"includes",value:e,position:r?...
  method startsWith (line 17) | startsWith(e,r){return this._addCheck({kind:"startsWith",value:e,...T.er...
  method endsWith (line 17) | endsWith(e,r){return this._addCheck({kind:"endsWith",value:e,...T.errToO...
  method min (line 17) | min(e,r){return this._addCheck({kind:"min",value:e,...T.errToObj(r)})}
  method max (line 17) | max(e,r){return this._addCheck({kind:"max",value:e,...T.errToObj(r)})}
  method length (line 17) | length(e,r){return this._addCheck({kind:"length",value:e,...T.errToObj(r...
  method nonempty (line 17) | nonempty(e){return this.min(1,T.errToObj(e))}
  method trim (line 17) | trim(){return new t({...this._def,checks:[...this._def.checks,{kind:"tri...
  method toLowerCase (line 17) | toLowerCase(){return new t({...this._def,checks:[...this._def.checks,{ki...
  method toUpperCase (line 17) | toUpperCase(){return new t({...this._def,checks:[...this._def.checks,{ki...
  method isDatetime (line 17) | get isDatetime(){return!!this._def.checks.find(e=>e.kind==="datetime")}
  method isDate (line 17) | get isDate(){return!!this._def.checks.find(e=>e.kind==="date")}
  method isTime (line 17) | get isTime(){return!!this._def.checks.find(e=>e.kind==="time")}
  method isDuration (line 17) | get isDuration(){return!!this._def.checks.find(e=>e.kind==="duration")}
  method isEmail (line 17) | get isEmail(){return!!this._def.checks.find(e=>e.kind==="email")}
  method isURL (line 17) | get isURL(){return!!this._def.checks.find(e=>e.kind==="url")}
  method isEmoji (line 17) | get isEmoji(){return!!this._def.checks.find(e=>e.kind==="emoji")}
  method isUUID (line 17) | get isUUID(){return!!this._def.checks.find(e=>e.kind==="uuid")}
  method isNANOID (line 17) | get isNANOID(){return!!this._def.checks.find(e=>e.kind==="nanoid")}
  method isCUID (line 17) | get isCUID(){return!!this._def.checks.find(e=>e.kind==="cuid")}
  method isCUID2 (line 17) | get isCUID2(){return!!this._def.checks.find(e=>e.kind==="cuid2")}
  method isULID (line 17) | get isULID(){return!!this._def.checks.find(e=>e.kind==="ulid")}
  method isIP (line 17) | get isIP(){return!!this._def.checks.find(e=>e.kind==="ip")}
  method isCIDR (line 17) | get isCIDR(){return!!this._def.checks.find(e=>e.kind==="cidr")}
  method isBase64 (line 17) | get isBase64(){return!!this._def.checks.find(e=>e.kind==="base64")}
  method isBase64url (line 17) | get isBase64url(){return!!this._def.checks.find(e=>e.kind==="base64url")}
  method minLength (line 17) | get minLength(){let e=null;for(let r of this._def.checks)r.kind==="min"&...
  method maxLength (line 17) | get maxLength(){let e=null;for(let r of this._def.checks)r.kind==="max"&...
  function J$ (line 17) | function J$(t,e){let r=(t.toString().split(".")[1]||"").length,n=(e.toSt...
  method constructor (line 17) | constructor(){super(...arguments),this.min=this.gte,this.max=this.lte,th...
  method _parse (line 17) | _parse(e){if(this._def.coerce&&(e.data=Number(e.data)),this._getType(e)!...
  method gte (line 17) | gte(e,r){return this.setLimit("min",e,!0,T.toString(r))}
  method gt (line 17) | gt(e,r){return this.setLimit("min",e,!1,T.toString(r))}
  method lte (line 17) | lte(e,r){return this.setLimit("max",e,!0,T.toString(r))}
  method lt (line 17) | lt(e,r){return this.setLimit("max",e,!1,T.toString(r))}
  method setLimit (line 17) | setLimit(e,r,n,o){return new t({...this._def,checks:[...this._def.checks...
  method _addCheck (line 17) | _addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}
  method int (line 17) | int(e){return this._addCheck({kind:"int",message:T.toString(e)})}
  method positive (line 17) | positive(e){return this._addCheck({kind:"min",value:0,inclusive:!1,messa...
  method negative (line 17) | negative(e){return this._addCheck({kind:"max",value:0,inclusive:!1,messa...
  method nonpositive (line 17) | nonpositive(e){return this._addCheck({kind:"max",value:0,inclusive:!0,me...
  method nonnegative (line 17) | nonnegative(e){return this._addCheck({kind:"min",value:0,inclusive:!0,me...
  method multipleOf (line 17) | multipleOf(e,r){return this._addCheck({kind:"multipleOf",value:e,message...
  method finite (line 17) | finite(e){return this._addCheck({kind:"finite",message:T.toString(e)})}
  method safe (line 17) | safe(e){return this._addCheck({kind:"min",inclusive:!0,value:Number.MIN_...
  method minValue (line 17) | get minValue(){let e=null;for(let r of this._def.checks)r.kind==="min"&&...
  method maxValue (line 17) | get maxValue(){let e=null;for(let r of this._def.checks)r.kind==="max"&&...
  method isInt (line 17) | get isInt(){return!!this._def.checks.find(e=>e.kind==="int"||e.kind==="m...
  method isFinite (line 17) | get isFinite(){let e=null,r=null;for(let n of this._def.checks){if(n.kin...
  method constructor (line 17) | constructor(){super(...arguments),this.min=this.gte,this.max=this.lte}
  method _parse (line 17) | _parse(e){if(this._def.coerce)try{e.data=BigInt(e.data)}catch{return thi...
  method _getInvalidInput (line 17) | _getInvalidInput(e){let r=this._getOrReturnCtx(e);return x(r,{code:y.inv...
  method gte (line 17) | gte(e,r){return this.setLimit("min",e,!0,T.toString(r))}
  method gt (line 17) | gt(e,r){return this.setLimit("min",e,!1,T.toString(r))}
  method lte (line 17) | lte(e,r){return this.setLimit("max",e,!0,T.toString(r))}
  method lt (line 17) | lt(e,r){return this.setLimit("max",e,!1,T.toString(r))}
  method setLimit (line 17) | setLimit(e,r,n,o){return new t({...this._def,checks:[...this._def.checks...
  method _addCheck (line 17) | _addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}
  method positive (line 17) | positive(e){return this._addCheck({kind:"min",value:BigInt(0),inclusive:...
  method negative (line 17) | negative(e){return this._addCheck({kind:"max",value:BigInt(0),inclusive:...
  method nonpositive (line 17) | nonpositive(e){return this._addCheck({kind:"max",value:BigInt(0),inclusi...
  method nonnegative (line 17) | nonnegative(e){return this._addCheck({kind:"min",value:BigInt(0),inclusi...
  method multipleOf (line 17) | multipleOf(e,r){return this._addCheck({kind:"multipleOf",value:e,message...
  method minValue (line 17) | get minValue(){let e=null;for(let r of this._def.checks)r.kind==="min"&&...
  method maxValue (line 17) | get maxValue(){let e=null;for(let r of this._def.checks)r.kind==="max"&&...
  method _parse (line 17) | _parse(e){if(this._def.coerce&&(e.data=!!e.data),this._getType(e)!==w.bo...
  method _parse (line 17) | _parse(e){if(this._def.coerce&&(e.data=new Date(e.data)),this._getType(e...
  method _addCheck (line 17) | _addCheck(e){return new t({...this._def,checks:[...this._def.checks,e]})}
  method min (line 17) | min(e,r){return this._addCheck({kind:"min",value:e.getTime(),message:T.t...
  method max (line 17) | max(e,r){return this._addCheck({kind:"max",value:e.getTime(),message:T.t...
  method minDate (line 17) | get minDate(){let e=null;for(let r of this._def.checks)r.kind==="min"&&(...
  method maxDate (line 17) | get maxDate(){let e=null;for(let r of this._def.checks)r.kind==="max"&&(...
  method _parse (line 17) | _parse(e){if(this._getType(e)!==w.symbol){let n=this._getOrReturnCtx(e);...
  method _parse (line 17) | _parse(e){if(this._getType(e)!==w.undefined){let n=this._getOrReturnCtx(...
  method _parse (line 17) | _parse(e){if(this._getType(e)!==w.null){let n=this._getOrReturnCtx(e);re...
  method constructor (line 17) | constructor(){super(...arguments),this._any=!0}
  method _parse (line 17) | _parse(e){return Ne(e.data)}
  method constructor (line 17) | constructor(){super(...arguments),this._unknown=!0}
  method _parse (line 17) | _parse(e){return Ne(e.data)}
  method _parse (line 17) | _parse(e){let r=this._getOrReturnCtx(e);return x(r,{code:y.invalid_type,...
  method _parse (line 17) | _parse(e){if(this._getType(e)!==w.undefined){let n=this._getOrReturnCtx(...
  method _parse (line 17) | _parse(e){let{ctx:r,status:n}=this._processInputParams(e),o=this._def;if...
  method element (line 17) | get element(){return this._def.type}
  method min (line 17) | min(e,r){return new t({...this._def,minLength:{value:e,message:T.toStrin...
  method max (line 17) | max(e,r){return new t({...this._def,maxLength:{value:e,message:T.toStrin...
  method length (line 17) | length(e,r){return new t({...this._def,exactLength:{value:e,message:T.to...
  method nonempty (line 17) | nonempty(e){return this.min(1,e)}
  function Nr (line 17) | function Nr(t){if(t instanceof He){let e={};for(let r in t.shape){let n=...
  method constructor (line 17) | constructor(){super(...arguments),this._cached=null,this.nonstrict=this....
  method _getCached (line 17) | _getCached(){if(this._cached!==null)return this._cached;let e=this._def....
  method _parse (line 17) | _parse(e){if(this._getType(e)!==w.object){let u=this._getOrReturnCtx(e);...
  method shape (line 17) | get shape(){return this._def.shape()}
  method strict (line 17) | strict(e){return T.errToObj,new t({...this._def,unknownKeys:"strict",......
  method strip (line 17) | strip(){return new t({...this._def,unknownKeys:"strip"})}
  method passthrough (line 17) | passthrough(){return new t({...this._def,unknownKeys:"passthrough"})}
  method extend (line 17) | extend(e){return new t({...this._def,shape:()=>({...this._def.shape(),.....
  method merge (line 17) | merge(e){return new t({unknownKeys:e._def.unknownKeys,catchall:e._def.ca...
  method setKey (line 17) | setKey(e,r){return this.augment({[e]:r})}
  method catchall (line 17) | catchall(e){return new t({...this._def,catchall:e})}
  method pick (line 17) | pick(e){let r={};for(let n of X.objectKeys(e))e[n]&&this.shape[n]&&(r[n]...
  method omit (line 17) | omit(e){let r={};for(let n of X.objectKeys(this.shape))e[n]||(r[n]=this....
  method deepPartial (line 17) | deepPartial(){return Nr(this)}
  method partial (line 17) | partial(e){let r={};for(let n of X.objectKeys(this.shape)){let o=this.sh...
  method required (line 17) | required(e){let r={};for(let n of X.objectKeys(this.shape))if(e&&!e[n])r...
  method keyof (line 17) | keyof(){return Ff(X.objectKeys(this.shape))}
  method _parse (line 17) | _parse(e){let{ctx:r}=this._processInputParams(e),n=this._def.options;fun...
  method options (line 17) | get options(){return this._def.options}
  method _parse (line 17) | _parse(e){let{ctx:r}=this._processInputParams(e);if(r.parsedType!==w.obj...
  method discriminator (line 17) | get discriminator(){return this._def.discriminator}
  method options (line 17) | get options(){return this._def.options}
  method optionsMap (line 17) | get optionsMap(){return this._def.optionsMap}
  method create (line 17) | static create(e,r,n){let o=new Map;for(let i of r){let a=Pt(i.shape[e]);...
  function qs (line 17) | function qs(t,e){let r=Tt(t),n=Tt(e);if(t===e)return{valid:!0,data:t};if...
  method _parse (line 17) | _parse(e){let{status:r,ctx:n}=this._processInputParams(e),o=(i,a)=>{if(C...
  method _parse (line 17) | _parse(e){let{status:r,ctx:n}=this._processInputParams(e);if(n.parsedTyp...
  method items (line 17) | get items(){return this._def.items}
  method rest (line 17) | rest(e){return new t({...this._def,rest:e})}
  method keySchema (line 17) | get keySchema(){return this._def.keyType}
  method valueSchema (line 17) | get valueSchema(){return this._def.valueType}
  method _parse (line 17) | _parse(e){let{status:r,ctx:n}=this._processInputParams(e);if(n.parsedTyp...
  method element (line 17) | get element(){return this._def.valueType}
  method create (line 17) | static create(e,r,n){return r instanceof K?new t({keyType:e,valueType:r,...
  method keySchema (line 17) | get keySchema(){return this._def.keyType}
  method valueSchema (line 17) | get valueSchema(){return this._def.valueType}
  method _parse (line 17) | _parse(e){let{status:r,ctx:n}=this._processInputParams(e);if(n.parsedTyp...
  method _parse (line 17) | _parse(e){let{status:r,ctx:n}=this._processInputParams(e);if(n.parsedTyp...
  method min (line 17) | min(e,r){return new t({...this._def,minSize:{value:e,message:T.toString(...
  method max (line 17) | max(e,r){return new t({...this._def,maxSize:{value:e,message:T.toString(...
  method size (line 17) | size(e,r){return this.min(e,r).max(e,r)}
  method nonempty (line 17) | nonempty(e){return this.min(1,e)}
  method constructor (line 17) | constructor(){super(...arguments),this.validate=this.implement}
  method _parse (line 17) | _parse(e){let{ctx:r}=this._processInputParams(e);if(r.parsedType!==w.fun...
  method parameters (line 17) | parameters(){return this._def.args}
  method returnType (line 17) | returnType(){return this._def.returns}
  method args (line 17) | args(...e){return new t({...this._def,args:Ot.create(e).rest(Gt.create()...
  method returns (line 17) | returns(e){return new t({...this._def,returns:e})}
  method implement (line 17) | implement(e){return this.parse(e)}
  method strictImplement (line 17) | strictImplement(e){return this.parse(e)}
  method create (line 17) | static create(e,r,n){return new t({args:e||Ot.create([]).rest(Gt.create(...
  method schema (line 17) | get schema(){return this._def.getter()}
  method _parse (line 17) | _parse(e){let{ctx:r}=this._processInputParams(e);return this._def.getter...
  method _parse (line 17) | _parse(e){if(e.data!==this._def.value){let r=this._getOrReturnCtx(e);ret...
  method value (line 17) | get value(){return this._def.value}
  function Ff (line 17) | function Ff(t,e){return new qr({values:t,typeName:D.ZodEnum,...L(e)})}
  method _parse (line 17) | _parse(e){if(typeof e.data!="string"){let r=this._getOrReturnCtx(e),n=th...
  method options (line 17) | get options(){return this._def.values}
  method enum (line 17) | get enum(){let e={};for(let r of this._def.values)e[r]=r;return e}
  method Values (line 17) | get Values(){let e={};for(let r of this._def.values)e[r]=r;return e}
  method Enum (line 17) | get Enum(){let e={};for(let r of this._def.values)e[r]=r;return e}
  method extract (line 17) | extract(e,r=this._def){return t.create(e,{...this._def,...r})}
  method exclude (line 17) | exclude(e,r=this._def){return t.create(this.options.filter(n=>!e.include...
  method _parse (line 17) | _parse(e){let r=X.getValidEnumValues(this._def.values),n=this._getOrRetu...
  method enum (line 17) | get enum(){return this._def.values}
  method unwrap (line 17) | unwrap(){return this._def.type}
  method _parse (line 17) | _parse(e){let{ctx:r}=this._processInputParams(e);if(r.parsedType!==w.pro...
  method innerType (line 17) | innerType(){return this._def.schema}
  method sourceType (line 17) | sourceType(){return this._def.schema._def.typeName===D.ZodEffects?this._...
  method _parse (line 17) | _parse(e){let{status:r,ctx:n}=this._processInputParams(e),o=this._def.ef...
  method _parse (line 17) | _parse(e){return this._getType(e)===w.undefined?Ne(void 0):this._def.inn...
  method unwrap (line 17) | unwrap(){return this._def.innerType}
  method _parse (line 17) | _parse(e){return this._getType(e)===w.null?Ne(null):this._def.innerType....
  method unwrap (line 17) | unwrap(){return this._def.innerType}
  method _parse (line 17) | _parse(e){let{ctx:r}=this._processInputParams(e),n=r.data;return r.parse...
  method removeDefault (line 17) | removeDefault(){return this._def.innerType}
  method _parse (line 17) | _parse(e){let{ctx:r}=this._processInputParams(e),n={...r,common:{...r.co...
  method removeCatch (line 17) | removeCatch(){return this._def.innerType}
  method _parse (line 17) | _parse(e){if(this._getType(e)!==w.nan){let n=this._getOrReturnCtx(e);ret...
  method _parse (line 17) | _parse(e){let{ctx:r}=this._processInputParams(e),n=r.data;return this._d...
  method unwrap (line 17) | unwrap(){return this._def.type}
  method _parse (line 17) | _parse(e){let{status:r,ctx:n}=this._processInputParams(e);if(n.common.as...
  method create (line 17) | static create(e,r){return new t({in:e,out:r,typeName:D.ZodPipeline})}
  method _parse (line 17) | _parse(e){let r=this._def.innerType._parse(e),n=o=>(fr(o)&&(o.value=Obje...
  method unwrap (line 17) | unwrap(){return this._def.innerType}
  function m (line 17) | function m(t,e,r){function n(s,c){if(s._zod||Object.defineProperty(s,"_z...
  method constructor (line 17) | constructor(){super("Encountered Promise during synchronous parse. Use ....
  method constructor (line 17) | constructor(e){super(`Encountered unidirectional transform during encode...
  function be (line 17) | function be(t){return t&&Object.assign(bi,t),bi}
  function G$ (line 17) | function G$(t){return t}
  function B$ (line 17) | function B$(t){return t}
  function X$ (line 17) | function X$(t){}
  function Y$ (line 17) | function Y$(t){throw new Error("Unexpected value in exhaustive check")}
  function Q$ (line 17) | function Q$(t){}
  function qn (line 17) | function qn(t){let e=Object.values(t).filter(n=>typeof n=="number");retu...
  function N (line 17) | function N(t,e="|"){return t.map(r=>R(r)).join(e)}
  function Kr (line 17) | function Kr(t,e){return typeof e=="bigint"?e.toString():e}
  function Hr (line 17) | function Hr(t){return{get value(){{let r=t();return Object.definePropert...
  function Xt (line 17) | function Xt(t){return t==null}
  function Fn (line 17) | function Fn(t){let e=t.startsWith("^")?1:0,r=t.endsWith("$")?t.length-1:...
  function Ks (line 17) | function Ks(t,e){let r=(t.toString().split(".")[1]||"").length,n=e.toStr...
  function q (line 17) | function q(t,e,r){let n;Object.defineProperty(t,e,{get(){if(n!==Jf)retur...
  function eb (line 17) | function eb(t){return Object.create(Object.getPrototypeOf(t),Object.getO...
  function Yt (line 17) | function Yt(t,e,r){Object.defineProperty(t,e,{value:r,writable:!0,enumer...
  function Dt (line 17) | function Dt(...t){let e={};for(let r of t){let n=Object.getOwnPropertyDe...
  function tb (line 17) | function tb(t){return Dt(t._zod.def)}
  function rb (line 17) | function rb(t,e){return e?e.reduce((r,n)=>r?.[n],t):t}
  function nb (line 17) | function nb(t){let e=Object.keys(t),r=e.map(n=>t[n]);return Promise.all(...
  function ob (line 17) | function ob(t=10){let e="abcdefghijklmnopqrstuvwxyz",r="";for(let n=0;n<...
  function xi (line 17) | function xi(t){return JSON.stringify(t)}
  function Hs (line 17) | function Hs(t){return t.toLowerCase().trim().replace(/[^\w\s-]/g,"").rep...
  function gr (line 17) | function gr(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}
  function Qt (line 17) | function Qt(t){if(gr(t)===!1)return!1;let e=t.constructor;if(e===void 0|...
  function Bs (line 17) | function Bs(t){return Qt(t)?{...t}:Array.isArray(t)?[...t]:t}
  function ib (line 17) | function ib(t){let e=0;for(let r in t)Object.prototype.hasOwnProperty.ca...
  function tt (line 17) | function tt(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}
  function Re (line 17) | function Re(t,e,r){let n=new t._zod.constr(e??t._zod.def);return(!e||r?....
  function k (line 17) | function k(t){let e=t;if(!e)return{};if(typeof e=="string")return{error:...
  function sb (line 17) | function sb(t){let e;return new Proxy({},{get(r,n,o){return e??(e=t()),R...
  function R (line 17) | function R(t){return typeof t=="bigint"?t.toString()+"n":typeof t=="stri...
  function Ys (line 17) | function Ys(t){return Object.keys(t).filter(e=>t[e]._zod.optin==="option...
  function Wf (line 17) | function Wf(t,e){let r=t._zod.def,n=r.checks;if(n&&n.length>0)throw new ...
  function Kf (line 17) | function Kf(t,e){let r=t._zod.def,n=r.checks;if(n&&n.length>0)throw new ...
  function Hf (line 17) | function Hf(t,e){if(!Qt(e))throw new Error("Invalid input to extend: exp...
  function Gf (line 17) | function Gf(t,e){if(!Qt(e))throw new Error("Invalid input to safeExtend:...
  function cb (line 17) | function cb(t,e){let r=Dt(t._zod.def,{get shape(){let n={...t._zod.def.s...
  function Bf (line 17) | function Bf(t,e,r){let o=e._zod.def.checks;if(o&&o.length>0)throw new Er...
  function Xf (line 17) | function Xf(t,e,r){let n=Dt(e._zod.def,{get shape(){let o=e._zod.def.sha...
  function er (line 17) | function er(t,e=0){if(t.aborted===!0)return!0;for(let r=e;r<t.issues.len...
  function Ge (line 17) | function Ge(t,e){return e.map(r=>{var n;return(n=r).path??(n.path=[]),r....
  function Ln (line 17) | function Ln(t){return typeof t=="string"?t:t?.message}
  function qe (line 17) | function qe(t,e,r){let n={...t,path:t.path??[]};if(!t.message){let o=Ln(...
  function Jn (line 17) | function Jn(t){return t instanceof Set?"set":t instanceof Map?"map":t in...
  function Wn (line 17) | function Wn(t){return Array.isArray(t)?"array":typeof t=="string"?"strin...
  function C (line 17) | function C(t){let e=typeof t;switch(e){case"number":return Number.isNaN(...
  function Gr (line 17) | function Gr(...t){let[e,r,n]=t;return typeof e=="string"?{message:e,code...
  function ub (line 17) | function ub(t){return Object.entries(t).filter(([e,r])=>Number.isNaN(Num...
  function Yf (line 17) | function Yf(t){let e=atob(t),r=new Uint8Array(e.length);for(let n=0;n<e....
  function Qf (line 17) | function Qf(t){let e="";for(let r=0;r<t.length;r++)e+=String.fromCharCod...
  function lb (line 17) | function lb(t){let e=t.replace(/-/g,"+").replace(/_/g,"/"),r="=".repeat(...
  function db (line 17) | function db(t){return Qf(t).replace(/\+/g,"-").replace(/\//g,"_").replac...
  function pb (line 17) | function pb(t){let e=t.replace(/^0x/,"");if(e.length%2!==0)throw new Err...
  function fb (line 17) | function fb(t){return Array.from(t).map(e=>e.toString(16).padStart(2,"0"...
  method constructor (line 17) | constructor(...e){}
  function wi (line 17) | function wi(t,e=r=>r.message){let r={},n=[];for(let o of t.issues)o.path...
  function zi (line 17) | function zi(t,e=r=>r.message){let r={_errors:[]},n=o=>{for(let i of o.is...
  function lc (line 17) | function lc(){return new RegExp(kb,"u")}
  function dm (line 17) | function dm(t){let e="(?:[01]\\d|2[0-3]):[0-5]\\d";return typeof t.preci...
  function yc (line 17) | function yc(t){return new RegExp(`^${dm(t)}$`)}
  function $c (line 17) | function $c(t){let e=dm({precision:t.precision}),r=["Z"];t.local&&r.push...
  function to (line 17) | function to(t,e){return new RegExp(`^[A-Za-z0-9+/]{${t}}${e}$`)}
  function ro (line 17) | function ro(t){return new RegExp(`^[A-Za-z0-9_-]{${t}}$`)}
  function pm (line 17) | function pm(t,e,r){t.issues.length&&e.issues.push(...Ge(r,t.issues))}
  method constructor (line 17) | constructor(e=[]){this.content=[],this.indent=0,this&&(this.args=e)}
  method indented (line 17) | indented(e){this.indent+=1,e(this),this.indent-=1}
  method write (line 17) | write(e){if(typeof e=="function"){e(this,{execution:"sync"}),e(this,{exe...
  method compile (line 18) | compile(){let e=Function,r=this?.args,o=[...(this?.content??[""]).map(i=...
  function Jm (line 19) | function Jm(t){if(t==="")return!0;if(t.length%4!==0)return!1;try{return ...
  function qb (line 19) | function qb(t){if(!Ii.test(t))return!1;let e=t.replace(/[-_]/g,n=>n==="-...
  function Fb (line 19) | function Fb(t,e=null){try{let r=t.split(".");if(r.length!==3)return!1;le...
  function Nm (line 19) | function Nm(t,e,r){t.issues.length&&e.issues.push(...Ge(r,t.issues)),e.v...
  function Ni (line 19) | function Ni(t,e,r,n,o){if(t.issues.length){if(o&&!(r in n))return;e.issu...
  function Wm (line 19) | function Wm(t){let e=Object.keys(t.shape);for(let n of e)if(!t.shape?.[n...
  function Km (line 19) | function Km(t,e,r,n,o,i){let a=[],s=o.keySet,c=o.catchall._zod,u=c.def.t...
  function Rm (line 53) | function Rm(t,e,r,n){for(let i of t)if(i.issues.length===0)return e.valu...
  function Am (line 53) | function Am(t,e,r,n){let o=t.filter(i=>i.issues.length===0);return o.len...
  function Oc (line 53) | function Oc(t,e){if(t===e)return{valid:!0,data:t};if(t instanceof Date&&...
  function Mm (line 53) | function Mm(t,e,r){let n=new Map,o;for(let s of e.issues)if(s.code==="un...
  function Pi (line 53) | function Pi(t,e,r){t.issues.length&&e.issues.push(...Ge(r,t.issues)),e.v...
  function Cm (line 53) | function Cm(t,e,r,n,o,i,a){t.issues.length&&(Vn.has(typeof n)?r.issues.p...
  function Um (line 53) | function Um(t,e){t.issues.length&&e.issues.push(...t.issues),e.value.add...
  function Zm (line 53) | function Zm(t,e){return t.issues.length&&e===void 0?{issues:[],value:voi...
  function Lm (line 53) | function Lm(t,e){return t.value===void 0&&(t.value=e.defaultValue),t}
  function qm (line 53) | function qm(t,e){return!t.issues.length&&t.value===void 0&&t.issues.push...
  function Oi (line 53) | function Oi(t,e,r){return t.issues.length?(t.aborted=!0,t):e._zod.run({v...
  function ji (line 53) | function ji(t,e,r){if(t.issues.length)return t.aborted=!0,t;if((r.direct...
  function Di (line 53) | function Di(t,e,r,n){return t.issues.length?(t.aborted=!0,t):r._zod.run(...
  function Fm (line 53) | function Fm(t){return t.value=Object.freeze(t.value),t}
  function Vm (line 53) | function Vm(t,e,r,n){if(!t){let o={code:"custom",input:r,inst:n,path:[.....
  function e (line 53) | function e(o){return t[o]??null}
  function Uu (line 53) | function Uu(){return{localeError:Jb()}}
  method constructor (line 53) | constructor(){this._map=new WeakMap,this._idmap=new Map}
  method add (line 53) | add(e,...r){let n=r[0];return this._map.set(e,n),n&&typeof n=="object"&&...
  method clear (line 53) | clear(){return this._map=new WeakMap,this._idmap=new Map,this}
  method remove (line 53) | remove(e){let r=this._map.get(e);return r&&typeof r=="object"&&"id"in r&...
  method get (line 53) | get(e){let r=e._zod.parent;if(r){let n={...this.get(r)??{}};delete n.id;...
  method has (line 53) | has(e){return this._map.has(e)}
  function qu (line 53) | function qu(){return new Lu}
  function Fu (line 53) | function Fu(t,e){return new t({type:"string",...k(e)})}
  function Ui (line 53) | function Ui(t,e){return new t({type:"string",format:"email",check:"strin...
  function so (line 53) | function so(t,e){return new t({type:"string",format:"guid",check:"string...
  function Zi (line 53) | function Zi(t,e){return new t({type:"string",format:"uuid",check:"string...
  function Li (line 53) | function Li(t,e){return new t({type:"string",format:"uuid",check:"string...
  function qi (line 53) | function qi(t,e){return new t({type:"string",format:"uuid",check:"string...
  function Fi (line 53) | function Fi(t,e){return new t({type:"string",format:"uuid",check:"string...
  function co (line 53) | function co(t,e){return new t({type:"string",format:"url",check:"string_...
  function Vi (line 53) | function Vi(t,e){return new t({type:"string",format:"emoji",check:"strin...
  function Ji (line 53) | function Ji(t,e){return new t({type:"string",format:"nanoid",check:"stri...
  function Wi (line 53) | function Wi(t,e){return new t({type:"string",format:"cuid",check:"string...
  function Ki (line 53) | function Ki(t,e){return new t({type:"string",format:"cuid2",check:"strin...
  function Hi (line 53) | function Hi(t,e){return new t({type:"string",format:"ulid",check:"string...
  function Gi (line 53) | function Gi(t,e){return new t({type:"string",format:"xid",check:"string_...
  function Bi (line 53) | function Bi(t,e){return new t({type:"string",format:"ksuid",check:"strin...
  function Xi (line 53) | function Xi(t,e){return new t({type:"string",format:"ipv4",check:"string...
  function Yi (line 53) | function Yi(t,e){return new t({type:"string",format:"ipv6",check:"string...
  function Vu (line 53) | function Vu(t,e){return new t({type:"string",format:"mac",check:"string_...
  function Qi (line 53) | function Qi(t,e){return new t({type:"string",format:"cidrv4",check:"stri...
  function ea (line 53) | function ea(t,e){return new t({type:"string",format:"cidrv6",check:"stri...
  function ta (line 53) | function ta(t,e){return new t({type:"string",format:"base64",check:"stri...
  function ra (line 53) | function ra(t,e){return new t({type:"string",format:"base64url",check:"s...
  function na (line 53) | function na(t,e){return new t({type:"string",format:"e164",check:"string...
  function oa (line 53) | function oa(t,e){return new t({type:"string",format:"jwt",check:"string_...
  function Ju (line 53) | function Ju(t,e){return new t({type:"string",format:"datetime",check:"st...
  function Wu (line 53) | function Wu(t,e){return new t({type:"string",format:"date",check:"string...
  function Ku (line 53) | function Ku(t,e){return new t({type:"string",format:"time",check:"string...
  function Hu (line 53) | function Hu(t,e){return new t({type:"string",format:"duration",check:"st...
  function Gu (line 53) | function Gu(t,e){return new t({type:"number",checks:[],...k(e)})}
  function Bu (line 53) | function Bu(t,e){return new t({type:"number",check:"number_format",abort...
  function Xu (line 53) | function Xu(t,e){return new t({type:"number",check:"number_format",abort...
  function Yu (line 53) | function Yu(t,e){return new t({type:"number",check:"number_format",abort...
  function Qu (line 53) | function Qu(t,e){return new t({type:"number",check:"number_format",abort...
  function el (line 53) | function el(t,e){return new t({type:"number",check:"number_format",abort...
  function tl (line 53) | function tl(t,e){return new t({type:"boolean",...k(e)})}
  function rl (line 53) | function rl(t,e){return new t({type:"bigint",...k(e)})}
  function nl (line 53) | function nl(t,e){return new t({type:"bigint",check:"bigint_format",abort...
  function ol (line 53) | function ol(t,e){return new t({type:"bigint",check:"bigint_format",abort...
  function il (line 53) | function il(t,e){return new t({type:"symbol",...k(e)})}
  function al (line 53) | function al(t,e){return new t({type:"undefined",...k(e)})}
  function sl (line 53) | function sl(t,e){return new t({type:"null",...k(e)})}
  function cl (line 53) | function cl(t){return new t({type:"any"})}
  function ul (line 53) | function ul(t){return new t({type:"unknown"})}
  function ll (line 53) | function ll(t,e){return new t({type:"never",...k(e)})}
  function dl (line 53) | function dl(t,e){return new t({type:"void",...k(e)})}
  function pl (line 53) | function pl(t,e){return new t({type:"date",...k(e)})}
  function fl (line 53) | function fl(t,e){return new t({type:"nan",...k(e)})}
  function Nt (line 53) | function Nt(t,e){return new Tc({check:"less_than",...k(e),value:t,inclus...
  function Be (line 53) | function Be(t,e){return new Tc({check:"less_than",...k(e),value:t,inclus...
  function Rt (line 53) | function Rt(t,e){return new Pc({check:"greater_than",...k(e),value:t,inc...
  function Me (line 53) | function Me(t,e){return new Pc({check:"greater_than",...k(e),value:t,inc...
  function ml (line 53) | function ml(t){return Rt(0,t)}
  function hl (line 53) | function hl(t){return Nt(0,t)}
  function gl (line 53) | function gl(t){return Be(0,t)}
  function vl (line 53) | function vl(t){return Me(0,t)}
  function yr (line 53) | function yr(t,e){return new mm({check:"multiple_of",...k(e),value:t})}
  function $r (line 53) | function $r(t,e){return new vm({check:"max_size",...k(e),maximum:t})}
  function At (line 53) | function At(t,e){return new _m({check:"min_size",...k(e),minimum:t})}
  function Xr (line 53) | function Xr(t,e){return new ym({check:"size_equals",...k(e),size:t})}
  function Yr (line 53) | function Yr(t,e){return new $m({check:"max_length",...k(e),maximum:t})}
  function tr (line 53) | function tr(t,e){return new bm({check:"min_length",...k(e),minimum:t})}
  function Qr (line 53) | function Qr(t,e){return new xm({check:"length_equals",...k(e),length:t})}
  function uo (line 53) | function uo(t,e){return new km({check:"string_format",format:"regex",......
  function lo (line 53) | function lo(t){return new Sm({check:"string_format",format:"lowercase",....
  function po (line 53) | function po(t){return new wm({check:"string_format",format:"uppercase",....
  function fo (line 53) | function fo(t,e){return new zm({check:"string_format",format:"includes",...
  function mo (line 53) | function mo(t,e){return new Im({check:"string_format",format:"starts_wit...
  function ho (line 53) | function ho(t,e){return new Em({check:"string_format",format:"ends_with"...
  function _l (line 53) | function _l(t,e,r){return new Tm({check:"property",property:t,schema:e,....
  function go (line 53) | function go(t,e){return new Pm({check:"mime_type",mime:t,...k(e)})}
  function yt (line 53) | function yt(t){return new Om({check:"overwrite",tx:t})}
  function vo (line 53) | function vo(t){return yt(e=>e.normalize(t))}
  function _o (line 53) | function _o(){return yt(t=>t.trim())}
  function yo (line 53) | function yo(){return yt(t=>t.toLowerCase())}
  function $o (line 53) | function $o(){return yt(t=>t.toUpperCase())}
  function ia (line 53) | function ia(){return yt(t=>Hs(t))}
  function Xm (line 53) | function Xm(t,e,r){return new t({type:"array",element:e,...k(r)})}
  function yl (line 53) | function yl(t,e){return new t({type:"file",...k(e)})}
  function $l (line 53) | function $l(t,e,r){let n=k(r);return n.abort??(n.abort=!0),new t({type:"...
  function bl (line 53) | function bl(t,e,r){return new t({type:"custom",check:"custom",fn:e,...k(...
  function xl (line 53) | function xl(t){let e=Gb(r=>(r.addIssue=n=>{if(typeof n=="string")r.issue...
  function Gb (line 53) | function Gb(t,e){let r=new se({check:"custom",...k(e)});return r._zod.ch...
  function kl (line 53) | function kl(t){let e=new se({check:"describe"});return e._zod.onattach=[...
  function Sl (line 53) | function Sl(t){let e=new se({check:"meta"});return e._zod.onattach=[r=>{...
  function wl (line 53) | function wl(t,e){let r=k(e),n=r.truthy??["true","1","yes","on","y","enab...
  function en (line 53) | function en(t,e,r,n={}){let o=k(n),i={...k(n),check:"string_format",type...
  function aa (line 53) | function aa(t){let e=t?.target??"draft-2020-12";return e==="draft-4"&&(e...
  function pe (line 53) | function pe(t,e,r={path:[],schemaPath:[]}){var n;let o=t._zod.def,i=e.se...
  function sa (line 53) | function sa(t,e){let r=t.seen.get(e);if(!r)throw new Error("Unprocessed ...
  function ca (line 55) | function ca(t,e){let r=t.seen.get(e);if(!r)throw new Error("Unprocessed ...
  function Ce (line 55) | function Ce(t,e){let r=e??{seen:new Set};if(r.seen.has(t))return!1;r.see...
  function tn (line 55) | function tn(t){return!!t._zod}
  function rr (line 55) | function rr(t,e){return tn(t)?Br(t,e):t.safeParse(e)}
  function ua (line 55) | function ua(t){if(!t)return;let e;if(tn(t)?e=t._zod?.def?.shape:e=t.shap...
  function Uh (line 55) | function Uh(t){if(tn(t)){let i=t._zod?.def;if(i){if(i.value!==void 0)ret...
  function Pl (line 55) | function Pl(t){return Ju(Tl,t)}
  function jl (line 55) | function jl(t){return Wu(Ol,t)}
  function Nl (line 55) | function Nl(t){return Ku(Dl,t)}
  function Al (line 55) | function Al(t){return Hu(Rl,t)}
  method get (line 55) | get(){return t.issues.length===0}
  method get (line 55) | get(){return Ae.get(t)?.description}
  function v (line 55) | function v(t){return Fu(ma,t)}
  function fx (line 55) | function fx(t){return Ui(Ul,t)}
  function mx (line 55) | function mx(t){return so(da,t)}
  function hx (line 55) | function hx(t){return Zi(Mt,t)}
  function gx (line 55) | function gx(t){return Li(Mt,t)}
  function vx (line 55) | function vx(t){return qi(Mt,t)}
  function _x (line 55) | function _x(t){return Fi(Mt,t)}
  function yx (line 55) | function yx(t){return co(ha,t)}
  function $x (line 55) | function $x(t){return co(ha,{protocol:/^https?$/,hostname:rt.domain,...$...
  function bx (line 55) | function bx(t){return Vi(Zl,t)}
  function xx (line 55) | function xx(t){return Ji(Ll,t)}
  function kx (line 55) | function kx(t){return Wi(ql,t)}
  function Sx (line 55) | function Sx(t){return Ki(Fl,t)}
  function wx (line 55) | function wx(t){return Hi(Vl,t)}
  function zx (line 55) | function zx(t){return Gi(Jl,t)}
  function Ix (line 55) | function Ix(t){return Bi(Wl,t)}
  function Ex (line 55) | function Ex(t){return Xi(Kl,t)}
  function Tx (line 55) | function Tx(t){return Vu(Qh,t)}
  function Px (line 55) | function Px(t){return Yi(Hl,t)}
  function Ox (line 55) | function Ox(t){return Qi(Gl,t)}
  function jx (line 55) | function jx(t){return ea(Bl,t)}
  function Dx (line 55) | function Dx(t){return ta(Xl,t)}
  function Nx (line 55) | function Nx(t){return ra(Yl,t)}
  function Rx (line 55) | function Rx(t){return na(Ql,t)}
  function Ax (line 55) | function Ax(t){return oa(ed,t)}
  function Mx (line 55) | function Mx(t,e,r={}){return en(So,t,e,r)}
  function Cx (line 55) | function Cx(t){return en(So,"hostname",rt.hostname,t)}
  function Ux (line 55) | function Ux(t){return en(So,"hex",rt.hex,t)}
  function Zx (line 55) | function Zx(t,e){let r=e?.enc??"hex",n=`${t}_${r}`,o=rt[n];if(!o)throw n...
  function ne (line 55) | function ne(t){return Gu(ga,t)}
  function Ml (line 55) | function Ml(t){return Bu(rn,t)}
  function Lx (line 55) | function Lx(t){return Xu(rn,t)}
  function qx (line 55) | function qx(t){return Yu(rn,t)}
  function Fx (line 55) | function Fx(t){return Qu(rn,t)}
  function Vx (line 55) | function Vx(t){return el(rn,t)}
  function ye (line 55) | function ye(t){return tl(va,t)}
  function Jx (line 55) | function Jx(t){return rl(_a,t)}
  function Wx (line 55) | function Wx(t){return nl(td,t)}
  function Kx (line 55) | function Kx(t){return ol(td,t)}
  function Hx (line 55) | function Hx(t){return il(eg,t)}
  function Gx (line 55) | function Gx(t){return al(tg,t)}
  function wo (line 55) | function wo(t){return sl(rg,t)}
  function Bx (line 55) | function Bx(){return cl(ng)}
  function ue (line 55) | function ue(){return ul(og)}
  function rd (line 55) | function rd(t){return ll(ig,t)}
  function Xx (line 55) | function Xx(t){return dl(ag,t)}
  function Yx (line 55) | function Yx(t){return pl(nd,t)}
  function G (line 55) | function G(t,e){return Xm(sg,t,e)}
  function Qx (line 55) | function Qx(t){let e=t._zod.def.shape;return Pe(Object.keys(e))}
  function z (line 55) | function z(t,e){let r={type:"object",shape:t??{},...$.normalizeParams(e)...
  function ek (line 55) | function ek(t,e){return new ya({type:"object",shape:t,catchall:rd(),...$...
  function Te (line 55) | function Te(t,e){return new ya({type:"object",shape:t,catchall:ue(),...$...
  function ie (line 55) | function ie(t,e){return new $a({type:"union",options:t,...$.normalizePar...
  function tk (line 55) | function tk(t,e){return new cg({type:"union",options:t,inclusive:!1,...$...
  function ba (line 55) | function ba(t,e,r){return new ug({type:"union",options:e,discriminator:t...
  function zo (line 55) | function zo(t,e){return new lg({type:"intersection",left:t,right:e})}
  function pg (line 55) | function pg(t,e,r){let n=e instanceof Z,o=n?r:e,i=n?e:null;return new dg...
  function fe (line 55) | function fe(t,e,r){return new xa({type:"record",keyType:t,valueType:e,.....
  function rk (line 55) | function rk(t,e,r){let n=Re(t);return n._zod.values=void 0,new xa({type:...
  function nk (line 55) | function nk(t,e,r){return new xa({type:"record",keyType:t,valueType:e,mo...
  function ok (line 55) | function ok(t,e,r){return new fg({type:"map",keyType:t,valueType:e,...$....
  function ik (line 55) | function ik(t,e){return new mg({type:"set",valueType:t,...$.normalizePar...
  function Pe (line 55) | function Pe(t,e){let r=Array.isArray(t)?Object.fromEntries(t.map(n=>[n,n...
  function ak (line 55) | function ak(t,e){return new ko({type:"enum",entries:t,...$.normalizePara...
  method get (line 55) | get(){if(e.values.length>1)throw new Error("This schema contains multipl...
  function P (line 55) | function P(t,e){return new hg({type:"literal",values:Array.isArray(t)?t:...
  function sk (line 55) | function sk(t){return yl(gg,t)}
  function od (line 55) | function od(t){return new vg({type:"transform",transform:t})}
  function me (line 55) | function me(t){return new id({type:"optional",innerType:t})}
  function yg (line 55) | function yg(t){return new _g({type:"optional",innerType:t})}
  function pa (line 55) | function pa(t){return new $g({type:"nullable",innerType:t})}
  function ck (line 55) | function ck(t){return me(pa(t))}
  function xg (line 55) | function xg(t,e){return new bg({type:"default",innerType:t,get defaultVa...
  function Sg (line 55) | function Sg(t,e){return new kg({type:"prefault",innerType:t,get defaultV...
  function wg (line 55) | function wg(t,e){return new ad({type:"nonoptional",innerType:t,...$.norm...
  function uk (line 55) | function uk(t){return new zg({type:"success",innerType:t})}
  function Eg (line 55) | function Eg(t,e){return new Ig({type:"catch",innerType:t,catchValue:type...
  function lk (line 55) | function lk(t){return fl(Tg,t)}
  function fa (line 55) | function fa(t,e){return new sd({type:"pipe",in:t,out:e})}
  function dk (line 55) | function dk(t,e,r){return new cd({type:"pipe",in:t,out:e,transform:r.dec...
  function Og (line 55) | function Og(t){return new Pg({type:"readonly",innerType:t})}
  function pk (line 55) | function pk(t,e){return new jg({type:"template_literal",parts:t,...$.nor...
  function Ng (line 55) | function Ng(t){return new Dg({type:"lazy",getter:t})}
  function fk (line 55) | function fk(t){return new Rg({type:"promise",innerType:t})}
  function mk (line 55) | function mk(t){return new Ag({type:"function",input:Array.isArray(t?.inp...
  function hk (line 55) | function hk(t){let e=new se({check:"custom"});return e._zod.check=t,e}
  function ud (line 55) | function ud(t,e){return $l(ka,t??(()=>!0),e)}
  function Mg (line 55) | function Mg(t,e={}){return bl(ka,t,e)}
  function Cg (line 55) | function Cg(t){return xl(t)}
  function _k (line 55) | function _k(t,e={}){let r=new ka({type:"custom",check:"custom",fn:n=>n i...
  function $k (line 55) | function $k(t){let e=Ng(()=>ie([v(t),ne(),ye(),wo(),G(e),fe(v(),e)]));re...
  function Sa (line 55) | function Sa(t,e){return fa(od(t),e)}
  method constructor (line 55) | constructor(e,r,n){super(`MCP error ${e}: ${r}`),this.code=e,this.data=n...
  method fromError (line 55) | static fromError(e,r,n){if(e===Y.UrlElicitationRequired&&n){let o=n;if(o...
  method constructor (line 55) | constructor(e,r=`URL elicitation${e.length>1?"s":""} required`){super(Y....
  method elicitations (line 55) | get elicitations(){return this.data?.elicitations??[]}
  function or (line 55) | function or(t){return t==="completed"||t==="failed"||t==="cancelled"}
  function Ed (line 55) | function Ed(t){let r=ua(t)?.method;if(!r)throw new Error("Schema is miss...
  function Td (line 55) | function Td(t,e){let r=rr(t,e);if(!r.success)throw r.error;return r.data}
  method constructor (line 55) | constructor(e){this._options=e,this._requestMessageId=0,this._requestHan...
  method _oncancel (line 55) | async _oncancel(e){if(!e.params.requestId)return;this._requestHandlerAbo...
  method _setupTimeout (line 55) | _setupTimeout(e,r,n,o,i=!1){this._timeoutInfo.set(e,{timeoutId:setTimeou...
  method _resetTimeout (line 55) | _resetTimeout(e){let r=this._timeoutInfo.get(e);if(!r)return!1;let n=Dat...
  method _cleanupTimeout (line 55) | _cleanupTimeout(e){let r=this._timeoutInfo.get(e);r&&(clearTimeout(r.tim...
  method connect (line 55) | async connect(e){if(this._transport)throw new Error("Already connected t...
  method _onclose (line 55) | _onclose(){let e=this._responseHandlers;this._responseHandlers=new Map,t...
  method _onerror (line 55) | _onerror(e){this.onerror?.(e)}
  method _onnotification (line 55) | _onnotification(e){let r=this._notificationHandlers.get(e.method)??this....
  method _onrequest (line 55) | _onrequest(e,r){let n=this._requestHandlers.get(e.method)??this.fallback...
  method _onprogress (line 55) | _onprogress(e){let{progressToken:r,...n}=e.params,o=Number(r),i=this._pr...
  method _onresponse (line 55) | _onresponse(e){let r=Number(e.id),n=this._requestResolvers.get(r);if(n){...
  method transport (line 55) | get transport(){return this._transport}
  method close (line 55) | async close(){await this._transport?.close()}
  method requestStream (line 55) | async*requestStream(e,r,n){let{task:o}=n??{};if(!o){try{yield{type:"resu...
  method request (line 55) | request(e,r,n){let{relatedRequestId:o,resumptionToken:i,onresumptiontoke...
  method getTask (line 55) | async getTask(e,r){return this.request({method:"tasks/get",params:e},Da,r)}
  method getTaskResult (line 55) | async getTaskResult(e,r,n){return this.request({method:"tasks/result",pa...
  method listTasks (line 55) | async listTasks(e,r){return this.request({method:"tasks/list",params:e},...
  method cancelTask (line 55) | async cancelTask(e,r){return this.request({method:"tasks/cancel",params:...
  method notification (line 55) | async notification(e,r){if(!this._transport)throw new Error("Not connect...
  method setRequestHandler (line 55) | setRequestHandler(e,r){let n=Ed(e);this.assertRequestHandlerCapability(n...
  method removeRequestHandler (line 55) | removeRequestHandler(e){this._requestHandlers.delete(e)}
  method assertCanSetRequestHandler (line 55) | assertCanSetRequestHandler(e){if(this._requestHandlers.has(e))throw new ...
  method setNotificationHandler (line 55) | setNotificationHandler(e,r){let n=Ed(e);this._notificationHandlers.set(n...
  method removeNotificationHandler (line 55) | removeNotificationHandler(e){this._notificationHandlers.delete(e)}
  method _cleanupTaskProgressHandler (line 55) | _cleanupTaskProgressHandler(e){let r=this._taskProgressTokens.get(e);r!=...
  method _enqueueTaskMessage (line 55) | async _enqueueTaskMessage(e,r,n){if(!this._taskStore||!this._taskMessage...
  method _clearTaskQueue (line 55) | async _clearTaskQueue(e,r){if(this._taskMessageQueue){let n=await this._...
  method _waitForTaskUpdate (line 55) | async _waitForTaskUpdate(e,r){let n=this._options?.defaultTaskPollInterv...
  method requestTaskStore (line 55) | requestTaskStore(e,r){let n=this._taskStore;if(!n)throw new Error("No ta...
  function rv (line 55) | function rv(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}
  function nv (line 55) | function nv(t,e){let r={...t};for(let n in e){let o=n,i=e[o];if(i===void...
  function YT (line 55) | function YT(){let t=new Fy.default({strict:!1,validateFormats:!0,validat...
  method constructor (line 55) | constructor(e){this._ajv=e??YT()}
  method getValidator (line 55) | getValidator(e){let r="$id"in e&&typeof e.$id=="string"?this._ajv.getSch...
  method constructor (line 55) | constructor(e){this._server=e}
  method requestStream (line 55) | requestStream(e,r,n){return this._server.requestStream(e,r,n)}
  method createMessageStream (line 55) | createMessageStream(e,r){let n=this._server.getClientCapabilities();if((...
  method elicitInputStream (line 55) | elicitInputStream(e,r){let n=this._server.getClientCapabilities(),o=e.mo...
  method getTask (line 55) | async getTask(e,r){return this._server.getTask({taskId:e},r)}
  method getTaskResult (line 55) | async getTaskResult(e,r,n){return this._server.getTaskResult({taskId:e},...
  method listTasks (line 55) | async listTasks(e,r){return this._server.listTasks(e?{cursor:e}:void 0,r)}
  method cancelTask (line 55) | async cancelTask(e,r){return this._server.cancelTask({taskId:e},r)}
  function Jy (line 55) | function Jy(t,e,r){if(!t)throw new Error(`${r} does not support task cre...
  function Wy (line 55) | function Wy(t,e,r){if(!t)throw new Error(`${r} does not support task cre...
  method constructor (line 55) | constructor(e,r){super(r),this._serverInfo=e,this._loggingLevels=new Map...
  method experimental (line 55) | get experimental(){return this._experimental||(this._experimental={tasks...
  method registerCapabilities (line 55) | registerCapabilities(e){if(this.transport)throw new Error("Cannot regist...
  method setRequestHandler (line 55) | setRequestHandler(e,r){let o=ua(e)?.method;if(!o)throw new Error("Schema...
  method assertCapabilityForMethod (line 55) | assertCapabilityForMethod(e){switch(e){case"sampling/createMessage":if(!...
  method assertNotificationCapability (line 55) | assertNotificationCapability(e){switch(e){case"notifications/message":if...
  method assertRequestHandlerCapability (line 55) | assertRequestHandlerCapability(e){if(this._capabilities)switch(e){case"c...
  method assertTaskCapability (line 55) | assertTaskCapability(e){Wy(this._clientCapabilities?.tasks?.requests,e,"...
  method assertTaskHandlerCapability (line 55) | assertTaskHandlerCapability(e){this._capabilities&&Jy(this._capabilities...
  method _oninitialize (line 55) | async _oninitialize(e){let r=e.params.protocolVersion;return this._clien...
  method getClientCapabilities (line 55) | getClientCapabilities(){return this._clientCapabilities}
  method getClientVersion (line 55) | getClientVersion(){return this._clientVersion}
  method getCapabilities (line 55) | getCapabilities(){return this._capabilities}
  method ping (line 55) | async ping(){return this.request({method:"ping"},Ea)}
  method createMessage (line 55) | async createMessage(e,r){if((e.tools||e.toolChoice)&&!this._clientCapabi...
  method elicitInput (line 55) | async elicitInput(e,r){switch(e.mode??"form"){case"url":{if(!this._clien...
  method createElicitationCompletionNotifier (line 55) | createElicitationCompletionNotifier(e,r){if(!this._clientCapabilities?.e...
  method listRoots (line 55) | async listRoots(e,r){return this.request({method:"roots/list",params:e},...
  method sendLoggingMessage (line 55) | async sendLoggingMessage(e,r){if(this._capabilities.logging&&!this.isMes...
  method sendResourceUpdated (line 55) | async sendResourceUpdated(e){return this.notification({method:"notificat...
  method sendResourceListChanged (line 55) | async sendResourceListChanged(){return this.notification({method:"notifi...
  method sendToolListChanged (line 55) | async sendToolListChanged(){return this.notification({method:"notificati...
  method sendPromptListChanged (line 55) | async sendPromptListChanged(){return this.notification({method:"notifica...
  method append (line 55) | append(e){this._buffer=this._buffer?Buffer.concat([this._buffer,e]):e}
  method readMessage (line 55) | readMessage(){if(!this._buffer)return null;let e=this._buffer.indexOf(`
  method clear (line 56) | clear(){this._buffer=void 0}
  function QT (line 56) | function QT(t){return Hg.parse(JSON.parse(t))}
  function Ky (line 56) | function Ky(t){return JSON.stringify(t)+`
  method constructor (line 57) | constructor(e=kf.default.stdin,r=kf.default.stdout){this._stdin=e,this._...
  method start (line 57) | async start(){if(this._started)throw new Error("StdioServerTransport alr...
  method processReadBuffer (line 57) | processReadBuffer(){for(;;)try{let e=this._readBuffer.readMessage();if(e...
  method close (line 57) | async close(){this._stdin.off("data",this._ondata),this._stdin.off("erro...
  method send (line 57) | send(e){return new Promise(r=>{let n=Ky(e);this._stdout.write(n)?r():thi...
  function Hy (line 57) | function Hy(t){return process.platform==="win32"?Math.round(t*Sf.WINDOWS...
  method getAllDefaults (line 57) | static getAllDefaults(){return{...this.DEFAULTS}}
  method get (line 57) | static get(e){return process.env[e]??this.DEFAULTS[e]}
  method getInt (line 57) | static getInt(e){let r=this.get(e);return parseInt(r,10)}
  method getBool (line 57) | static getBool(e){let r=this.get(e);return r==="true"||r===!0}
  method applyEnvOverrides (line 57) | static applyEnvOverrides(e){let r={...e};for(let n of Object.keys(this.D...
  method loadFromFile (line 57) | static loadFromFile(e){try{if(!(0,zt.existsSync)(e)){let a=this.getAllDe...
  function eP (line 57) | function eP(){return typeof __dirname<"u"?__dirname:(0,$e.dirname)((0,By...
  function tP (line 57) | function tP(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAU...
  function iP (line 57) | function iP(t,e={},r){return new Promise((n,o)=>{let i=setTimeout(()=>o(...
  function aP (line 57) | function aP(){if(Es!==null)return Es;let t=If.default.join(jr.get("CLAUD...
  function sP (line 57) | function sP(){if(Ts!==null)return Ts;let t=If.default.join(jr.get("CLAUD...
  function cP (line 57) | function cP(t){return`http://${sP()}:${aP()}${t}`}
  function Ps (line 57) | function Ps(t,e={}){let r=e.method??"GET",n=e.timeoutMs??oP,o=cP(t),i={m...
  function e$ (line 57) | function e$(t){let e=t.slice(t.lastIndexOf("."));return uP[e]||"unknown"}
  function t$ (line 57) | function t$(t){let e=lP[t];if(!e)return null;try{let r=Qy.resolve(e+"/pa...
  function r$ (line 102) | function r$(t){switch(t){case"javascript":case"typescript":case"tsx":ret...
  function n$ (line 102) | function n$(t){if(Tf.has(t))return Tf.get(t);Ef||(Ef=(0,It.mkdtempSync)(...
  function pP (line 102) | function pP(){if(mi)return mi;try{let t=Qy.resolve("tree-sitter-cli/pack...
  function fP (line 102) | function fP(t,e,r){return o$(t,[e],r).get(e)||[]}
  function o$ (line 102) | function o$(t,e,r){if(e.length===0)return new Map;let n=pP(),o=["query",...
  function mP (line 102) | function mP(t){let e=new Map,r=null,n=null;for(let o of t.split(`
  function gP (line 103) | function gP(t,e,r,n=200){let i=t[e]||"";if(!i.trimEnd().endsWith("{")&&!...
  function vP (line 104) | function vP(t,e){let r=[],n=!1;for(let o=e-1;o>=0;o--){let i=t[o].trim()...
  function _P (line 105) | function _P(t,e,r){for(let n=e+1;n<=Math.min(e+3,r);n++){let o=t[n]?.tri...
  function yP (line 105) | function yP(t,e,r,n,o,i){switch(i){case"javascript":case"typescript":cas...
  function i$ (line 105) | function i$(t,e,r){let n=[],o=[],i=[],a=[];for(let c of t)for(let u of c...
  function Os (line 105) | function Os(t,e){let r=e$(e),n=t.split(`
  function a$ (line 106) | function a$(t){let e=new Map,r=new Map;for(let n of t){let o=e$(n.relati...
  function wn (line 108) | function wn(t){let e=[];if(e.push(`\u{1F4C1} ${t.filePath} (${t.language...
  function s$ (line 109) | function s$(t,e){let r=[],n=$P(t.kind),o=t.exported?" [exported]":"",i=t...
  function $P (line 111) | function $P(t){return{function:"\u0192",method:"\u0192",class:"\u25C6",i...
  function c$ (line 111) | function c$(t,e,r){let n=Os(t,e),o=u=>{for(let l of u){if(l.name===r)ret...
  function wP (line 114) | async function wP(t){try{let e=await(0,zn.stat)(t);if(e.size>SP||e.size=...
  function l$ (line 114) | async function l$(t,e,r={}){let n=r.maxResults||20,o=e.toLowerCase(),i=o...
  function js (line 114) | function js(t,e){let r=0;for(let n of e)if(t===n)r+=10;else if(t.include...
  function zP (line 114) | function zP(t){let e=t.symbols.length;for(let r of t.symbols)r.children&...
  function d$ (line 114) | function d$(t,e){let r=[];if(r.push(`\u{1F50D} Smart Search: "${e}"`),r....
  function f$ (line 117) | async function f$(t,e){ve.debug("SYSTEM","\u2192 Worker API",void 0,{end...
  function EP (line 117) | async function EP(t,e){ve.debug("HTTP","Worker API request (POST)",void ...
  function TP (line 117) | async function TP(){try{return(await Ps("/api/health")).ok}catch(t){retu...
  function OP (line 141) | function OP(){if(process.platform==="win32")return;let t=process.ppid;gi...
  function Nf (line 141) | function Nf(){gi&&clearInterval(gi),ve.info("SYSTEM","MCP server shuttin...
  function jP (line 141) | async function jP(){let t=new ws;await Df.connect(t),ve.info("SYSTEM","C...

FILE: plugin/scripts/smart-install.js
  function isPluginDisabledInClaudeSettings (line 19) | function isPluginDisabledInClaudeSettings() {
  constant IS_WINDOWS (line 34) | const IS_WINDOWS = process.platform === 'win32';
  function resolveRoot (line 46) | function resolveRoot() {
  constant ROOT (line 70) | const ROOT = resolveRoot();
  constant MARKER (line 71) | const MARKER = join(ROOT, '.install-version');
  function isBunInstalled (line 76) | function isBunInstalled() {
  function getBunPath (line 99) | function getBunPath() {
  constant MIN_BUN_VERSION (line 128) | const MIN_BUN_VERSION = '1.1.14';
  function compareVersions (line 133) | function compareVersions(v1, v2) {
  function isBunVersionSufficient (line 148) | function isBunVersionSufficient() {
  function getBunVersion (line 157) | function getBunVersion() {
  function isUvInstalled (line 176) | function isUvInstalled() {
  function getUvVersion (line 199) | function getUvVersion() {
  function installBun (line 215) | function installBun() {
  function installUv (line 280) | function installUv() {
  function installCLI (line 345) | function installCLI() {
  function needsInstall (line 400) | function needsInstall() {
  function installDeps (line 418) | function installDeps() {
  function verifyCriticalModules (line 472) | function verifyCriticalModules() {

FILE: plugin/scripts/worker-cli.js
  method constructor (line 2) | constructor(){this.useColor=process.stdout.isTTY??!1}
  method getLevel (line 2) | getLevel(){if(this.level===null){let t=l.get("CLAUDE_MEM_LOG_LEVEL").toU...
  method correlationId (line 2) | correlationId(t,e){return`obs-${t}-${e}`}
  method sessionId (line 2) | sessionId(t){return`session-${t}`}
  method formatData (line 2) | formatData(t){if(t==null)return"";if(typeof t=="string")return t;if(type...
  method formatTool (line 3) | formatTool(t,e){if(!e)return t;let r=typeof e=="string"?JSON.parse(e):e;...
  method formatTimestamp (line 3) | formatTimestamp(t){let e=t.getFullYear(),r=String(t.getMonth()+1).padSta...
  method log (line 3) | log(t,e,r,n,s){if(t<this.getLevel())return;let o=this.formatTimestamp(ne...
  method debug (line 4) | debug(t,e,r,n){this.log(0,t,e,r,n)}
  method info (line 4) | info(t,e,r,n){this.log(1,t,e,r,n)}
  method warn (line 4) | warn(t,e,r,n){this.log(2,t,e,r,n)}
  method error (line 4) | error(t,e,r,n){this.log(3,t,e,r,n)}
  method dataIn (line 4) | dataIn(t,e,r,n){this.info(t,`\u2192 ${e}`,r,n)}
  method dataOut (line 4) | dataOut(t,e,r,n){this.info(t,`\u2190 ${e}`,r,n)}
  method success (line 4) | success(t,e,r,n){this.info(t,`\u2713 ${e}`,r,n)}
  method failure (line 4) | failure(t,e,r,n){this.error(t,`\u2717 ${e}`,r,n)}
  method timing (line 4) | timing(t,e,r,n){this.info(t,`\u23F1 ${e}`,n,{duration:`${r}ms`})}
  method happyPathError (line 4) | happyPathError(t,e,r,n,s=""){let p=((new Error().stack||"").split(`
  method getAllDefaults (line 5) | static getAllDefaults(){return{...this.DEFAULTS}}
  method get (line 5) | static get(t){return this.DEFAULTS[t]}
  method getInt (line 5) | static getInt(t){let e=this.get(t);return parseInt(e,10)}
  method getBool (line 5) | static getBool(t){return this.get(t)==="true"}
  method loadFromFile (line 5) | static loadFromFile(t){try{if(!X(t))return this.getAllDefaults();let e=V...
  function Z (line 5) | function Z(){return typeof __dirname<"u"?__dirname:q(Q(import.meta.url))}
  function R (line 5) | function R(){let i=process.platform==="win32";try{if(tt("bun",["--versio...
  function N (line 5) | function N(){return R()!==null}
  method start (line 5) | static async start(t){if(isNaN(t)||t<1024||t>65535)return{success:!1,err...
  method isBunAvailable (line 5) | static isBunAvailable(){return N()}
  method escapePowerShellString (line 5) | static escapePowerShellString(t){return t.replace(/'/g,"''")}
  method startWithBun (line 5) | static async startWithBun(t,e,r){let n=R();if(!n)return{success:!1,error...
  method stop (line 5) | static async stop(t=5e3){let e=this.getPidInfo();if(process.platform==="...
  method restart (line 5) | static async restart(t){return await this.stop(),this.start(t)}
  method status (line 5) | static async status(){let t=this.getPidInfo();if(!t)return{running:!1};l...
  method isRunning (line 5) | static async isRunning(){let t=this.getPidInfo();if(!t)return!1;let e=th...
  method getPortFromSettings (line 5) | static getPortFromSettings(){try{let t=S(u,"settings.json"),e=l.loadFrom...
  method tryHttpShutdown (line 5) | static async tryHttpShutdown(t){try{return(await fetch(`http://127.0.0.1...
  method waitForWorkerDown (line 5) | static async waitForWorkerDown(t,e){let r=Date.now();for(;Date.now()-r<e...
  method getPidInfo (line 5) | static getPidInfo(){try{if(!w(d))return null;let t=rt(d,"utf-8"),e=JSON....
  method writePidFile (line 5) | static writePidFile(t){$(u,{recursive:!0}),nt(d,JSON.stringify(t,null,2))}
  method removePidFile (line 5) | static removePidFile(){try{w(d)&&st(d)}catch{}}
  method isProcessAlive (line 5) | static isProcessAlive(t){try{return process.kill(t,0),!0}catch{return!1}}
  method waitForHealth (line 5) | static async waitForHealth(t,e,r=1e4){let n=Date.now(),s=process.platfor...
  method waitForExit (line 19) | static async waitForExit(t,e){let r=Date.now();for(;Date.now()-r<e;){if(...
  method getLogFilePath (line 19) | static getLogFilePath(){let t=new Date().toISOString().slice(0,10);retur...
  method formatUptime (line 19) | static formatUptime(t){let e=new Date(t).getTime(),n=Date.now()-e,s=Math...
  function W (line 19) | function W(i){return process.platform==="win32"?Math.round(i*I.WINDOWS_M...
  function H (line 19) | function H(){if(M!==null)return M;let i=F.join(l.get("CLAUDE_MEM_DATA_DI...
  function pt (line 19) | async function pt(){switch(Et){case"start":{let i=await g.start(G);if(i....

FILE: plugin/scripts/worker-service.cjs
  method constructor (line 4) | constructor(e){if(super(),!it.IDENTIFIER.test(e))throw new Error("CodeGe...
  method toString (line 4) | toString(){return this.str}
  method emptyStr (line 4) | emptyStr(){return!1}
  method names (line 4) | get names(){return{[this.str]:1}}
  method constructor (line 4) | constructor(e){super(),this._items=typeof e=="string"?[e]:e}
  method toString (line 4) | toString(){return this.str}
  method emptyStr (line 4) | emptyStr(){if(this._items.length>1)return!1;let e=this._items[0];return ...
  method str (line 4) | get str(){var e;return(e=this._str)!==null&&e!==void 0?e:this._str=this....
  method names (line 4) | get names(){var e;return(e=this._names)!==null&&e!==void 0?e:this._names...
  function mR (line 4) | function mR(t,...e){let r=[t[0]],n=0;for(;n<e.length;)Ex(r,e[n]),r.push(...
  function fR (line 4) | function fR(t,...e){let r=[pl(t[0])],n=0;for(;n<e.length;)r.push(wx),Ex(...
  function Ex (line 4) | function Ex(t,e){e instanceof In?t.push(...e._items):e instanceof so?t.p...
  function I3 (line 4) | function I3(t){let e=1;for(;e<t.length-1;){if(t[e]===wx){let r=R3(t[e-1]...
  function R3 (line 4) | function R3(t,e){if(e==='""')return t;if(t==='""')return e;if(typeof t==...
  function O3 (line 4) | function O3(t,e){return e.emptyStr()?t:t.emptyStr()?e:fR`${t}${e}`}
  function P3 (line 4) | function P3(t){return typeof t=="number"||typeof t=="boolean"||t===null?...
  function C3 (line 4) | function C3(t){return new In(pl(t))}
  function pl (line 4) | function pl(t){return JSON.stringify(t).replace(/\u2028/g,"\\u2028").rep...
  function A3 (line 4) | function A3(t){return typeof t=="string"&&it.IDENTIFIER.test(t)?new In(`...
  function N3 (line 4) | function N3(t){if(typeof t=="string"&&it.IDENTIFIER.test(t))return new I...
  function M3 (line 4) | function M3(t){return new In(t.toString())}
  method constructor (line 4) | constructor(e){super(`CodeGen: "code" for ${e} not defined`),this.value=...
  method constructor (line 4) | constructor({prefixes:e,parent:r}={}){this._names={},this._prefixes=e,th...
  method toName (line 4) | toName(e){return e instanceof Kr.Name?e:this.name(e)}
  method name (line 4) | name(e){return new Kr.Name(this._newName(e))}
  method _newName (line 4) | _newName(e){let r=this._names[e]||this._nameGroup(e);return`${e}${r.inde...
  method _nameGroup (line 4) | _nameGroup(e){var r,n;if(!((n=(r=this._parent)===null||r===void 0?void 0...
  method constructor (line 4) | constructor(e,r){super(r),this.prefix=e}
  method setValue (line 4) | setValue(e,{property:r,itemIndex:n}){this.value=e,this.scopePath=(0,Kr._...
  method constructor (line 4) | constructor(e){super(e),this._values={},this._scope=e.scope,this.opts={....
  method get (line 4) | get(){return this._scope}
  method name (line 4) | name(e){return new Vm(e,this._newName(e))}
  method value (line 4) | value(e,r){var n;if(r.ref===void 0)throw new Error("CodeGen: ref must be...
  method getValue (line 4) | getValue(e,r){let n=this._values[e];if(n)return n.get(r)}
  method scopeRefs (line 4) | scopeRefs(e,r=this._values){return this._reduceValues(r,n=>{if(n.scopePa...
  method scopeCode (line 4) | scopeCode(e=this._values,r,n){return this._reduceValues(e,i=>{if(i.value...
  method _reduceValues (line 4) | _reduceValues(e,r,n={},i){let s=Kr.nil;for(let o in e){let a=e[o];if(!a)...
  method optimizeNodes (line 4) | optimizeNodes(){return this}
  method optimizeNames (line 4) | optimizeNames(e,r){return this}
  method constructor (line 4) | constructor(e,r,n){super(),this.varKind=e,this.name=r,this.rhs=n}
  method render (line 4) | render({es5:e,_n:r}){let n=e?Vn.varKinds.var:this.varKind,i=this.rhs===v...
  method optimizeNames (line 4) | optimizeNames(e,r){if(e[this.name.str])return this.rhs&&(this.rhs=$a(thi...
  method names (line 4) | get names(){return this.rhs instanceof et._CodeOrName?this.rhs.names:{}}
  method constructor (line 4) | constructor(e,r,n){super(),this.lhs=e,this.rhs=r,this.sideEffects=n}
  method render (line 4) | render({_n:e}){return`${this.lhs} = ${this.rhs};`+e}
  method optimizeNames (line 4) | optimizeNames(e,r){if(!(this.lhs instanceof et.Name&&!e[this.lhs.str]&&!...
  method names (line 4) | get names(){let e=this.lhs instanceof et.Name?{}:{...this.lhs.names};ret...
  method constructor (line 4) | constructor(e,r,n,i){super(e,n,i),this.op=r}
  method render (line 4) | render({_n:e}){return`${this.lhs} ${this.op}= ${this.rhs};`+e}
  method constructor (line 4) | constructor(e){super(),this.label=e,this.names={}}
  method render (line 4) | render({_n:e}){return`${this.label}:`+e}
  method constructor (line 4) | constructor(e){super(),this.label=e,this.names={}}
  method render (line 4) | render({_n:e}){return`break${this.label?` ${this.label}`:""};`+e}
  method constructor (line 4) | constructor(e){super(),this.error=e}
  method render (line 4) | render({_n:e}){return`throw ${this.error};`+e}
  method names (line 4) | get names(){return this.error.names}
  method constructor (line 4) | constructor(e){super(),this.code=e}
  method render (line 4) | render({_n:e}){return`${this.code};`+e}
  method optimizeNodes (line 4) | optimizeNodes(){return`${this.code}`?this:void 0}
  method optimizeNames (line 4) | optimizeNames(e,r){return this.code=$a(this.code,e,r),this}
  method names (line 4) | get names(){return this.code instanceof et._CodeOrName?this.code.names:{}}
  method constructor (line 4) | constructor(e=[]){super(),this.nodes=e}
  method render (line 4) | render(e){return this.nodes.reduce((r,n)=>r+n.render(e),"")}
  method optimizeNodes (line 4) | optimizeNodes(){let{nodes:e}=this,r=e.length;for(;r--;){let n=e[r].optim...
  method optimizeNames (line 4) | optimizeNames(e,r){let{nodes:n}=this,i=n.length;for(;i--;){let s=n[i];s....
  method names (line 4) | get names(){return this.nodes.reduce((e,r)=>co(e,r.names),{})}
  method render (line 4) | render(e){return"{"+e._n+super.render(e)+"}"+e._n}
  method constructor (line 4) | constructor(e,r){super(r),this.condition=e}
  method render (line 4) | render(e){let r=`if(${this.condition})`+super.render(e);return this.else...
  method optimizeNodes (line 4) | optimizeNodes(){super.optimizeNodes();let e=this.condition;if(e===!0)ret...
  method optimizeNames (line 4) | optimizeNames(e,r){var n;if(this.else=(n=this.else)===null||n===void 0?v...
  method names (line 4) | get names(){let e=super.names;return Km(e,this.condition),this.else&&co(...
  method constructor (line 4) | constructor(e){super(),this.iteration=e}
  method render (line 4) | render(e){return`for(${this.iteration})`+super.render(e)}
  method optimizeNames (line 4) | optimizeNames(e,r){if(super.optimizeNames(e,r))return this.iteration=$a(...
  method names (line 4) | get names(){return co(super.names,this.iteration.names)}
  method constructor (line 4) | constructor(e,r,n,i){super(),this.varKind=e,this.name=r,this.from=n,this...
  method render (line 4) | render(e){let r=e.es5?Vn.varKinds.var:this.varKind,{name:n,from:i,to:s}=...
  method names (line 4) | get names(){let e=Km(super.names,this.from);return Km(e,this.to)}
  method constructor (line 4) | constructor(e,r,n,i){super(),this.loop=e,this.varKind=r,this.name=n,this...
  method render (line 4) | render(e){return`for(${this.varKind} ${this.name} ${this.loop} ${this.it...
  method optimizeNames (line 4) | optimizeNames(e,r){if(super.optimizeNames(e,r))return this.iterable=$a(t...
  method names (line 4) | get names(){return co(super.names,this.iterable.names)}
  method constructor (line 4) | constructor(e,r,n){super(),this.name=e,this.args=r,this.async=n}
  method render (line 4) | render(e){return`${this.async?"async ":""}function ${this.name}(${this.a...
  method render (line 4) | render(e){return"return "+super.render(e)}
  method render (line 4) | render(e){let r="try"+super.render(e);return this.catch&&(r+=this.catch....
  method optimizeNodes (line 4) | optimizeNodes(){var e,r;return super.optimizeNodes(),(e=this.catch)===nu...
  method optimizeNames (line 4) | optimizeNames(e,r){var n,i;return super.optimizeNames(e,r),(n=this.catch...
  method names (line 4) | get names(){let e=super.names;return this.catch&&co(e,this.catch.names),...
  method constructor (line 4) | constructor(e){super(),this.error=e}
  method render (line 4) | render(e){return`catch(${this.error})`+super.render(e)}
  method render (line 4) | render(e){return"finally"+super.render(e)}
  method constructor (line 4) | constructor(e,r={}){this._values={},this._blockStarts=[],this._constants...
  method toString (line 5) | toString(){return this._root.render(this.opts)}
  method name (line 5) | name(e){return this._scope.name(e)}
  method scopeName (line 5) | scopeName(e){return this._extScope.name(e)}
  method scopeValue (line 5) | scopeValue(e,r){let n=this._extScope.value(e,r);return(this._values[n.pr...
  method getScopeValue (line 5) | getScopeValue(e,r){return this._extScope.getValue(e,r)}
  method scopeRefs (line 5) | scopeRefs(e){return this._extScope.scopeRefs(e,this._values)}
  method scopeCode (line 5) | scopeCode(){return this._extScope.scopeCode(this._values)}
  method _def (line 5) | _def(e,r,n,i){let s=this._scope.toName(r);return n!==void 0&&i&&(this._c...
  method const (line 5) | const(e,r,n){return this._def(Vn.varKinds.const,e,r,n)}
  method let (line 5) | let(e,r,n){return this._def(Vn.varKinds.let,e,r,n)}
  method var (line 5) | var(e,r,n){return this._def(Vn.varKinds.var,e,r,n)}
  method assign (line 5) | assign(e,r,n){return this._leafNode(new Gm(e,r,n))}
  method add (line 5) | add(e,r){return this._leafNode(new Rx(e,qe.operators.ADD,r))}
  method code (line 5) | code(e){return typeof e=="function"?e():e!==et.nil&&this._leafNode(new A...
  method object (line 5) | object(...e){let r=["{"];for(let[n,i]of e)r.length>1&&r.push(","),r.push...
  method if (line 5) | if(e,r,n){if(this._blockNode(new oo(e)),r&&n)this.code(r).else().code(n)...
  method elseIf (line 5) | elseIf(e){return this._elseNode(new oo(e))}
  method else (line 5) | else(){return this._elseNode(new ka)}
  method endIf (line 5) | endIf(){return this._endBlockNode(oo,ka)}
  method _for (line 5) | _for(e,r){return this._blockNode(e),r&&this.code(r).endFor(),this}
  method for (line 5) | for(e,r){return this._for(new Mx(e),r)}
  method forRange (line 5) | forRange(e,r,n,i,s=this.opts.es5?Vn.varKinds.var:Vn.varKinds.let){let o=...
  method forOf (line 5) | forOf(e,r,n,i=Vn.varKinds.const){let s=this._scope.toName(e);if(this.opt...
  method forIn (line 5) | forIn(e,r,n,i=this.opts.es5?Vn.varKinds.var:Vn.varKinds.const){if(this.o...
  method endFor (line 5) | endFor(){return this._endBlockNode(ao)}
  method label (line 5) | label(e){return this._leafNode(new Ox(e))}
  method break (line 5) | break(e){return this._leafNode(new Px(e))}
  method return (line 5) | return(e){let r=new gl;if(this._blockNode(r),this.code(e),r.nodes.length...
  method try (line 5) | try(e,r,n){if(!r&&!n)throw new Error('CodeGen: "try" without "catch" and...
  method throw (line 5) | throw(e){return this._leafNode(new Cx(e))}
  method block (line 5) | block(e,r){return this._blockStarts.push(this._nodes.length),e&&this.cod...
  method endBlock (line 5) | endBlock(e){let r=this._blockStarts.pop();if(r===void 0)throw new Error(...
  method func (line 5) | func(e,r=et.nil,n,i){return this._blockNode(new hl(e,r,n)),i&&this.code(...
  method endFunc (line 5) | endFunc(){return this._endBlockNode(hl)}
  method optimize (line 5) | optimize(e=1){for(;e-- >0;)this._root.optimizeNodes(),this._root.optimiz...
  method _leafNode (line 5) | _leafNode(e){return this._currNode.nodes.push(e),this}
  method _blockNode (line 5) | _blockNode(e){this._currNode.nodes.push(e),this._nodes.push(e)}
  method _endBlockNode (line 5) | _endBlockNode(e,r){let n=this._currNode;if(n instanceof e||r&&n instance...
  method _elseNode (line 5) | _elseNode(e){let r=this._currNode;if(!(r instanceof oo))throw new Error(...
  method _root (line 5) | get _root(){return this._nodes[0]}
  method _currNode (line 5) | get _currNode(){let e=this._nodes;return e[e.length-1]}
  method _currNode (line 5) | set _currNode(e){let r=this._nodes;r[r.length-1]=e}
  function co (line 5) | function co(t,e){for(let r in e)t[r]=(t[r]||0)+(e[r]||0);return t}
  function Km (line 5) | function Km(t,e){return e instanceof et._CodeOrName?co(t,e.names):t}
  function $a (line 5) | function $a(t,e,r){if(t instanceof et.Name)return n(t);if(!i(t))return t...
  function j3 (line 5) | function j3(t,e){for(let r in e)t[r]=(t[r]||0)-(e[r]||0)}
  function hR (line 5) | function hR(t){return typeof t=="boolean"||typeof t=="number"||t===null?...
  function L3 (line 5) | function L3(...t){return t.reduce(z3)}
  function q3 (line 5) | function q3(...t){return t.reduce(U3)}
  function gR (line 5) | function gR(t){return(e,r)=>e===et.nil?r:r===et.nil?e:(0,et._)`${Lx(e)} ...
  function Lx (line 5) | function Lx(t){return t instanceof et.Name?t:(0,et._)`(${t})`}
  function H3 (line 5) | function H3(t){let e={};for(let r of t)e[r]=!0;return e}
  function Z3 (line 5) | function Z3(t,e){return typeof e=="boolean"?e:Object.keys(e).length===0?...
  function _R (line 5) | function _R(t,e=t.schema){let{opts:r,self:n}=t;if(!r.strictSchema||typeo...
  function bR (line 5) | function bR(t,e){if(typeof t=="boolean")return!t;for(let r in t)if(e[r])...
  function B3 (line 5) | function B3(t,e){if(typeof t=="boolean")return!t;for(let r in t)if(r!=="...
  function V3 (line 5) | function V3({topSchemaRef:t,schemaPath:e},r,n,i){if(!i){if(typeof r=="nu...
  function G3 (line 5) | function G3(t){return xR(decodeURIComponent(t))}
  function W3 (line 5) | function W3(t){return encodeURIComponent(qx(t))}
  function qx (line 5) | function qx(t){return typeof t=="number"?`${t}`:t.replace(/~/g,"~0").rep...
  function xR (line 5) | function xR(t){return t.replace(/~1/g,"/").replace(/~0/g,"~")}
  function K3 (line 5) | function K3(t,e){if(Array.isArray(t))for(let r of t)e(r);else e(t)}
  function vR (line 5) | function vR({mergeNames:t,mergeToName:e,mergeValues:r,resultToName:n}){r...
  function SR (line 5) | function SR(t,e){if(e===!0)return t.var("props",!0);let r=t.var("props",...
  function Fx (line 5) | function Fx(t,e,r){Object.keys(r).forEach(n=>t.assign((0,St._)`${e}${(0,...
  function J3 (line 5) | function J3(t,e){return t.scopeValue("func",{ref:e,code:yR[e.code]||(yR[...
  function X3 (line 5) | function X3(t,e,r){if(t instanceof St.Name){let n=e===Ux.Num;return r?n?...
  function wR (line 5) | function wR(t,e,r=t.opts.strictSchema){if(r){if(e=`strict mode: ${e}`,r=...
  function Q3 (line 5) | function Q3(t,e=$r.keywordError,r,n){let{it:i}=t,{gen:s,compositeRule:o,...
  function eZ (line 5) | function eZ(t,e=$r.keywordError,r){let{it:n}=t,{gen:i,compositeRule:s,al...
  function tZ (line 5) | function tZ(t,e){t.assign(zr.default.errors,e),t.if((0,rt._)`${zr.defaul...
  function rZ (line 5) | function rZ({gen:t,keyword:e,schemaValue:r,data:n,errsCount:i,it:s}){if(...
  function ER (line 5) | function ER(t,e){let r=t.const("err",e);t.if((0,rt._)`${zr.default.vErro...
  function kR (line 5) | function kR(t,e){let{gen:r,validateName:n,schemaEnv:i}=t;i.$async?r.thro...
  function $R (line 5) | function $R(t,e,r){let{createErrors:n}=t.it;return n===!1?(0,rt._)`{}`:n...
  function nZ (line 5) | function nZ(t,e,r={}){let{gen:n,it:i}=t,s=[iZ(i,r),sZ(t,r)];return oZ(t,...
  function iZ (line 5) | function iZ({errorPath:t},{instancePath:e}){let r=e?(0,rt.str)`${t}${(0,...
  function sZ (line 5) | function sZ({keyword:t,it:{errSchemaPath:e}},{schemaPath:r,parentSchema:...
  function oZ (line 5) | function oZ(t,{params:e,message:r},n){let{keyword:i,data:s,schemaValue:o...
  function dZ (line 5) | function dZ(t){let{gen:e,schema:r,validateName:n}=t;r===!1?TR(t,!1):type...
  function pZ (line 5) | function pZ(t,e){let{gen:r,schema:n}=t;n===!1?(r.var(e,!1),TR(t)):r.var(...
  function TR (line 5) | function TR(t,e){let{gen:r,data:n}=t,i={gen:r,keyword:"false schema",dat...
  function hZ (line 5) | function hZ(t){return typeof t=="string"&&fZ.has(t)}
  function gZ (line 5) | function gZ(){let t={number:{type:"number",rules:[]},string:{type:"strin...
  function vZ (line 5) | function vZ({schema:t,self:e},r){let n=e.RULES.types[r];return n&&n!==!0...
  function RR (line 5) | function RR(t,e){return e.rules.some(r=>OR(t,r))}
  function OR (line 5) | function OR(t,e){var r;return t[e.keyword]!==void 0||((r=e.definition.im...
  function xZ (line 5) | function xZ(t){let e=CR(t.type);if(e.includes("null")){if(t.nullable===!...
  function CR (line 5) | function CR(t){let e=Array.isArray(t)?t:t?[t]:[];if(e.every(yZ.isJSONTyp...
  function SZ (line 5) | function SZ(t,e){let{gen:r,data:n,opts:i}=t,s=wZ(e,i.coerceTypes),o=e.le...
  function wZ (line 5) | function wZ(t,e){return e?t.filter(r=>AR.has(r)||e==="array"&&r==="array...
  function EZ (line 5) | function EZ(t,e,r){let{gen:n,data:i,opts:s}=t,o=n.let("dataType",(0,je._...
  function kZ (line 8) | function kZ({gen:t,parentData:e,parentDataProperty:r},n){t.if((0,je._)`$...
  function Vx (line 8) | function Vx(t,e,r,n=Ra.Correct){let i=n===Ra.Correct?je.operators.EQ:je....
  function Gx (line 8) | function Gx(t,e,r,n){if(t.length===1)return Vx(t[0],e,r,n);let i,s=(0,PR...
  function Wx (line 8) | function Wx(t){let e=TZ(t);(0,bZ.reportError)(e,$Z)}
  function TZ (line 8) | function TZ(t){let{gen:e,data:r,schema:n}=t,i=(0,PR.schemaRefOrVal)(t,n,...
  function RZ (line 8) | function RZ(t,e){let{properties:r,items:n}=t.schema;if(e==="object"&&r)f...
  function NR (line 8) | function NR(t,e,r){let{gen:n,compositeRule:i,data:s,opts:o}=t;if(r===voi...
  function PZ (line 8) | function PZ(t,e){let{gen:r,data:n,it:i}=t;r.if(Xx(r,n,e,i.opts.ownProper...
  function CZ (line 8) | function CZ({gen:t,data:e,it:{opts:r}},n,i){return(0,Ot.or)(...n.map(s=>...
  function AZ (line 8) | function AZ(t,e){t.setParams({missingProperty:e},!0),t.error()}
  function DR (line 8) | function DR(t){return t.scopeValue("func",{ref:Object.prototype.hasOwnPr...
  function Jx (line 8) | function Jx(t,e,r){return(0,Ot._)`${DR(t)}.call(${e}, ${r})`}
  function NZ (line 8) | function NZ(t,e,r,n){let i=(0,Ot._)`${e}${(0,Ot.getProperty)(r)} !== und...
  function Xx (line 8) | function Xx(t,e,r,n){let i=(0,Ot._)`${e}${(0,Ot.getProperty)(r)} === und...
  function jR (line 8) | function jR(t){return t?Object.keys(t).filter(e=>e!=="__proto__"):[]}
  function MZ (line 8) | function MZ(t,e){return jR(e).filter(r=>!(0,Kx.alwaysValidSchema)(t,e[r]))}
  function DZ (line 8) | function DZ({schemaCode:t,data:e,it:{gen:r,topSchemaRef:n,schemaPath:i,e...
  function zZ (line 8) | function zZ({gen:t,it:{opts:e}},r){let n=e.unicodeRegExp?"u":"",{regExp:...
  function LZ (line 8) | function LZ(t){let{gen:e,data:r,keyword:n,it:i}=t,s=e.name("valid");if(i...
  function UZ (line 8) | function UZ(t){let{gen:e,schema:r,keyword:n,it:i}=t;if(!Array.isArray(r)...
  function HZ (line 8) | function HZ(t,e){let{gen:r,keyword:n,schema:i,parentSchema:s,it:o}=t,a=e...
  function ZZ (line 8) | function ZZ(t,e){var r;let{gen:n,keyword:i,schema:s,parentSchema:o,$data...
  function zR (line 8) | function zR(t){let{gen:e,data:r,it:n}=t;e.if(n.parentData,()=>e.assign(r...
  function BZ (line 8) | function BZ(t,e){let{gen:r}=t;r.if((0,Lr._)`Array.isArray(${e})`,()=>{r....
  function VZ (line 8) | function VZ({schemaEnv:t},e){if(e.async&&!t.$async)throw new Error("asyn...
  function LR (line 8) | function LR(t,e,r){if(r===void 0)throw new Error(`keyword "${e}" failed ...
  function GZ (line 8) | function GZ(t,e,r=!1){return!e.length||e.some(n=>n==="array"?Array.isArr...
  function WZ (line 8) | function WZ({schema:t,opts:e,self:r,errSchemaPath:n},i,s){if(Array.isArr...
  function KZ (line 8) | function KZ(t,{keyword:e,schemaProp:r,schema:n,schemaPath:i,errSchemaPat...
  function JZ (line 8) | function JZ(t,e,{dataProp:r,dataPropType:n,data:i,dataTypes:s,propertyNa...
  function XZ (line 8) | function XZ(t,{jtdDiscriminator:e,jtdMetadata:r,compositeRule:n,createEr...
  function Qm (line 8) | function Qm(t,e,r,n,i,s,o,a,c,u){if(n&&typeof n=="object"&&!Array.isArra...
  function YZ (line 8) | function YZ(t){return t.replace(/~/g,"~0").replace(/\//g,"~1")}
  function nB (line 8) | function nB(t,e=!0){return typeof t=="boolean"?!0:e===!0?!Qx(t):e?VR(t)<...
  function Qx (line 8) | function Qx(t){for(let e in t){if(iB.has(e))return!0;let r=t[e];if(Array...
  function VR (line 8) | function VR(t){let e=0;for(let r in t){if(r==="$ref")return 1/0;if(e++,!...
  function GR (line 8) | function GR(t,e="",r){r!==!1&&(e=Pa(e));let n=t.parse(e);return WR(t,n)}
  function WR (line 8) | function WR(t,e){return t.serialize(e).split("#")[0]+"#"}
  function Pa (line 8) | function Pa(t){return t?t.replace(sB,""):""}
  function oB (line 8) | function oB(t,e,r){return r=Pa(r),t.resolve(e,r)}
  function cB (line 8) | function cB(t,e){if(typeof t=="boolean")return{};let{schemaId:r,uriResol...
  function dB (line 8) | function dB(t){if(rO(t)&&(nO(t),tO(t))){fB(t);return}eO(t,()=>(0,QR.topB...
  function eO (line 8) | function eO({gen:t,validateName:e,schema:r,schemaEnv:n,opts:i},s){i.code...
  function pB (line 8) | function pB(t){return(0,fe._)`{${Re.default.instancePath}="", ${Re.defau...
  function mB (line 8) | function mB(t,e){t.if(Re.default.valCxt,()=>{t.var(Re.default.instancePa...
  function fB (line 8) | function fB(t){let{schema:e,opts:r,gen:n}=t;eO(t,()=>{r.$comment&&e.$com...
  function hB (line 8) | function hB(t){let{gen:e,validateName:r}=t;t.evaluated=e.const("evaluate...
  function JR (line 8) | function JR(t,e){let r=typeof t=="object"&&t[e.schemaId];return r&&(e.co...
  function gB (line 8) | function gB(t,e){if(rO(t)&&(nO(t),tO(t))){vB(t,e);return}(0,QR.boolOrEmp...
  function tO (line 8) | function tO({schema:t,self:e}){if(typeof t=="boolean")return!t;for(let r...
  function rO (line 8) | function rO(t){return typeof t.schema!="boolean"}
  function vB (line 8) | function vB(t,e){let{schema:r,gen:n,opts:i}=t;i.$comment&&r.$comment&&sO...
  function nO (line 8) | function nO(t){(0,Bi.checkUnknownRules)(t),yB(t)}
  function iO (line 8) | function iO(t,e){if(t.opts.jtd)return XR(t,[],!1,e);let r=(0,KR.getSchem...
  function yB (line 8) | function yB(t){let{schema:e,errSchemaPath:r,opts:n,self:i}=t;e.$ref&&n.i...
  function _B (line 8) | function _B(t){let{schema:e,opts:r}=t;e.default!==void 0&&r.useDefaults&...
  function bB (line 8) | function bB(t){let e=t.schema[t.opts.schemaId];e&&(t.baseId=(0,lB.resolv...
  function xB (line 8) | function xB(t){if(t.schema.$async&&!t.schemaEnv.$async)throw new Error("...
  function sO (line 8) | function sO({gen:t,schemaEnv:e,schema:r,errSchemaPath:n,opts:i}){let s=r...
  function SB (line 8) | function SB(t){let{gen:e,schemaEnv:r,validateName:n,ValidationError:i,op...
  function wB (line 8) | function wB({gen:t,evaluated:e,props:r,items:n}){r instanceof fe.Name&&t...
  function XR (line 8) | function XR(t,e,r,n){let{gen:i,schema:s,data:o,allErrors:a,opts:c,self:u...
  function YR (line 8) | function YR(t,e){let{gen:r,schema:n,opts:{useDefaults:i}}=t;i&&(0,uB.ass...
  function EB (line 8) | function EB(t,e){t.schemaEnv.meta||!t.opts.strictTypes||(kB(t,e),t.opts....
  function kB (line 8) | function kB(t,e){if(e.length){if(!t.dataTypes.length){t.dataTypes=e;retu...
  function $B (line 8) | function $B(t,e){e.length>1&&!(e.length===2&&e.includes("null"))&&rS(t,"...
  function TB (line 8) | function TB(t,e){let r=t.self.RULES.all;for(let n in r){let i=r[n];if(ty...
  function IB (line 8) | function IB(t,e){return t.includes(e)||e==="number"&&t.includes("integer")}
  function oO (line 8) | function oO(t,e){return t.includes(e)||e==="integer"&&t.includes("number")}
  function RB (line 8) | function RB(t,e){let r=[];for(let n of t.dataTypes)oO(e,n)?r.push(n):e.i...
  function rS (line 8) | function rS(t,e){let r=t.schemaEnv.baseId+t.errSchemaPath;e+=` at "${r}"...
  method constructor (line 8) | constructor(e,r,n){if((0,wl.validateKeywordUsage)(e,r,n),this.gen=e.gen,...
  method result (line 8) | result(e,r,n){this.failResult((0,fe.not)(e),r,n)}
  method failResult (line 8) | failResult(e,r,n){this.gen.if(e),n?n():this.error(),r?(this.gen.else(),r...
  method pass (line 8) | pass(e,r){this.failResult((0,fe.not)(e),void 0,r)}
  method fail (line 8) | fail(e){if(e===void 0){this.error(),this.allErrors||this.gen.if(!1);retu...
  method fail$data (line 8) | fail$data(e){if(!this.$data)return this.fail(e);let{schemaCode:r}=this;t...
  method error (line 8) | error(e,r,n){if(r){this.setParams(r),this._error(e,n),this.setParams({})...
  method _error (line 8) | _error(e,r){(e?Sl.reportExtraError:Sl.reportError)(this,this.def.error,r)}
  method $dataError (line 8) | $dataError(){(0,Sl.reportError)(this,this.def.$dataError||Sl.keyword$Dat...
  method reset (line 8) | reset(){if(this.errsCount===void 0)throw new Error('add "trackErrors" to...
  method ok (line 8) | ok(e){this.allErrors||this.gen.if(e)}
  method setParams (line 8) | setParams(e,r){r?Object.assign(this.params,e):this.params=e}
  method block$data (line 8) | block$data(e,r,n=fe.nil){this.gen.block(()=>{this.check$data(e,n),r()})}
  method check$data (line 8) | check$data(e=fe.nil,r=fe.nil){if(!this.$data)return;let{gen:n,schemaCode...
  method invalid$data (line 8) | invalid$data(){let{gen:e,schemaCode:r,schemaType:n,def:i,it:s}=this;retu...
  method subschema (line 8) | subschema(e,r){let n=(0,eS.getSubschema)(this.it,e);(0,eS.extendSubschem...
  method mergeEvaluated (line 8) | mergeEvaluated(e,r){let{it:n,gen:i}=this;n.opts.unevaluated&&(n.props!==...
  method mergeValidEvaluated (line 8) | mergeValidEvaluated(e,r){let{it:n,gen:i}=this;if(n.opts.unevaluated&&(n....
  function aO (line 8) | function aO(t,e,r,n){let i=new tf(t,r,e);"code"in r?r.code(i,n):i.$data&...
  function cO (line 8) | function cO(t,{dataLevel:e,dataNames:r,dataPathArr:n}){let i,s;if(t===""...
  method constructor (line 8) | constructor(e){super("validation failed"),this.errors=e,this.ajv=this.va...
  method constructor (line 8) | constructor(e,r,n,i){super(i||`can't resolve reference ${n} from id ${r}...
  method constructor (line 8) | constructor(e){var r;this.refs={},this.dynamicAnchors={};let n;typeof e....
  function uS (line 8) | function uS(t){let e=lO.call(this,t);if(e)return e;let r=(0,Wn.getFullPa...
  function NB (line 8) | function NB(t,e,r){var n;r=(0,Wn.resolveUrl)(this.opts.uriResolver,e,r);...
  function MB (line 8) | function MB(t){return(0,Wn.inlineRef)(t.schema,this.opts.inlineRefs)?t.s...
  function lO (line 8) | function lO(t){for(let e of this._compilations)if(DB(e,t))return e}
  function DB (line 8) | function DB(t,e){return t.schema===e.schema&&t.root===e.root&&t.baseId==...
  function jB (line 8) | function jB(t,e){let r;for(;typeof(r=this.refs[e])=="string";)e=r;return...
  function nf (line 8) | function nf(t,e){let r=this.opts.uriResolver.parse(e),n=(0,Wn._getFullPa...
  function cS (line 8) | function cS(t,{baseId:e,schema:r,root:n}){var i;if(((i=t.fragment)===nul...
  function lS (line 8) | function lS(t){let e="",r=0,n=0;for(n=0;n<t.length;n++)if(r=t[n].charCod...
  function pO (line 8) | function pO(t){return t.length=0,!0}
  function FB (line 8) | function FB(t,e,r){if(t.length){let n=lS(t);if(n!=="")e.push(n);else ret...
  function HB (line 8) | function HB(t){let e=0,r={error:!1,address:"",zone:""},n=[],i=[],s=!1,o=...
  function fO (line 8) | function fO(t){if(ZB(t,":")<2)return{host:t,isIPV6:!1};let e=HB(t);if(e....
  function ZB (line 8) | function ZB(t,e){let r=0;for(let n=0;n<t.length;n++)t[n]===e&&r++;return r}
  function BB (line 8) | function BB(t){let e=t,r=[],n=-1,i=0;for(;i=e.length;){if(i===1){if(e===...
  function VB (line 8) | function VB(t,e){let r=e!==!0?escape:unescape;return t.scheme!==void 0&&...
  function GB (line 8) | function GB(t){let e=[];if(t.userinfo!==void 0&&(e.push(t.userinfo),e.pu...
  function XB (line 8) | function XB(t){return JB.indexOf(t)!==-1}
  function pS (line 8) | function pS(t){return t.secure===!0?!0:t.secure===!1?!1:t.scheme?t.schem...
  function gO (line 8) | function gO(t){return t.host||(t.error=t.error||"HTTP URIs must have a h...
  function vO (line 8) | function vO(t){let e=String(t.scheme).toLowerCase()==="https";return(t.p...
  function YB (line 8) | function YB(t){return t.secure=pS(t),t.resourceName=(t.path||"/")+(t.que...
  function QB (line 8) | function QB(t){if((t.port===(pS(t)?443:80)||t.port==="")&&(t.port=void 0...
  function eV (line 8) | function eV(t,e){if(!t.path)return t.error="URN can not be parsed",t;let...
  function tV (line 8) | function tV(t,e){if(t.nid===void 0)throw new Error("URN without nid cann...
  function rV (line 8) | function rV(t,e){let r=t;return r.uuid=r.nss,r.nss=void 0,!e.tolerant&&(...
  function nV (line 8) | function nV(t){let e=t;return e.nss=(t.uuid||"").toLowerCase(),e}
  function mS (line 8) | function mS(t){return t&&(af[t]||af[t.toLowerCase()])||void 0}
  function mV (line 8) | function mV(t,e){return typeof t=="string"?t=pi(Vi(t,e),e):typeof t=="ob...
  function fV (line 8) | function fV(t,e,r){let n=r?Object.assign({scheme:"null"},r):{scheme:"nul...
  function SO (line 8) | function SO(t,e,r,n){let i={};return n||(t=Vi(pi(t,r),r),e=Vi(pi(e,r),r)...
  function hV (line 8) | function hV(t,e,r){return typeof t=="string"?(t=unescape(t),t=pi(cf(Vi(t...
  function pi (line 8) | function pi(t,e){let r={host:t.host,scheme:t.scheme,userinfo:t.userinfo,...
  function Vi (line 8) | function Vi(t,e){let r=Object.assign({},e),n={scheme:void 0,userinfo:voi...
  function $V (line 8) | function $V(t){var e,r,n,i,s,o,a,c,u,l,d,p,m,f,g,h,v,x,b,_,S,w,E,$,R;let...
  method constructor (line 8) | constructor(e={}){this.schemas={},this.refs={},this.formats={},this._com...
  method _addVocabularies (line 8) | _addVocabularies(){this.addKeyword("$async")}
  method _addDefaultMetaSchema (line 8) | _addDefaultMetaSchema(){let{$data:e,meta:r,schemaId:n}=this.opts,i=$O;n=...
  method defaultMeta (line 8) | defaultMeta(){let{meta:e,schemaId:r}=this.opts;return this.opts.defaultM...
  method validate (line 8) | validate(e,r){let n;if(typeof e=="string"){if(n=this.getSchema(e),!n)thr...
  method compile (line 8) | compile(e,r){let n=this._addSchema(e,r);return n.validate||this._compile...
  method compileAsync (line 8) | compileAsync(e,r){if(typeof this.opts.loadSchema!="function")throw new E...
  method addSchema (line 8) | addSchema(e,r,n,i=this.opts.validateSchema){if(Array.isArray(e)){for(let...
  method addMetaSchema (line 8) | addMetaSchema(e,r,n=this.opts.validateSchema){return this.addSchema(e,r,...
  method validateSchema (line 8) | validateSchema(e,r){if(typeof e=="boolean")return!0;let n;if(n=e.$schema...
  method getSchema (line 8) | getSchema(e){let r;for(;typeof(r=RO.call(this,e))=="string";)e=r;if(r===...
  method removeSchema (line 8) | removeSchema(e){if(e instanceof RegExp)return this._removeAllSchemas(thi...
  method addVocabulary (line 8) | addVocabulary(e){for(let r of e)this.addKeyword(r);return this}
  method addKeyword (line 8) | addKeyword(e,r){let n;if(typeof e=="string")n=e,typeof r=="object"&&(thi...
  method getKeyword (line 8) | getKeyword(e){let r=this.RULES.all[e];return typeof r=="object"?r.defini...
  method removeKeyword (line 8) | removeKeyword(e){let{RULES:r}=this;delete r.keywords[e],delete r.all[e];...
  method addFormat (line 8) | addFormat(e,r){return typeof r=="string"&&(r=new RegExp(r)),this.formats...
  method errorsText (line 8) | errorsText(e=this.errors,{separator:r=", ",dataVar:n="data"}={}){return!...
  method $dataMetaSchema (line 8) | $dataMetaSchema(e,r){let n=this.RULES.all;e=JSON.parse(JSON.stringify(e)...
  method _removeAllSchemas (line 8) | _removeAllSchemas(e,r){for(let n in e){let i=e[n];(!r||r.test(n))&&(type...
  method _addSchema (line 8) | _addSchema(e,r,n,i=this.opts.validateSchema,s=this.opts.addUsedSchema){l...
  method _checkUnique (line 8) | _checkUnique(e){if(this.schemas[e]||this.refs[e])throw new Error(`schema...
  method _compileSchemaEnv (line 8) | _compileSchemaEnv(e){if(e.meta?this._compileMetaSchema(e):Tl.compileSche...
  method _compileMetaSchema (line 8) | _compileMetaSchema(e){let r=this.opts;this.opts=this._metaOpts;try{Tl.co...
  function IO (line 8) | function IO(t,e,r,n="error"){for(let i in t){let s=i;s in e&&this.logger...
  function RO (line 8) | function RO(t){return t=(0,Il.normalizeId)(t),this.schemas[t]||this.refs...
  function TV (line 8) | function TV(){let t=this.opts.schemas;if(t)if(Array.isArray(t))this.addS...
  function IV (line 8) | function IV(){for(let t in this.opts.formats){let e=this.opts.formats[t]...
  function RV (line 8) | function RV(t){if(Array.isArray(t)){this.addVocabulary(t);return}this.lo...
  function OV (line 8) | function OV(){let t={...this.opts};for(let e of SV)delete t[e];return t}
  method log (line 8) | log(){}
  method warn (line 8) | warn(){}
  method error (line 8) | error(){}
  function CV (line 8) | function CV(t){if(t===!1)return PV;if(t===void 0)return console;if(t.log...
  function NV (line 8) | function NV(t,e){let{RULES:r}=this;if((0,vS.eachItem)(t,n=>{if(r.keyword...
  function gS (line 8) | function gS(t,e,r){var n;let i=e?.post;if(r&&i)throw new Error('keyword ...
  function MV (line 8) | function MV(t,e,r){let n=t.rules.findIndex(i=>i.keyword===r);n>=0?t.rule...
  function DV (line 8) | function DV(t){let{metaSchema:e}=t;e!==void 0&&(t.$data&&this.opts.$data...
  function CO (line 8) | function CO(t){return{anyOf:[t,jV]}}
  method code (line 8) | code(){throw new Error('NOT SUPPORTED: keyword "id", use "$id" for schem...
  method code (line 8) | code(t){let{gen:e,schema:r,it:n}=t,{baseId:i,schemaEnv:s,validateName:o,...
  function jO (line 8) | function jO(t,e){let{gen:r}=t;return e.validate?r.scopeValue("validate",...
  function pf (line 8) | function pf(t,e,r,n){let{gen:i,it:s}=t,{allErrors:o,schemaEnv:a,opts:c}=...
  method code (line 8) | code(t){let{keyword:e,data:r,schemaCode:n}=t;t.fail$data((0,mf._)`${r} $...
  method code (line 8) | code(t){let{gen:e,data:r,schemaCode:n,it:i}=t,s=i.opts.multipleOfPrecisi...
  function FO (line 8) | function FO(t){let e=t.length,r=0,n=0,i;for(;n<e;)r++,i=t.charCodeAt(n++...
  method message (line 8) | message({keyword:t,schemaCode:e}){let r=t==="maxLength"?"more":"fewer";r...
  method code (line 8) | code(t){let{keyword:e,data:r,schemaCode:n,it:i}=t,s=e==="maxLength"?fo.o...
  method code (line 8) | code(t){let{gen:e,data:r,$data:n,schema:i,schemaCode:s,it:o}=t,a=o.opts....
  method message (line 8) | message({keyword:t,schemaCode:e}){let r=t==="maxProperties"?"more":"fewe...
  method code (line 8) | code(t){let{keyword:e,data:r,schemaCode:n}=t,i=e==="maxProperties"?Pl.op...
  method code (line 8) | code(t){let{gen:e,schema:r,schemaCode:n,data:i,$data:s,it:o}=t,{opts:a}=...
  method message (line 8) | message({keyword:t,schemaCode:e}){let r=t==="maxItems"?"more":"fewer";re...
  method code (line 8) | code(t){let{keyword:e,data:r,schemaCode:n}=t,i=e==="maxItems"?Nl.operato...
  method code (line 8) | code(t){let{gen:e,data:r,$data:n,schema:i,parentSchema:s,schemaCode:o,it...
  method code (line 8) | code(t){let{gen:e,data:r,$data:n,schemaCode:i,schema:s}=t;n||s&&typeof s...
  method code (line 8) | code(t){let{gen:e,data:r,$data:n,schema:i,schemaCode:s,it:o}=t;if(!n&&i....
  method code (line 8) | code(t){let{parentSchema:e,it:r}=t,{items:n}=e;if(!Array.isArray(n)){(0,...
  function eP (line 8) | function eP(t,e){let{gen:r,schema:n,data:i,keyword:s,it:o}=t;o.items=!0;...
  method code (line 8) | code(t){let{schema:e,it:r}=t;if(Array.isArray(e))return rP(t,"additional...
  function rP (line 8) | function rP(t,e,r=t.schema){let{gen:n,parentSchema:i,data:s,keyword:o,it...
  method code (line 8) | code(t){let{schema:e,parentSchema:r,it:n}=t,{prefixItems:i}=r;n.items=!0...
  method code (line 8) | code(t){let{gen:e,schema:r,parentSchema:n,data:i,it:s}=t,o,a,{minContain...
  method code (line 11) | code(t){let[e,r]=GG(t);aP(t,e),cP(t,r)}
  function GG (line 11) | function GG({schema:t}){let e={},r={};for(let n in t){if(n==="__proto__"...
  function aP (line 11) | function aP(t,e=t.schema){let{gen:r,data:n,it:i}=t;if(Object.keys(e).len...
  function cP (line 11) | function cP(t,e=t.schema){let{gen:r,data:n,keyword:i,it:s}=t,o=r.name("v...
  method code (line 11) | code(t){let{gen:e,schema:r,data:n,it:i}=t;if((0,WG.alwaysValidSchema)(i,...
  method code (line 11) | code(t){let{gen:e,schema:r,parentSchema:n,data:i,errsCount:s,it:o}=t;if(...
  method code (line 11) | code(t){let{gen:e,schema:r,parentSchema:n,data:i,it:s}=t;s.opts.removeAd...
  method code (line 11) | code(t){let{gen:e,schema:r,data:n,parentSchema:i,it:s}=t,{opts:o}=s,a=(0...
  method code (line 11) | code(t){let{gen:e,schema:r,it:n}=t;if((0,nW.alwaysValidSchema)(n,r)){t.f...
  method code (line 11) | code(t){let{gen:e,schema:r,parentSchema:n,it:i}=t;if(!Array.isArray(r))t...
  method code (line 11) | code(t){let{gen:e,schema:r,it:n}=t;if(!Array.isArray(r))throw new Error(...
  method code (line 11) | code(t){let{gen:e,parentSchema:r,it:n}=t;r.then===void 0&&r.else===void ...
  function wP (line 11) | function wP(t,e){let r=t.schema[e];return r!==void 0&&!(0,EP.alwaysValid...
  method code (line 11) | code({keyword:t,parentSchema:e,it:r}){e.if===void 0&&(0,fW.checkStrictMo...
  function CW (line 11) | function CW(t=!1){let e=[$W.default,TW.default,IW.default,RW.default,OW....
  method code (line 11) | code(t,e){let{gen:r,data:n,$data:i,schema:s,schemaCode:o,it:a}=t,{opts:c...
  method code (line 11) | code(t){let{gen:e,data:r,schema:n,parentSchema:i,it:s}=t,{oneOf:o}=i;if(...
  method _addVocabularies (line 11) | _addVocabularies(){super._addVocabularies(),WW.default.forEach(e=>this.a...
  method _addDefaultMetaSchema (line 11) | _addDefaultMetaSchema(){if(super._addDefaultMetaSchema(),!this.opts.meta...
  method defaultMeta (line 11) | defaultMeta(){return this.opts.defaultMeta=super.defaultMeta()||(this.ge...
  function fi (line 11) | function fi(t,e){return{validate:t,compare:e}}
  function e7 (line 11) | function e7(t){return t%4===0&&(t%100!==0||t%400===0)}
  function FP (line 11) | function FP(t){let e=t7.exec(t);if(!e)return!1;let r=+e[1],n=+e[2],i=+e[...
  function d0 (line 11) | function d0(t,e){if(t&&e)return t>e?1:t<e?-1:0}
  function u0 (line 11) | function u0(t){return function(r){let n=c0.exec(r);if(!n)return!1;let i=...
  function p0 (line 11) | function p0(t,e){if(!(t&&e))return;let r=new Date("2020-01-01T"+t).value...
  function HP (line 11) | function HP(t,e){if(!(t&&e))return;let r=c0.exec(t),n=c0.exec(e);if(r&&n...
  function LP (line 11) | function LP(t){let e=u0(t);return function(n){let i=n.split(l0);return i...
  function ZP (line 11) | function ZP(t,e){if(!(t&&e))return;let r=new Date(t).valueOf(),n=new Dat...
  function BP (line 11) | function BP(t,e){if(!(t&&e))return;let[r,n]=t.split(l0),[i,s]=e.split(l0...
  function s7 (line 11) | function s7(t){return n7.test(t)&&i7.test(t)}
  function o7 (line 11) | function o7(t){return UP.lastIndex=0,UP.test(t)}
  function u7 (line 11) | function u7(t){return Number.isInteger(t)&&t<=c7&&t>=a7}
  function l7 (line 11) | function l7(t){return Number.isInteger(t)}
  function qP (line 11) | function qP(){return!0}
  function p7 (line 11) | function p7(t){if(d7.test(t))return!1;try{return new RegExp(t),!0}catch{...
  method code (line 11) | code(t){let{gen:e,data:r,schemaCode:n,keyword:i,it:s}=t,{opts:o,self:a}=...
  function KP (line 11) | function KP(t,e,r,n){var i,s;(i=(s=t.opts.code).formats)!==null&&i!==voi...
  function b7 (line 11) | function b7(t,e){var r=e.pathExt!==void 0?e.pathExt:process.env.PATHEXT;...
  function nC (line 11) | function nC(t,e,r){return!t.isSymbolicLink()&&!t.isFile()?!1:b7(e,r)}
  function iC (line 11) | function iC(t,e,r){rC.stat(t,function(n,i){r(n,n?!1:nC(i,t,e))})}
  function x7 (line 11) | function x7(t,e){return nC(rC.statSync(t),t,e)}
  function cC (line 11) | function cC(t,e,r){aC.stat(t,function(n,i){r(n,n?!1:uC(i,e))})}
  function S7 (line 11) | function S7(t,e){return uC(aC.statSync(t),e)}
  function uC (line 11) | function uC(t,e){return t.isFile()&&w7(t,e)}
  function w7 (line 11) | function w7(t,e){var r=t.mode,n=t.uid,i=t.gid,s=e.uid!==void 0?e.uid:pro...
  function h0 (line 11) | function h0(t,e,r){if(typeof e=="function"&&(r=e,e={}),!r){if(typeof Pro...
  function E7 (line 11) | function E7(t,e){try{return Rf.sync(t,e||{})}catch(r){if(e&&e.ignoreErro...
  function EC (line 11) | function EC(t,e){let r=t.options.env||process.env,n=process.cwd(),i=t.op...
  function R7 (line 11) | function R7(t){return EC(t)||EC(t,!0)}
  function O7 (line 11) | function O7(t){return t=t.replace(v0,"^$1"),t}
  function P7 (line 11) | function P7(t,e){return t=`${t}`,t=t.replace(/(?=(\\+?)?)\1"/g,'$1$1\\"'...
  function N7 (line 11) | function N7(t){let r=Buffer.alloc(150),n;try{n=_0.openSync(t,"r"),_0.rea...
  function U7 (line 11) | function U7(t){t.file=NC(t);let e=t.file&&D7(t.file);return e?(t.args.un...
  function q7 (line 11) | function q7(t){if(!j7)return t;let e=U7(t),r=!z7.test(e);if(t.options.fo...
  function F7 (line 11) | function F7(t,e,r){e&&!Array.isArray(e)&&(r=e,e=null),e=e?e.slice(0):[],...
  function x0 (line 11) | function x0(t,e){return Object.assign(new Error(`${e} ${t.command} ENOEN...
  function H7 (line 11) | function H7(t,e){if(!b0)return;let r=t.emit;t.emit=function(n,i){if(n===...
  function zC (line 11) | function zC(t,e){return b0&&t===1&&!e.file?x0(e.original,"spawn"):null}
  function Z7 (line 11) | function Z7(t,e){return b0&&t===1&&!e.file?x0(e.original,"spawnSync"):null}
  function FC (line 11) | function FC(t,e,r){let n=S0(t,e,r),i=qC.spawn(n.command,n.args,n.options...
  function B7 (line 11) | function B7(t,e,r){let n=S0(t,e,r),i=qC.spawnSync(n.command,n.args,n.opt...
  method constructor (line 11) | constructor(){this.useColor=process.stdout.isTTY??!1}
  method ensureLogFileInitialized (line 11) | ensureLogFileInitialized(){if(!this.logFileInitialized){this.logFileInit...
  method getLevel (line 11) | getLevel(){if(this.level===null)try{let e=(0,ql.join)(GC,"settings.json"...
  method correlationId (line 11) | correlationId(e,r){return`obs-${e}-${r}`}
  method sessionId (line 11) | sessionId(e){return`session-${e}`}
  method formatData (line 11) | formatData(e){if(e==null)return"";if(typeof e=="string")return e;if(type...
  method formatTool (line 12) | formatTool(e,r){if(!r)return e;let n=r;if(typeof r=="string")try{n=JSON....
  method formatTimestamp (line 12) | formatTimestamp(e){let r=e.getFullYear(),n=String(e.getMonth()+1).padSta...
  method log (line 12) | log(e,r,n,i,s){if(e<this.getLevel())return;this.ensureLogFileInitialized...
  method debug (line 18) | debug(e,r,n,i){this.log(0,e,r,n,i)}
  method info (line 18) | info(e,r,n,i){this.log(1,e,r,n,i)}
  method warn (line 18) | warn(e,r,n,i){this.log(2,e,r,n,i)}
  method error (line 18) | error(e,r,n,i){this.log(3,e,r,n,i)}
  method dataIn (line 18) | dataIn(e,r,n,i){this.info(e,`\u2192 ${r}`,n,i)}
  method dataOut (line 18) | dataOut(e,r,n,i){this.info(e,`\u2190 ${r}`,n,i)}
  method success (line 18) | success(e,r,n,i){this.info(e,`\u2713 ${r}`,n,i)}
  method failure (line 18) | failure(e,r,n,i){this.error(e,`\u2717 ${r}`,n,i)}
  method timing (line 18) | timing(e,r,n,i){this.info(e,`\u23F1 ${r}`,i,{duration:`${n}ms`})}
  method happyPathError (line 18) | happyPathError(e,r,n,i,s=""){let u=((new Error().stack||"").split(`
  function Pf (line 19) | function Pf(t){return process.platform==="win32"?Math.round(t*_r.WINDOWS...
  method getAllDefaults (line 19) | static getAllDefaults(){return{...this.DEFAULTS}}
  method get (line 19) | static get(e){return process.env[e]??this.DEFAULTS[e]}
  method getInt (line 19) | static getInt(e){let r=this.get(e);return parseInt(r,10)}
  method getBool (line 19) | static getBool(e){let r=this.get(e);return r==="true"||r===!0}
  method applyEnvOverrides (line 19) | static applyEnvOverrides(e){let r={...e};for(let n of Object.keys(this.D...
  method loadFromFile (line 19) | static loadFromFile(e){try{if(!(0,gi.existsSync)(e)){let o=this.getAllDe...
  function J7 (line 19) | function J7(){return typeof __dirname<"u"?__dirname:(0,lt.dirname)((0,YC...
  function Y7 (line 19) | function Y7(){if(process.env.CLAUDE_MEM_DATA_DIR)return process.env.CLAU...
  function rK (line 19) | function rK(t){return(0,lt.join)(T0,t)}
  function nK (line 19) | function nK(t){return(0,lt.join)(ar,`worker-${t}.sock`)}
  function Ir (line 19) | function Ir(t){(0,Af.mkdirSync)(t,{recursive:!0})}
  function iK (line 19) | function iK(){Ir(ar),Ir(T0),Ir(QC),Ir(eA),Ir(tA),Ir(I0)}
  function sK (line 19) | function sK(){Ir(I0)}
  function oK (line 19) | function oK(){Ir(Wi),Ir(rA)}
  function nA (line 19) | function nA(){try{let t=(0,XC.execSync)("git rev-parse --show-toplevel",...
  function Qr (line 19) | function Qr(){return(0,lt.join)(X7,"..")}
  function aK (line 19) | function aK(){let t=Qr();return(0,lt.join)(t,"commands")}
  function cK (line 19) | function cK(t){let e=new Date().toISOString().replace(/[:.]/g,"-").repla...
  function lK (line 19) | function lK(t,e={},r){return new Promise((n,i)=>{let s=setTimeout(()=>i(...
  function Ur (line 19) | function Ur(){if(Hl!==null)return Hl;let t=Mf.default.join(Ee.get("CLAUD...
  function O0 (line 19) | function O0(){if(Zl!==null)return Zl;let t=Mf.default.join(Ee.get("CLAUD...
  function oA (line 19) | function oA(){Hl=null,Zl=null}
  function dK (line 19) | function dK(t){return`http://${O0()}:${Ur()}${t}`}
  function jt (line 19) | function jt(t,e={}){let r=e.method??"GET",n=e.timeoutMs??R0,i=dK(t),s={m...
  function pK (line 19) | async function pK(){return(await jt("/api/health",{timeoutMs:R0})).ok}
  function mK (line 19) | function mK(){try{let t=Mf.default.join(Ki,"package.json");return JSON.p...
  function fK (line 19) | async function fK(){let t=await jt("/api/version",{timeoutMs:R0});if(!t....
  function hK (line 19) | async function hK(){try{let t=mK();if(t==="unknown")return;let e=await f...
  function en (line 19) | async function en(){try{if(await pK())return await hK(),!0}catch(t){y.de...
  function Uf (line 19) | function Uf(t,e,r){return(0,$A.createHash)("sha256").update((t||"")+(e||...
  function qf (line 19) | function qf(t,e,r){let n=r-MK;return t.prepare("SELECT id, created_at_ep...
  method constructor (line 19) | constructor(e=Fl){e!==":memory:"&&Ir(ar),this.db=new IA.Database(e),this...
  method initializeSchema (line 19) | initializeSchema(){this.db.run(`
  method ensureWorkerPortColumn (line 81) | ensureWorkerPortColumn(){this.db.query("PRAGMA table_info(sdk_sessions)"...
  method ensurePromptTrackingColumns (line 81) | ensurePromptTrackingColumns(){this.db.query("PRAGMA table_info(sdk_sessi...
  method removeSessionSummariesUniqueConstraint (line 81) | removeSessionSummariesUniqueConstraint(){if(!this.db.query("PRAGMA index...
  method addObservationHierarchicalFields (line 109) | addObservationHierarchicalFields(){if(this.db.prepare("SELECT version FR...
  method makeObservationsTextNullable (line 117) | makeObservationsTextNullable(){if(this.db.prepare("SELECT version FROM s...
  method createUserPromptsTable (line 147) | createUserPromptsTable(){if(this.db.prepare("SELECT version FROM schema_...
  method ensureDiscoveryTokensColumn (line 185) | ensureDiscoveryTokensColumn(){if(this.db.prepare("SELECT version FROM sc...
  method createPendingMessagesTable (line 185) | createPendingMessagesTable(){if(this.db.prepare("SELECT version FROM sch...
  method renameSessionIdColumns (line 205) | renameSessionIdColumns(){if(this.db.prepare("SELECT version FROM schema_...
  method repairSessionIdColumnRename (line 205) | repairSessionIdColumnRename(){this.db.prepare("SELECT version FROM schem...
  method addFailedAtEpochColumn (line 205) | addFailedAtEpochColumn(){if(this.db.prepare("SELECT version FROM schema_...
  method addOnUpdateCascadeToForeignKeys (line 205) | addOnUpdateCascadeToForeignKeys(){if(!this.db.prepare("SELECT version FR...
  method addObservationContentHashColumn (line 299) | addObservationContentHashColumn(){if(this.db.query("PRAGMA table_info(ob...
  method addSessionCustomTitleColumn (line 299) | addSessionCustomTitleColumn(){if(this.db.prepare("SELECT version FROM sc...
  method updateMemorySessionId (line 299) | updateMemorySessionId(e,r){this.db.prepare(`
  method ensureMemorySessionIdRegistered (line 303) | ensureMemorySessionIdRegistered(e,r){let n=this.db.prepare(`
  method getRecentSummaries (line 307) | getRecentSummaries(e,r=10){return this.db.prepare(`
  method getRecentSummariesWithSessionInfo (line 315) | getRecentSummariesWithSessionInfo(e,r=3){return this.db.prepare(`
  method getRecentObservations (line 323) | getRecentObservations(e,r=20){return this.db.prepare(`
  method getAllRecentObservations (line 329) | getAllRecentObservations(e=100){return this.db.prepare(`
  method getAllRecentSummaries (line 334) | getAllRecentSummaries(e=50){return this.db.prepare(`
  method getAllRecentUserPrompts (line 341) | getAllRecentUserPrompts(e=100){return this.db.prepare(`
  method getAllProjects (line 354) | getAllProjects(){return this.db.prepare(`
  method getLatestUserPrompt (line 359) | getLatestUserPrompt(e){return this.db.prepare(`
  method getRecentSessionsWithStatus (line 369) | getRecentSessionsWithStatus(e,r=3){return this.db.prepare(`
  method getObservationsForSession (line 386) | getObservationsForSession(e){return this.db.prepare(`
  method getObservationById (line 391) | getObservationById(e){return this.db.prepare(`
  method getObservationsByIds (line 395) | getObservationsByIds(e,r={}){if(e.length===0)return[];let{orderBy:n="dat...
  method getSummaryForSession (line 401) | getSummaryForSession(e){return this.db.prepare(`
  method getFilesForSession (line 410) | getFilesForSession(e){let n=this.db.prepare(`
  method getSessionById (line 414) | getSessionById(e){return this.db.prepare(`
  method getSdkSessionsBySessionIds (line 419) | getSdkSessionsBySessionIds(e){if(e.length===0)return[];let r=e.map(()=>"...
  method getPromptNumberFromUserPrompts (line 425) | getPromptNumberFromUserPrompts(e){return this.db.prepare(`
  method createSDKSession (line 427) | createSDKSession(e,r,n,i){let s=new Date,o=s.getTime(),a=this.db.prepare(`
  method saveUserPrompt (line 439) | saveUserPrompt(e,r,n){let i=new Date,s=i.getTime();return this.db.prepare(`
  method getUserPrompt (line 443) | getUserPrompt(e,r){return this.db.prepare(`
  method storeObservation (line 448) | storeObservation(e,r,n,i,s=0,o){let a=o??Date.now(),c=new Date(a).toISOS...
  method storeSummary (line 453) | storeSummary(e,r,n,i,s=0,o){let a=o??Date.now(),c=new Date(a).toISOStrin...
  method storeObservations (line 458) | storeObservations(e,r,n,i,s,o=0,a){let c=a??Date.now(),u=new Date(c).toI...
  method storeObservationsAndMarkComplete (line 468) | storeObservationsAndMarkComplete(e,r,n,i,s,o,a,c=0,u){let l=u??Date.now(...
  method getSessionSummariesByIds (line 486) | getSessionSummariesByIds(e,r={}){if(e.length===0)return[];let{orderBy:n=...
  method getUserPromptsByIds (line 491) | getUserPromptsByIds(e,r={}){if(e.length===0)return[];let{orderBy:n="date...
  method getTimelineAroundTimestamp (line 501) | getTimelineAroundTimestamp(e,r=10,n=10,i){return this.getTimelineAroundO...
  method getTimelineAroundObservation (line 501) | getTimelineAroundObservation(e,r,n=10,i=10,s){let o=s?"AND project = ?":...
  method getPromptById (line 541) | getPromptById(e){return this.db.prepare(`
  method getPromptsByIds (line 554) | getPromptsByIds(e){if(e.length===0)return[];let r=e.map(()=>"?").join(",...
  method getSessionSummaryById (line 567) | getSessionSummaryById(e){return this.db.prepare(`
  method getOrCreateManualSession (line 582) | getOrCreateManualSession(e){let r=`manual-${e}`,n=`manual-content-${e}`;...
  method close (line 585) | close(){this.db.close()}
  method importSdkSession (line 585) | importSdkSession(e){let r=this.db.prepare("SELECT id FROM sdk_sessions W...
  method importSessionSummary (line 590) | importSessionSummary(e){let r=this.db.prepare("SELECT id FROM session_su...
  method importObservation (line 596) | importObservation(e){let r=this.db.prepare(`
  method importUserPrompt (line 605) | importUserPrompt(e){let r=this.db.prepare(`
  function WA (line 613) | function WA(t,e){for(var r=t.split(/[ ,]+/),n=String(e).toLowerCase(),i=...
  function GK (line 613) | function GK(t,e,r){var n=Object.getOwnPropertyDescriptor(t,e),i=n.value;
Condensed preview — 589 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,727K chars).
[
  {
    "path": ".claude/commands/anti-pattern-czar.md",
    "chars": 3793,
    "preview": "# Anti-Pattern Czar\n\nYou are the **Anti-Pattern Czar**, an expert at identifying and fixing error handling anti-patterns"
  },
  {
    "path": ".claude/reports/test-audit-2026-01-05.md",
    "chars": 15842,
    "preview": "# Test Quality Audit Report\n\n**Date**: 2026-01-05\n**Auditor**: Claude Code (Opus 4.5)\n**Methodology**: Deep analysis wit"
  },
  {
    "path": ".claude/settings.json",
    "chars": 154,
    "preview": "{\n  \"env\": {},\n  \"permissions\": {\n    \"deny\": [\n      \"Read(./package-lock.json)\",\n      \"Read(./node_modules/**)\",\n    "
  },
  {
    "path": ".claude-plugin/CLAUDE.md",
    "chars": 4685,
    "preview": "<claude-mem-context>\n# Recent Activity\n\n### Oct 25, 2025\n\n| ID | Time | T | Title | Read |\n|----|------|---|-------|----"
  },
  {
    "path": ".claude-plugin/marketplace.json",
    "chars": 426,
    "preview": "{\n  \"name\": \"thedotmack\",\n  \"owner\": {\n    \"name\": \"Alex Newman\"\n  },\n  \"metadata\": {\n    \"description\": \"Plugins by Ale"
  },
  {
    "path": ".claude-plugin/plugin.json",
    "chars": 379,
    "preview": "{\n  \"name\": \"claude-mem\",\n  \"version\": \"10.4.1\",\n  \"description\": \"Persistent memory system for Claude Code - seamlessly"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 19,
    "preview": "github: thedotmack\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1614,
    "preview": "---\nname: Bug report\nabout: Use the automated bug report tool for best results\ntitle: ''\nlabels: 'bug, needs-triage'\nass"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 758,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: feature-request\nassignees: ''\n\n---\n\n"
  },
  {
    "path": ".github/workflows/claude-code-review.yml",
    "chars": 1964,
    "preview": "name: Claude Code Review\n\non:\n  pull_request:\n    types: [opened, synchronize]\n    # Optional: Only run on specific file"
  },
  {
    "path": ".github/workflows/claude.yml",
    "chars": 1898,
    "preview": "name: Claude Code\n\non:\n  issue_comment:\n    types: [created]\n  pull_request_review_comment:\n    types: [created]\n  issue"
  },
  {
    "path": ".github/workflows/convert-feature-requests.yml",
    "chars": 4588,
    "preview": "name: Convert Feature Requests to Discussions\n\non:\n  issues:\n    types: [labeled]\n  workflow_dispatch:\n    inputs:\n     "
  },
  {
    "path": ".github/workflows/deploy-install-scripts.yml",
    "chars": 726,
    "preview": "name: Deploy Install Scripts\n\non:\n  push:\n    branches: [main]\n    paths:\n      - 'openclaw/install.sh'\n      - 'install"
  },
  {
    "path": ".github/workflows/npm-publish.yml",
    "chars": 438,
    "preview": "name: Publish to npm\n\non:\n  push:\n    tags:\n      - 'v*'\n\njobs:\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n      -"
  },
  {
    "path": ".github/workflows/summary.yml",
    "chars": 879,
    "preview": "name: Summarize new issues\n\non:\n  issues:\n    types: [opened]\n\njobs:\n  summary:\n    runs-on: ubuntu-latest\n    permissio"
  },
  {
    "path": ".gitignore",
    "chars": 587,
    "preview": "datasets/\nnode_modules/\ndist/\n!installer/dist/\n**/_tree-sitter/\n*.log\n.DS_Store\n.env\n.env.local\n*.tmp\n*.temp\n.install-ve"
  },
  {
    "path": ".markdownlint.json",
    "chars": 20,
    "preview": "{\n  \"MD013\": false\n}"
  },
  {
    "path": ".plan/npx-distribution.md",
    "chars": 38158,
    "preview": "# Plan: NPX Distribution + Universal IDE/CLI Coverage for claude-mem\n\n## Problem\n\n1. **Installation is slow and fragile*"
  },
  {
    "path": ".translation-cache.json",
    "chars": 3085,
    "preview": "{\n  \"sourceHash\": \"9ab0d799179c66f9\",\n  \"lastUpdated\": \"2025-12-12T07:42:03.489Z\",\n  \"translations\": {\n    \"zh\": {\n     "
  },
  {
    "path": "CHANGELOG.md",
    "chars": 61928,
    "preview": "# Changelog\n\nAll notable changes to claude-mem.\n\n## [v10.6.3] - 2026-03-29\n\n## v10.6.3 — Critical Patch Release\n\n### Bug"
  },
  {
    "path": "CLAUDE.md",
    "chars": 4102,
    "preview": "# Claude-Mem: AI Development Instructions\n\nClaude-mem is a Claude Code plugin providing persistent memory across session"
  },
  {
    "path": "LICENSE",
    "chars": 32902,
    "preview": "                  GNU AFFERO GENERAL PUBLIC LICENSE\n                      Version 3, 19 November 2007\n\n  Copyright (C) 2"
  },
  {
    "path": "README.md",
    "chars": 15189,
    "preview": "<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.com/thedotmack/claude-mem\">\n    <picture>\n      <source media=\"(pre"
  },
  {
    "path": "conductor.json",
    "chars": 155,
    "preview": "{\n    \"scripts\": {\n        \"setup\": \"cp ../settings.local.json .claude/settings.local.json && npm install\",\n        \"run"
  },
  {
    "path": "cursor-hooks/.gitignore",
    "chars": 44,
    "preview": "# Ignore backup files created by sed\n*.bak\n\n"
  },
  {
    "path": "cursor-hooks/CONTEXT-INJECTION.md",
    "chars": 5009,
    "preview": "# Context Injection in Cursor Hooks\n\n## The Solution: Auto-Updated Rules File\n\nContext is automatically injected via Cur"
  },
  {
    "path": "cursor-hooks/INTEGRATION.md",
    "chars": 6923,
    "preview": "# Claude-Mem ↔ Cursor Integration Architecture\n\n## Overview\n\nThis integration connects claude-mem's persistent memory sy"
  },
  {
    "path": "cursor-hooks/PARITY.md",
    "chars": 7847,
    "preview": "# Feature Parity: Claude-Mem Hooks vs Cursor Hooks\n\nThis document compares claude-mem's Claude Code hooks with the Curso"
  },
  {
    "path": "cursor-hooks/QUICKSTART.md",
    "chars": 3159,
    "preview": "# Quick Start: Claude-Mem + Cursor Integration\n\n> **Give your Cursor AI persistent memory in under 5 minutes**\n\n## What "
  },
  {
    "path": "cursor-hooks/README.md",
    "chars": 7638,
    "preview": "# Claude-Mem Cursor Hooks Integration\n\n> **Persistent AI Memory for Cursor - Free Options Available**\n\nGive your Cursor "
  },
  {
    "path": "cursor-hooks/REVIEW.md",
    "chars": 10251,
    "preview": "# Comprehensive Review: Cursor Hooks Integration\n\n## Overview\n\nThis document provides a thorough review of the Cursor ho"
  },
  {
    "path": "cursor-hooks/STANDALONE-SETUP.md",
    "chars": 7610,
    "preview": "# Claude-Mem for Cursor (No Claude Code Required)\n\n> **Persistent AI Memory for Cursor - Zero Cost to Start**\n\n## Overvi"
  },
  {
    "path": "cursor-hooks/cursorrules-template.md",
    "chars": 2392,
    "preview": "# Claude-Mem Rules for Cursor\n\n## Automatic Context Injection\n\nThe `context-inject.sh` hook **automatically creates and "
  },
  {
    "path": "cursor-hooks/hooks.json",
    "chars": 617,
    "preview": "{\n  \"version\": 1,\n  \"hooks\": {\n    \"beforeSubmitPrompt\": [\n      {\n        \"command\": \"./cursor-hooks/session-init.sh\"\n "
  },
  {
    "path": "docs/CLAUDE.md",
    "chars": 4665,
    "preview": "<claude-mem-context>\n# Recent Activity\n\n<!-- This section is auto-generated by claude-mem. Edit content outside the tags"
  },
  {
    "path": "docs/PR-SHIPPING-REPORT.md",
    "chars": 5920,
    "preview": "# Claude-Mem PR Shipping Report\n*Generated: 2026-02-04*\n\n## Executive Summary\n\n6 PRs analyzed for shipping readiness. **"
  },
  {
    "path": "docs/SESSION_ID_ARCHITECTURE.md",
    "chars": 7085,
    "preview": "# Session ID Architecture\n\n## Overview\n\nClaude-mem uses **two distinct session IDs** to track conversations and memory:\n"
  },
  {
    "path": "docs/VERSION_FIX.md",
    "chars": 3596,
    "preview": "# Version Consistency Fix (Issue #XXX)\n\n## Problem\nVersion mismatch between plugin and worker caused infinite restart lo"
  },
  {
    "path": "docs/anti-pattern-cleanup-plan.md",
    "chars": 1441,
    "preview": "# Error Handling Anti-Pattern Cleanup Plan\n\n**Total: 132 anti-patterns to fix**\n\nRun detector: `bun run scripts/anti-pat"
  },
  {
    "path": "docs/bug-fixes/windows-spaces-issue.md",
    "chars": 2625,
    "preview": "---\nTitle: Bug: SDK Agent fails on Windows when username contains spaces\n---\n\n## Bug Report\n\n**Summary:** Claude SDK Age"
  },
  {
    "path": "docs/context/agent-sdk-v2-examples.ts",
    "chars": 3974,
    "preview": "/**\n * Claude Agent SDK V2 Examples\n *\n * The V2 API provides a session-based interface with separate send()/receive(),\n"
  },
  {
    "path": "docs/context/agent-sdk-v2-preview.md",
    "chars": 10840,
    "preview": "# TypeScript SDK V2 interface (preview)\n\nPreview of the simplified V2 TypeScript Agent SDK, with session-based send/rece"
  },
  {
    "path": "docs/context/cursor-hooks-reference.md",
    "chars": 18964,
    "preview": "# Hooks\n\nHooks let you observe, control, and extend the agent loop using custom scripts. Hooks are spawned processes tha"
  },
  {
    "path": "docs/context/hooks-reference-2026-01-07.md",
    "chars": 9759,
    "preview": "# Get started with Claude Code hooks\n\n> Learn how to customize and extend Claude Code's behavior by registering shell co"
  },
  {
    "path": "docs/i18n/.translation-cache.json",
    "chars": 3901,
    "preview": "{\n  \"sourceHash\": \"c0eb50d6772b5e61\",\n  \"lastUpdated\": \"2025-12-23T00:48:34.035Z\",\n  \"translations\": {\n    \"zh\": {\n     "
  },
  {
    "path": "docs/i18n/README.ar.md",
    "chars": 12144,
    "preview": "<section dir=\"rtl\">\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.com/thedotmack/claude-mem\">\n    <picture>\n     "
  },
  {
    "path": "docs/i18n/README.bn.md",
    "chars": 12807,
    "preview": "🌐 এটি একটি স্বয়ংক্রিয় অনুবাদ। সম্প্রদায়ের সংশোধন স্বাগত জানাই!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://git"
  },
  {
    "path": "docs/i18n/README.cs.md",
    "chars": 12826,
    "preview": "🌐 Toto je automatický překlad. Komunitní opravy jsou vítány!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.c"
  },
  {
    "path": "docs/i18n/README.da.md",
    "chars": 12695,
    "preview": "🌐 Dette er en automatisk oversættelse. Fællesskabsrettelser er velkomne!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"http"
  },
  {
    "path": "docs/i18n/README.de.md",
    "chars": 13373,
    "preview": "🌐 Dies ist eine automatisierte Übersetzung. Korrekturen aus der Community sind willkommen!\n\n---\n<h1 align=\"center\">\n  <b"
  },
  {
    "path": "docs/i18n/README.el.md",
    "chars": 13490,
    "preview": "🌐 Αυτή είναι μια αυτοματοποιημένη μετάφραση. Καλώς ορίζονται οι διορθώσεις από την κοινότητα!\n\n---\n<h1 align=\"center\">\n "
  },
  {
    "path": "docs/i18n/README.es.md",
    "chars": 13612,
    "preview": "🌐 Esta es una traducción automática. ¡Las correcciones de la comunidad son bienvenidas!\n\n---\n\n<h1 align=\"center\">\n  <br>"
  },
  {
    "path": "docs/i18n/README.fi.md",
    "chars": 12946,
    "preview": "🌐 Tämä on automaattinen käännös. Yhteisön korjaukset ovat tervetulleita!\n\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://"
  },
  {
    "path": "docs/i18n/README.fr.md",
    "chars": 14127,
    "preview": "🌐 Ceci est une traduction automatisée. Les corrections de la communauté sont les bienvenues !\n\n---\n<h1 align=\"center\">\n "
  },
  {
    "path": "docs/i18n/README.he.md",
    "chars": 11288,
    "preview": "🌐 זהו תרגום אוטומטי. תיקונים מהקהילה יתקבלו בברכה!\n\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.com/thedotmack/"
  },
  {
    "path": "docs/i18n/README.hi.md",
    "chars": 12595,
    "preview": "🌐 यह एक स्वचालित अनुवाद है। समुदाय से सुधार का स्वागत है!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.com/"
  },
  {
    "path": "docs/i18n/README.hu.md",
    "chars": 13341,
    "preview": "🌐 Ez egy automatikus fordítás. Közösségi javítások szívesen fogadottak!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"https"
  },
  {
    "path": "docs/i18n/README.id.md",
    "chars": 12806,
    "preview": "🌐 Ini adalah terjemahan otomatis. Koreksi dari komunitas sangat dipersilakan!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href="
  },
  {
    "path": "docs/i18n/README.it.md",
    "chars": 13557,
    "preview": "🌐 Questa è una traduzione automatica. Le correzioni della comunità sono benvenute!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a "
  },
  {
    "path": "docs/i18n/README.ja.md",
    "chars": 9795,
    "preview": "🌐 これは自動翻訳です。コミュニティによる修正を歓迎します!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.com/thedotmack/claude-mem\">\n   "
  },
  {
    "path": "docs/i18n/README.ko.md",
    "chars": 9624,
    "preview": "🌐 이것은 자동 번역입니다. 커뮤니티의 수정 제안을 환영합니다!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.com/thedotmack/claude-mem\""
  },
  {
    "path": "docs/i18n/README.nl.md",
    "chars": 12911,
    "preview": "🌐 Dit is een automatische vertaling. Gemeenschapscorrecties zijn welkom!\n\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://"
  },
  {
    "path": "docs/i18n/README.no.md",
    "chars": 12626,
    "preview": "🌐 Dette er en automatisk oversettelse. Bidrag fra fellesskapet er velkomne!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"h"
  },
  {
    "path": "docs/i18n/README.pl.md",
    "chars": 13355,
    "preview": "🌐 To jest automatyczne tłumaczenie. Korekty społeczności są mile widziane!\n\n<h1 align=\"center\">\n  <br>\n  <a href=\"https:"
  },
  {
    "path": "docs/i18n/README.pt-br.md",
    "chars": 13340,
    "preview": "🌐 Esta é uma tradução automatizada. Correções da comunidade são bem-vindas!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"h"
  },
  {
    "path": "docs/i18n/README.ro.md",
    "chars": 13263,
    "preview": "🌐 Aceasta este o traducere automată. Corecțiile din partea comunității sunt binevenite!\n\n---\n<h1 align=\"center\">\n  <br>\n"
  },
  {
    "path": "docs/i18n/README.ru.md",
    "chars": 13248,
    "preview": "🌐 Это автоматический перевод. Приветствуются исправления от сообщества!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"https"
  },
  {
    "path": "docs/i18n/README.sv.md",
    "chars": 12665,
    "preview": "🌐 Detta är en automatiserad översättning. Bidrag från gemenskapen är välkomna!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href"
  },
  {
    "path": "docs/i18n/README.th.md",
    "chars": 12021,
    "preview": "🌐 นี่คือการแปลอัตโนมัติ ยินดีต้อนรับการแก้ไขจากชุมชน!\n\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.com/thedotma"
  },
  {
    "path": "docs/i18n/README.tl.md",
    "chars": 14161,
    "preview": "🌐 Ito ay isang awtomatikong pagsasalin. Malugod na tinatanggap ang mga pagwawasto mula sa komunidad!\n\n---\n<h1 align=\"cen"
  },
  {
    "path": "docs/i18n/README.tr.md",
    "chars": 12963,
    "preview": "🌐 Bu otomatik bir çevirisidir. Topluluk düzeltmeleri memnuniyetle karşılanır!\n\n<h1 align=\"center\">\n  <br>\n  <a href=\"htt"
  },
  {
    "path": "docs/i18n/README.uk.md",
    "chars": 13100,
    "preview": "🌐 Це автоматичний переклад. Вітаються виправлення від спільноти!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://gith"
  },
  {
    "path": "docs/i18n/README.ur.md",
    "chars": 12398,
    "preview": "<section dir=\"rtl\">\n🌐 یہ ایک خودکار ترجمہ ہے۔ کمیونٹی کی اصلاحات کا خیر مقدم ہے!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a hr"
  },
  {
    "path": "docs/i18n/README.vi.md",
    "chars": 12672,
    "preview": "🌐 Đây là bản dịch tự động. Chúng tôi hoan nghênh các đóng góp từ cộng đồng!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"h"
  },
  {
    "path": "docs/i18n/README.zh-tw.md",
    "chars": 8970,
    "preview": "🌐 這是自動翻譯。歡迎社群貢獻修正!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.com/thedotmack/claude-mem\">\n    <picture>\n "
  },
  {
    "path": "docs/i18n/README.zh.md",
    "chars": 8748,
    "preview": "🌐 这是自动翻译。欢迎社区修正!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a href=\"https://github.com/thedotmack/claude-mem\">\n    <picture>\n   "
  },
  {
    "path": "docs/i18n/pt.md",
    "chars": 13451,
    "preview": "🌐 Esta é uma tradução manual por mig4ng. Correções da comunidade são bem-vindas!\n\n---\n<h1 align=\"center\">\n  <br>\n  <a hr"
  },
  {
    "path": "docs/public/CLAUDE.md",
    "chars": 2888,
    "preview": "# Claude-Mem Public Documentation\n\n## What This Folder Is\n\nThis `docs/public/` folder contains the **Mintlify documentat"
  },
  {
    "path": "docs/public/architecture/database.mdx",
    "chars": 8455,
    "preview": "---\ntitle: \"Database Architecture\"\ndescription: \"SQLite schema, FTS5 search, and data storage\"\n---\n\n# Database Architect"
  },
  {
    "path": "docs/public/architecture/hooks.mdx",
    "chars": 29696,
    "preview": "---\ntitle: \"Hook Lifecycle\"\ndescription: \"Complete guide to the 5-stage memory agent lifecycle for platform implementers"
  },
  {
    "path": "docs/public/architecture/overview.mdx",
    "chars": 10467,
    "preview": "---\ntitle: \"Architecture Overview\"\ndescription: \"System components and data flow in Claude-Mem\"\n---\n\n# Architecture Over"
  },
  {
    "path": "docs/public/architecture/pm2-to-bun-migration.mdx",
    "chars": 17235,
    "preview": "---\ntitle: \"PM2 to Bun Migration\"\ndescription: \"Complete technical documentation for the process management and database"
  },
  {
    "path": "docs/public/architecture/search-architecture.mdx",
    "chars": 13540,
    "preview": "---\ntitle: \"Search Architecture\"\ndescription: \"MCP tools with 3-layer workflow for token-efficient memory retrieval\"\n---"
  },
  {
    "path": "docs/public/architecture/worker-service.mdx",
    "chars": 14574,
    "preview": "---\ntitle: \"Worker Service\"\ndescription: \"HTTP API and Bun process management\"\n---\n\n# Worker Service\n\nThe worker service"
  },
  {
    "path": "docs/public/architecture-evolution.mdx",
    "chars": 31418,
    "preview": "---\ntitle: \"Architecture Evolution\"\ndescription: \"How claude-mem evolved from v3 to v5+\"\n---\n\n# Architecture Evolution\n\n"
  },
  {
    "path": "docs/public/beta-features.mdx",
    "chars": 5710,
    "preview": "---\ntitle: \"Beta Features\"\ndescription: \"Try experimental features like Endless Mode before they're released\"\n---\n\n# Bet"
  },
  {
    "path": "docs/public/configuration.mdx",
    "chars": 16392,
    "preview": "---\ntitle: \"Configuration\"\ndescription: \"Environment variables and settings for Claude-Mem\"\n---\n\n# Configuration\n\n## Set"
  },
  {
    "path": "docs/public/context-engineering.mdx",
    "chars": 7095,
    "preview": "---\ntitle: \"Context Engineering\"\ndescription: \"Best practices for curating optimal token sets for AI agents\"\n---\n\n# Cont"
  },
  {
    "path": "docs/public/cursor/gemini-setup.mdx",
    "chars": 4552,
    "preview": "---\ntitle: \"Cursor + Gemini Setup\"\ndescription: \"Use Claude-Mem in Cursor with Google's free Gemini API\"\n---\n\n# Cursor +"
  },
  {
    "path": "docs/public/cursor/index.mdx",
    "chars": 5422,
    "preview": "---\ntitle: \"Cursor Integration\"\ndescription: \"Persistent AI memory for Cursor IDE - free tier options available\"\n---\n\n# "
  },
  {
    "path": "docs/public/cursor/openrouter-setup.mdx",
    "chars": 4730,
    "preview": "---\ntitle: \"Cursor + OpenRouter Setup\"\ndescription: \"Use Claude-Mem in Cursor with OpenRouter's 100+ AI models\"\n---\n\n# C"
  },
  {
    "path": "docs/public/development.mdx",
    "chars": 16192,
    "preview": "---\ntitle: \"Development\"\ndescription: \"Build from source, run tests, and contribute to Claude-Mem\"\n---\n\n# Development Gu"
  },
  {
    "path": "docs/public/docs.json",
    "chars": 3615,
    "preview": "{\n  \"$schema\": \"https://mintlify.com/schema.json\",\n  \"name\": \"Claude-Mem\",\n  \"description\": \"Persistent memory compressi"
  },
  {
    "path": "docs/public/endless-mode.mdx",
    "chars": 3327,
    "preview": "---\ntitle: \"Endless Mode (Beta)\"\ndescription: \"Experimental biomimetic memory architecture for extended sessions\"\n---\n\n#"
  },
  {
    "path": "docs/public/hooks-architecture.mdx",
    "chars": 22564,
    "preview": "# How Claude-Mem Uses Hooks: A Lifecycle-Driven Architecture\n\n## Core Principle\n**Observe the main Claude Code session f"
  },
  {
    "path": "docs/public/installation.mdx",
    "chars": 3308,
    "preview": "---\ntitle: \"Installation\"\ndescription: \"Install Claude-Mem plugin for persistent memory across sessions\"\n---\n\n# Installa"
  },
  {
    "path": "docs/public/introduction.mdx",
    "chars": 4908,
    "preview": "---\ntitle: \"Introduction\"\ndescription: \"Persistent memory compression system for Claude Code\"\n---\n\n# Claude-Mem\n\n**Persi"
  },
  {
    "path": "docs/public/modes.mdx",
    "chars": 3974,
    "preview": "---\ntitle: \"Modes & Languages\"\ndescription: \"Configure Claude-Mem behavior and language with the Mode System\"\n---\n\n# Mod"
  },
  {
    "path": "docs/public/openclaw-integration.mdx",
    "chars": 14398,
    "preview": "---\ntitle: OpenClaw Integration\ndescription: Persistent memory for OpenClaw agents — observation recording, system promp"
  },
  {
    "path": "docs/public/platform-integration.mdx",
    "chars": 36638,
    "preview": "---\ntitle: Platform Integration Guide\ndescription: Complete reference for integrating claude-mem worker service into VSC"
  },
  {
    "path": "docs/public/progressive-disclosure.mdx",
    "chars": 17497,
    "preview": "# Progressive Disclosure: Claude-Mem's Context Priming Philosophy\n\n## Core Principle\n**Show what exists and its retrieva"
  },
  {
    "path": "docs/public/smart-explore-benchmark.mdx",
    "chars": 10552,
    "preview": "---\ntitle: \"Smart Explore Benchmark\"\ndescription: \"Token efficiency comparison between AST-based and traditional code ex"
  },
  {
    "path": "docs/public/troubleshooting.mdx",
    "chars": 22465,
    "preview": "---\ntitle: \"Troubleshooting\"\ndescription: \"Common issues and solutions for Claude-Mem\"\n---\n\n# Troubleshooting Guide\n\n## "
  },
  {
    "path": "docs/public/usage/claude-desktop.mdx",
    "chars": 4012,
    "preview": "---\ntitle: Claude Desktop MCP\ndescription: Use claude-mem memory search in Claude Desktop with MCP tools\nicon: desktop\n-"
  },
  {
    "path": "docs/public/usage/export-import.mdx",
    "chars": 7900,
    "preview": "---\ntitle: \"Memory Export/Import\"\ndescription: \"Share knowledge across claude-mem installations with duplicate preventio"
  },
  {
    "path": "docs/public/usage/folder-context.mdx",
    "chars": 8255,
    "preview": "---\ntitle: \"Folder Context Files\"\ndescription: \"Automatic per-folder CLAUDE.md files that provide directory-level contex"
  },
  {
    "path": "docs/public/usage/gemini-provider.mdx",
    "chars": 5728,
    "preview": "---\ntitle: \"Gemini Provider\"\ndescription: \"Use Google's Gemini API as an alternative to Claude for observation extractio"
  },
  {
    "path": "docs/public/usage/getting-started.mdx",
    "chars": 6807,
    "preview": "---\ntitle: \"Getting Started\"\ndescription: \"Learn how Claude-Mem works automatically in the background\"\n---\n\n# Getting St"
  },
  {
    "path": "docs/public/usage/manual-recovery.mdx",
    "chars": 10900,
    "preview": "---\ntitle: \"Manual Recovery\"\ndescription: \"Recover stuck observations after worker crashes or restarts\"\n---\n\n# Manual Re"
  },
  {
    "path": "docs/public/usage/openrouter-provider.mdx",
    "chars": 10852,
    "preview": "---\ntitle: \"OpenRouter Provider\"\ndescription: \"Access 100+ AI models through OpenRouter's unified API, including free mo"
  },
  {
    "path": "docs/public/usage/private-tags.mdx",
    "chars": 6343,
    "preview": "---\ntitle: \"Private Tags\"\ndescription: \"Control what gets stored in memory with privacy tags\"\n---\n\n# Private Tags\n\n## Ov"
  },
  {
    "path": "docs/public/usage/search-tools.mdx",
    "chars": 12600,
    "preview": "---\ntitle: \"Memory Search\"\ndescription: \"Search your project history with MCP tools\"\n---\n\n# Memory Search with MCP Tools"
  },
  {
    "path": "docs/reports/2026-01-02--generator-failure-investigation.md",
    "chars": 22903,
    "preview": "# Generator Failure Investigation Report\n\n**Date:** January 2, 2026\n**Session:** Anti-Pattern Cleanup Recovery\n**Status:"
  },
  {
    "path": "docs/reports/2026-01-02--observation-duplication-regression.md",
    "chars": 13534,
    "preview": "# Observation Duplication Regression - 2026-01-02\n\n## Executive Summary\n\nA critical regression is causing the same obser"
  },
  {
    "path": "docs/reports/2026-01-02--stuck-observations.md",
    "chars": 12682,
    "preview": "# Investigation Report: Stuck Observations in Processing State\n\n**Date:** January 2, 2026\n**Investigator:** Claude\n**Sta"
  },
  {
    "path": "docs/reports/2026-01-03--observation-saving-failure.md",
    "chars": 6644,
    "preview": "# Observation Saving Failure Investigation\n\n**Date**: 2026-01-03\n**Severity**: CRITICAL\n**Status**: Bugs fixed, but obse"
  },
  {
    "path": "docs/reports/2026-01-04--gemini-agent-failures.md",
    "chars": 11535,
    "preview": "# GeminiAgent Test Failures Analysis Report\n\n**Date:** 2026-01-04\n**Category:** GeminiAgent Tests\n**Total Failures:** 6 "
  },
  {
    "path": "docs/reports/2026-01-04--issue-511-gemini-model-missing.md",
    "chars": 2067,
    "preview": "# Issue #511: GeminiAgent Missing gemini-3-flash Model\n\n## Summary\n\n**Issue**: `gemini-3-flash` model missing from Gemin"
  },
  {
    "path": "docs/reports/2026-01-04--issue-514-orphaned-sessions-analysis.md",
    "chars": 11042,
    "preview": "# Issue #514: Orphaned Observer Session Files Analysis\n\n**Date:** January 4, 2026\n**Status:** PARTIALLY RESOLVED - Root "
  },
  {
    "path": "docs/reports/2026-01-04--issue-517-windows-powershell-analysis.md",
    "chars": 3726,
    "preview": "# Issue #517 Analysis: Windows PowerShell Escaping in cleanupOrphanedProcesses()\n\n**Date:** 2026-01-04\n**Version Analyze"
  },
  {
    "path": "docs/reports/2026-01-04--issue-520-stuck-messages-analysis.md",
    "chars": 8037,
    "preview": "# Issue #520: Stuck Messages Analysis\n\n**Date:** January 4, 2026\n**Status:** RESOLVED - Issue no longer exists in curren"
  },
  {
    "path": "docs/reports/2026-01-04--issue-527-uv-homebrew-analysis.md",
    "chars": 3748,
    "preview": "# Issue #527: uv Detection Fails on Apple Silicon Macs with Homebrew Installation\n\n**Date**: 2026-01-04\n**Issue**: GitHu"
  },
  {
    "path": "docs/reports/2026-01-04--issue-531-export-type-duplication.md",
    "chars": 2141,
    "preview": "# Issue #531: Export Script Type Duplication\n\n## Summary\n\n**Issue**: Reduce code duplication in export scripts with shar"
  },
  {
    "path": "docs/reports/2026-01-04--issue-532-memory-leak-analysis.md",
    "chars": 11005,
    "preview": "# Issue #532: Memory Leak in SessionManager - Analysis Report\n\n**Date**: 2026-01-04\n**Issue**: Memory leak causing 54GB+"
  },
  {
    "path": "docs/reports/2026-01-04--logger-coverage-failures.md",
    "chars": 9806,
    "preview": "# Logger Coverage Test Failures Report\n\n**Date**: 2026-01-04\n**Category**: Logger Coverage\n**Failing Tests**: 2\n**Test F"
  },
  {
    "path": "docs/reports/2026-01-04--logging-analysis-and-recommendations.md",
    "chars": 12075,
    "preview": "# Logging Analysis and Recommendations\n\n**Date**: 2026-01-04\n**Status**: CRITICAL - Current logging does not prove syste"
  },
  {
    "path": "docs/reports/2026-01-04--session-id-refactor-failures.md",
    "chars": 10205,
    "preview": "# Session ID Refactor Test Failures Analysis\n\n**Date:** 2026-01-04\n**Test File:** `tests/session_id_refactor.test.ts`\n**"
  },
  {
    "path": "docs/reports/2026-01-04--session-id-validation-failures.md",
    "chars": 12507,
    "preview": "# Session ID Usage Validation Test Failures Analysis\n\n**Report Date:** 2026-01-04\n**Test File:** `tests/session_id_usage"
  },
  {
    "path": "docs/reports/2026-01-04--session-store-failures.md",
    "chars": 9031,
    "preview": "# SessionStore Test Failures Analysis\n\n**Date:** 2026-01-04\n**Category:** SessionStore\n**Failing Tests:** 2\n**File:** `t"
  },
  {
    "path": "docs/reports/2026-01-04--test-suite-report.md",
    "chars": 7000,
    "preview": "# Test Suite Report\n\n**Date:** January 4, 2026\n**Branch:** `refactor-tests`\n**Runner:** Bun Test v1.2.20\n\n---\n\n## Summar"
  },
  {
    "path": "docs/reports/2026-01-05--PR-556-brainstorming-claude-md-distribution.md",
    "chars": 2471,
    "preview": "Brainstorming Report: CLAUDE.md Distribution Architecture\n\n  Problem Statement\n\n  The current folder-level CLAUDE.md gen"
  },
  {
    "path": "docs/reports/2026-01-05--context-hook-investigation.md",
    "chars": 2063,
    "preview": "# Context Hook Investigation Report\n\n**Date:** 2026-01-05\n**Branch:** `feature/no-more-hook-files`\n**Status:** Partial f"
  },
  {
    "path": "docs/reports/2026-01-05--issue-543-slash-command-unavailable.md",
    "chars": 9289,
    "preview": "# Issue #543 Analysis: /claude-mem Slash Command Not Available Despite Installation\n\n**Date:** 2026-01-05\n**Version Anal"
  },
  {
    "path": "docs/reports/2026-01-05--issue-544-mem-search-hint-claude-code.md",
    "chars": 13910,
    "preview": "# Investigation Report: Issue #544 - mem-search Skill Hint Shown to Claude Code Users\n\n**Date:** 2026-01-05\n**Issue:** h"
  },
  {
    "path": "docs/reports/2026-01-05--issue-545-formattool-json-parse-crash.md",
    "chars": 7085,
    "preview": "# Issue #545: formatTool Crashes on Non-JSON Tool Input Strings\n\n## Summary\n\n**Issue**: `formatTool` method in `src/util"
  },
  {
    "path": "docs/reports/2026-01-05--issue-555-windows-hooks-ipc-false.md",
    "chars": 9062,
    "preview": "# Issue #555 Analysis: Windows Hooks Not Executing - hasIpc Always False\n\n**Date:** 2026-01-05\n**Version Analyzed:** 8.5"
  },
  {
    "path": "docs/reports/2026-01-05--issue-557-settings-module-loader-error.md",
    "chars": 11168,
    "preview": "# Investigation Report: Issue #557 - Plugin Fails to Start\n\n**Date:** January 5, 2026\n**Issue:** [#557](https://github.c"
  },
  {
    "path": "docs/reports/2026-01-06--windows-woes-comprehensive-report.md",
    "chars": 10428,
    "preview": "# Windows Woes: Comprehensive Report\n\n**Date:** 2026-01-06\n**Coverage:** October 2025 - January 2026\n**Memory Sources:**"
  },
  {
    "path": "docs/reports/2026-01-07--all-open-issues-explained.md",
    "chars": 8440,
    "preview": "# All Open Issues Explained\n\n*Generated: January 7, 2026*\n\nThis report provides plain English explanations of all 12 ope"
  },
  {
    "path": "docs/reports/2026-01-07--open-issues-summary.md",
    "chars": 3197,
    "preview": "# Open Issues Summary - January 7, 2026\n\nThis document provides an index of all open GitHub issues analyzed on 2026-01-0"
  },
  {
    "path": "docs/reports/2026-01-10--anti-pattern-czar-generalization-analysis.md",
    "chars": 7815,
    "preview": "# Anti-Pattern Czar Generalization Analysis\n\n*Generated: January 10, 2026*\n\nThis report analyzes whether the `/anti-patt"
  },
  {
    "path": "docs/reports/intentional-patterns-validation.md",
    "chars": 9244,
    "preview": "# Intentional Patterns Validation Report\n\n**Generated:** 2026-01-13\n**Purpose:** Validate whether \"intentional\" patterns"
  },
  {
    "path": "docs/reports/issue-586-feature-request-unknown.md",
    "chars": 16510,
    "preview": "# Issue #586: Race Condition in memory_session_id Capture\n\n**Report Date:** 2026-01-07\n**Issue:** [#586](https://github."
  },
  {
    "path": "docs/reports/issue-587-observations-not-stored.md",
    "chars": 13539,
    "preview": "# Technical Report: Issue #587 - Observations Not Being Stored\n\n**Issue:** v9.0.0: Observations not being stored - SDK a"
  },
  {
    "path": "docs/reports/issue-588-api-key-usage-warning.md",
    "chars": 14008,
    "preview": "# Issue #588: Unexpected API Charges from ANTHROPIC_API_KEY Discovery\n\n**Date:** January 7, 2026\n**Status:** INVESTIGATI"
  },
  {
    "path": "docs/reports/issue-590-windows-chroma-terminal-popup.md",
    "chars": 11861,
    "preview": "# Issue #590: Blank Terminal Window Pops Up on Windows When Chroma MCP Server Starts\n\n**Date:** 2026-01-07\n**Issue Autho"
  },
  {
    "path": "docs/reports/issue-591-openrouter-memorysessionid-capture.md",
    "chars": 14072,
    "preview": "# Issue #591: OpenRouter Agent Fails to Capture memorySessionId for Empty Prompt History Sessions\n\n**Report Date:** 2026"
  },
  {
    "path": "docs/reports/issue-596-processtransport-not-ready.md",
    "chars": 13061,
    "preview": "# Issue #596: ProcessTransport is not ready for writing - Generator aborted on every observation\n\n**Date:** 2026-01-07\n*"
  },
  {
    "path": "docs/reports/issue-597-too-many-bugs.md",
    "chars": 9971,
    "preview": "# Issue #597: Too Many Bugs - Technical Analysis Report\n\n**Date:** 2026-01-07\n**Issue:** [#597](https://github.com/thedo"
  },
  {
    "path": "docs/reports/issue-598-conversation-history-pollution.md",
    "chars": 12956,
    "preview": "# Issue #598: Conversation History Pollution - Technical Analysis Report\n\n**Issue:** Too many messages, polluting my con"
  },
  {
    "path": "docs/reports/issue-599-windows-drive-root-400-error.md",
    "chars": 10765,
    "preview": "# Technical Report: Issue #599 - Windows Drive Root 400 Error\n\n**Issue:** [#599](https://github.com/thedotmack/claude-me"
  },
  {
    "path": "docs/reports/issue-600-documentation-audit-features-not-implemented.md",
    "chars": 14622,
    "preview": "# Issue #600: Documentation Audit - Features Documented But Not Implemented\n\n**Report Date:** 2026-01-07\n**Issue Author:"
  },
  {
    "path": "docs/reports/issue-602-posttooluse-worker-service-failed.md",
    "chars": 14294,
    "preview": "# Issue #602: PostToolUse Error - Worker Service Failed to Start (Windows)\n\n**Report Date:** 2026-01-07\n**Issue Author:*"
  },
  {
    "path": "docs/reports/issue-603-worker-daemon-leaks-child-processes.md",
    "chars": 14146,
    "preview": "# Technical Report: Worker Daemon Child Process Leak\n\n**Issue:** #603 - Bug: worker-service daemon leaks child claude pr"
  },
  {
    "path": "docs/reports/log-level-audit.txt",
    "chars": 89630,
    "preview": "bun test v1.2.20 (6ad208bc)\n\n=== LOG LEVEL AUDIT REPORT ===\n\nTotal logger calls found: 437\n\n\nERROR (should be critical f"
  },
  {
    "path": "docs/reports/nonsense-logic.md",
    "chars": 11812,
    "preview": "# Unjustified Logic Report - worker-service.ts\n\n**Generated:** 2026-01-13\n**Source:** `src/services/worker-service.ts` ("
  },
  {
    "path": "install/.gitignore",
    "chars": 27,
    "preview": ".vercel\npublic/openclaw.sh\n"
  },
  {
    "path": "install/public/install.sh",
    "chars": 1598,
    "preview": "#!/bin/bash\nset -euo pipefail\n\n# claude-mem installer bootstrap\n# Usage: curl -fsSL https://install.cmem.ai | bash\n#   o"
  },
  {
    "path": "install/public/installer.js",
    "chars": 95540,
    "preview": "#!/usr/bin/env node\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.g"
  },
  {
    "path": "install/vercel.json",
    "chars": 607,
    "preview": "{\n  \"$schema\": \"https://openapi.vercel.sh/vercel.json\",\n  \"rewrites\": [\n    { \"source\": \"/\", \"destination\": \"/install.sh"
  },
  {
    "path": "installer/build.mjs",
    "chars": 297,
    "preview": "import { build } from 'esbuild';\n\nawait build({\n  entryPoints: ['src/index.ts'],\n  bundle: true,\n  format: 'esm',\n  plat"
  },
  {
    "path": "installer/dist/index.js",
    "chars": 95540,
    "preview": "#!/usr/bin/env node\nvar __create = Object.create;\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.g"
  },
  {
    "path": "installer/package.json",
    "chars": 489,
    "preview": "{\n  \"name\": \"claude-mem-installer\",\n  \"version\": \"1.0.0\",\n  \"type\": \"module\",\n  \"bin\": { \"claude-mem-installer\": \"./dist"
  },
  {
    "path": "installer/src/index.ts",
    "chars": 1656,
    "preview": "import * as p from '@clack/prompts';\nimport { runWelcome } from './steps/welcome.js';\nimport { runDependencyChecks } fro"
  },
  {
    "path": "installer/src/steps/complete.ts",
    "chars": 1995,
    "preview": "import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport type { ProviderConfig } from './provider.js';\ni"
  },
  {
    "path": "installer/src/steps/dependencies.ts",
    "chars": 5081,
    "preview": "import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { findBinary, compareVersions, installBun, inst"
  },
  {
    "path": "installer/src/steps/ide-selection.ts",
    "chars": 895,
    "preview": "import * as p from '@clack/prompts';\n\nexport type IDE = 'claude-code' | 'cursor';\n\nexport async function runIdeSelection"
  },
  {
    "path": "installer/src/steps/install.ts",
    "chars": 5413,
    "preview": "import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { execSync } from 'child_process';\nimport { exi"
  },
  {
    "path": "installer/src/steps/provider.ts",
    "chars": 3921,
    "preview": "import * as p from '@clack/prompts';\nimport pc from 'picocolors';\n\nexport type ProviderType = 'claude' | 'gemini' | 'ope"
  },
  {
    "path": "installer/src/steps/settings.ts",
    "chars": 5177,
    "preview": "import * as p from '@clack/prompts';\nimport pc from 'picocolors';\n\nexport interface SettingsConfig {\n  workerPort: strin"
  },
  {
    "path": "installer/src/steps/welcome.ts",
    "chars": 1511,
    "preview": "import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { existsSync } from 'fs';\nimport { expandHome }"
  },
  {
    "path": "installer/src/steps/worker.ts",
    "chars": 2393,
    "preview": "import * as p from '@clack/prompts';\nimport pc from 'picocolors';\nimport { spawn } from 'child_process';\nimport { join }"
  },
  {
    "path": "installer/src/utils/dependencies.ts",
    "chars": 2257,
    "preview": "import { existsSync } from 'fs';\nimport { execSync } from 'child_process';\nimport { commandExists, runCommand, expandHom"
  },
  {
    "path": "installer/src/utils/settings-writer.ts",
    "chars": 3117,
    "preview": "import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { homedir }"
  },
  {
    "path": "installer/src/utils/system.ts",
    "chars": 1253,
    "preview": "import { execSync } from 'child_process';\nimport { homedir } from 'os';\nimport { join } from 'path';\n\nexport type OSType"
  },
  {
    "path": "installer/tsconfig.json",
    "chars": 404,
    "preview": "{\n  \"compilerOptions\": {\n    \"module\": \"ESNext\",\n    \"target\": \"ES2022\",\n    \"moduleResolution\": \"bundler\",\n    \"esModul"
  },
  {
    "path": "openclaw/.gitignore",
    "chars": 20,
    "preview": "node_modules/\ndist/\n"
  },
  {
    "path": "openclaw/Dockerfile.e2e",
    "chars": 2507,
    "preview": "# Dockerfile.e2e — End-to-end test: install claude-mem plugin on a real OpenClaw instance\n# Simulates the complete plugi"
  },
  {
    "path": "openclaw/SKILL.md",
    "chars": 15687,
    "preview": "# Claude-Mem OpenClaw Plugin — Setup Guide\n\nThis guide walks through setting up the claude-mem plugin on an OpenClaw gat"
  },
  {
    "path": "openclaw/TESTING.md",
    "chars": 6656,
    "preview": "# OpenClaw Claude-Mem Plugin — Testing Guide\n\n## Quick Start (Docker)\n\nThe fastest way to test the plugin is using the p"
  },
  {
    "path": "openclaw/e2e-verify.sh",
    "chars": 6969,
    "preview": "#!/usr/bin/env bash\n# e2e-verify.sh — Automated E2E verification for claude-mem plugin on OpenClaw\n#\n# This script verif"
  },
  {
    "path": "openclaw/install.sh",
    "chars": 62982,
    "preview": "#!/usr/bin/env bash\nset -euo pipefail\n\n# claude-mem OpenClaw Plugin Installer\n# Installs the claude-mem persistent memor"
  },
  {
    "path": "openclaw/openclaw.plugin.json",
    "chars": 3621,
    "preview": "{\n  \"id\": \"claude-mem\",\n  \"name\": \"Claude-Mem (Persistent Memory)\",\n  \"description\": \"Official OpenClaw plugin for Claud"
  },
  {
    "path": "openclaw/package.json",
    "chars": 373,
    "preview": "{\n  \"name\": \"@openclaw/claude-mem\",\n  \"version\": \"1.0.0\",\n  \"private\": true,\n  \"type\": \"module\",\n  \"main\": \"dist/index.j"
  },
  {
    "path": "openclaw/src/index.test.ts",
    "chars": 35764,
    "preview": "import { describe, it, beforeEach, afterEach } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { creat"
  },
  {
    "path": "openclaw/src/index.ts",
    "chars": 36625,
    "preview": "// No file-system imports needed — context is injected via system prompt hook,\n// not by writing to MEMORY.md.\n\n// Minim"
  },
  {
    "path": "openclaw/test-e2e.sh",
    "chars": 1492,
    "preview": "#!/usr/bin/env bash\n# test-e2e.sh — Run E2E test of claude-mem plugin on real OpenClaw\n#\n# Usage:\n#   ./test-e2e.sh     "
  },
  {
    "path": "openclaw/test-install.sh",
    "chars": 72993,
    "preview": "#!/usr/bin/env bash\nset -euo pipefail\n\n# Test suite for openclaw/install.sh functions\n# Tests the OpenClaw gateway detec"
  },
  {
    "path": "openclaw/test-sse-consumer.js",
    "chars": 3123,
    "preview": "/**\n * Smoke test for OpenClaw claude-mem plugin registration.\n * Validates the plugin structure works independently of "
  },
  {
    "path": "openclaw/tsconfig.json",
    "chars": 544,
    "preview": "{\n  \"compilerOptions\": {\n    \"target\": \"ES2022\",\n    \"module\": \"ESNext\",\n    \"moduleResolution\": \"node\",\n    \"lib\": [\"ES"
  },
  {
    "path": "package.json",
    "chars": 4968,
    "preview": "{\n  \"name\": \"claude-mem\",\n  \"version\": \"10.6.3\",\n  \"description\": \"Memory compression system for Claude Code - persist c"
  },
  {
    "path": "plugin/.claude-plugin/CLAUDE.md",
    "chars": 517,
    "preview": "<claude-mem-context>\n# Recent Activity\n\n### Nov 6, 2025\n\n| ID | Time | T | Title | Read |\n|----|------|---|-------|-----"
  },
  {
    "path": "plugin/.claude-plugin/plugin.json",
    "chars": 379,
    "preview": "{\n  \"name\": \"claude-mem\",\n  \"version\": \"10.6.3\",\n  \"description\": \"Persistent memory system for Claude Code - seamlessly"
  },
  {
    "path": "plugin/CLAUDE.md",
    "chars": 214,
    "preview": "<claude-mem-context>\n# Recent Activity\n\n### Jan 10, 2026\n\n| ID | Time | T | Title | Read |\n|----|------|---|-------|----"
  },
  {
    "path": "plugin/hooks/CLAUDE.md",
    "chars": 1073,
    "preview": "<claude-mem-context>\n# Recent Activity\n\n### Oct 25, 2025\n\n| ID | Time | T | Title | Read |\n|----|------|---|-------|----"
  },
  {
    "path": "plugin/hooks/bugfixes-2026-01-10.md",
    "chars": 3655,
    "preview": "# Bugfix Sprint: 2026-01-10\n\n## Critical Priority (Blocks Users)\n\n### #646 - Plugin bricks Claude Code - stdin fstat EIN"
  },
  {
    "path": "plugin/hooks/hooks.json",
    "chars": 3204,
    "preview": "{\n  \"description\": \"Claude-mem memory system hooks\",\n  \"hooks\": {\n    \"Setup\": [\n      {\n        \"matcher\": \"*\",\n       "
  },
  {
    "path": "plugin/modes/code--ar.json",
    "chars": 2869,
    "preview": "{\n  \"name\": \"Code Development (Arabic)\",\n  \"prompts\": {\n    \"footer\": \"IMPORTANT! DO NOT do any work right now other tha"
  },
  {
    "path": "plugin/modes/code--bn.json",
    "chars": 3000,
    "preview": "{\n  \"name\": \"Code Development (Bengali)\",\n  \"prompts\": {\n    \"footer\": \"IMPORTANT! DO NOT do any work right now other th"
  },
  {
    "path": "plugin/modes/code--chill.json",
    "chars": 1836,
    "preview": "{\n  \"name\": \"Code Development (Chill)\",\n  \"prompts\": {\n    \"recording_focus\": \"WHAT TO RECORD (SELECTIVE MODE)\\n--------"
  }
]

// ... and 389 more files (download for full content)

About this extraction

This page contains the full source code of the thedotmack/claude-mem GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 589 files (67.4 MB), approximately 1.8M tokens, and a symbol index with 6898 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!