Add memory plugin with semantic search and session planning#145
Add memory plugin with semantic search and session planning#145chriswritescode-dev merged 2 commits intomainfrom
Conversation
| } | ||
|
|
||
| function normalizeBaseUrl(baseUrl: string): string { | ||
| const trimmed = baseUrl.replace(/\/+$/, '') |
Check failure
Code scanning / CodeQL
Polynomial regular expression used on uncontrolled data High
| store.delete(key) | ||
| }, | ||
| async invalidatePattern(pattern: string): Promise<void> { | ||
| const regex = new RegExp(pattern.replace('*', '.*')) |
Check failure
Code scanning / CodeQL
Incomplete string escaping or encoding High test
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI about 17 hours ago
To fix this, we should (a) ensure all * characters are handled, not just the first, and (b) avoid letting other characters in pattern be interpreted as regex metacharacters unless explicitly intended. The most robust approach is to escape the entire pattern for use inside a RegExp, then specifically transform escaped \* into .* and apply the g flag when replacing, so that every * becomes a wildcard segment and all other characters are treated literally.
Concretely, in packages/memory/test/memory-service.test.ts, inside createMockCache, change the invalidatePattern implementation. Replace new RegExp(pattern.replace('*', '.*')) with logic that:
- Escapes regex metacharacters in
patternusing a small helper. - Replaces all escaped
\*with.*using a global regex. - Constructs a
RegExpfrom the resulting string.
Because we’re in a test file and can freely define small helpers, we can add a local escapeRegex function above createMockCache. No external dependencies are required, and behavior for existing single-* patterns will be preserved, while multi-* patterns will now work correctly.
| @@ -32,6 +32,11 @@ | ||
| } | ||
| } | ||
|
|
||
| function escapeRegex(input: string): string { | ||
| // Escape characters that have special meaning in regular expressions | ||
| return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') | ||
| } | ||
|
|
||
| function createMockCache(): CacheService { | ||
| const store = new Map<string, { value: unknown; expiry: number }>() | ||
|
|
||
| @@ -53,7 +58,11 @@ | ||
| store.delete(key) | ||
| }, | ||
| async invalidatePattern(pattern: string): Promise<void> { | ||
| const regex = new RegExp(pattern.replace('*', '.*')) | ||
| // Treat pattern as a glob where '*' matches any sequence of characters. | ||
| // First escape regex metacharacters, then turn escaped '*' into '.*'. | ||
| const escaped = escapeRegex(pattern) | ||
| const regexPattern = escaped.replace(/\\\*/g, '.*') | ||
| const regex = new RegExp(regexPattern) | ||
| for (const key of store.keys()) { | ||
| if (regex.test(key)) { | ||
| store.delete(key) |
12ff8aa to
cc0339f
Compare
Summary
@opencode-manager/memory— a new workspace package that acts as an OpenCode plugin, providing semantic memory storage and retrieval via vector embeddings (localall-MiniLM-L6-v2, OpenAI, or Voyage AI)/memory), frontendMemoriespage,MemoryPluginConfigsettings UI, and shared Zod schemas and types to integrate the plugin with the web UIChanges
New Package:
@opencode-manager/memorysrc/index.ts— Plugin entry point with setup, hooks, tools, and agentssrc/embedding/— Local and API-based embedding providers with server-side syncsrc/storage/— SQLite + vector store (vec) implementations with metadata queriessrc/services/— Memory service with deduplication, session state management, embedding syncsrc/hooks/— Keyword, session, and compaction hooks for memory lifecyclesrc/agents/— Code agent with memory-aware context injection for code review tasksBackend
/memoryroutes for CRUD, search, planning state, and embedding sync@opencode-manager/memoryFrontend
Memoriespage with list and form dialog for managing memoriesMemoryPluginConfigcomponent in Settings for plugin configurationuseMemorieshook for API integrationRepoDetailto show memory plugin statusTesting
packages/memory/test/covering all major modulesScope
116 files changed, ~11,240 insertions, ~1,226 deletions