@prmichaelsen/remember-mcp 2.6.7 → 2.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,41 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.6.8] - 2026-02-17
9
+
10
+ ### 🐛 Fixed
11
+
12
+ - **Critical Build Error**: Added missing `poetry` content type metadata to `src/constants/content-types.ts`
13
+ - Fixed TypeScript compilation error: "Property 'poetry' is missing in type Record<ContentType, ContentTypeMetadata>"
14
+ - Added poetry definition with category, description, examples, and common fields
15
+ - Updated `CONTENT_TYPE_CATEGORIES` to include poetry in creative category
16
+ - Build now successful
17
+
18
+ ### ✨ Added
19
+
20
+ - **Task 66: Comment Field Initialization in Tools**
21
+ - Updated `remember_create_memory` tool to initialize comment fields
22
+ - Added `parent_id`, `thread_root_id`, `moderation_flags` to `CreateMemoryArgs` interface
23
+ - New memories created with `parent_id: null`, `thread_root_id: null`, `moderation_flags: []`
24
+ - Updated `remember_update_memory` tool to support comment field updates
25
+ - Added comment fields to tool schema and `UpdateMemoryArgs` interface
26
+ - Can now update `parent_id`, `thread_root_id`, and `moderation_flags`
27
+ - Space memory tools automatically include comment fields via spread operator
28
+ - Created task documentation: `agent/tasks/task-66-initialize-comment-fields-in-tools.md`
29
+
30
+ ### 📝 Changed
31
+
32
+ - Updated `agent/progress.yaml` with Task 66 completion and build fix details
33
+ - All new memories now have consistent schema with comment fields initialized
34
+
35
+ ### 🎯 Impact
36
+
37
+ - **Schema Consistency**: All new memories have comment fields, matching migrated old memories
38
+ - **Comment System Ready**: Can create comments, nested comments, and manage moderation flags
39
+ - **Build Stability**: TypeScript compiles without errors, all 81 tests passing
40
+
41
+ ---
42
+
8
43
  ## [2.6.6] - 2026-02-16
9
44
 
10
45
  ### 🔧 Improved
@@ -523,6 +523,42 @@ progress:
523
523
  overall: 50%
524
524
 
525
525
  recent_work:
526
+ - date: 2026-02-17
527
+ description: Fixed Build Error & Completed Task 66 - Comment Field Initialization
528
+ items:
529
+ - ✅ Fixed critical TypeScript build error in content-types.ts
530
+ - ✅ Added missing 'poetry' content type metadata
531
+ - ✅ Build now successful - TypeScript compiles without errors
532
+ - ✅ Task 66 COMPLETED: Initialize comment fields in create/update tools
533
+ - ✅ Updated remember_create_memory tool schema with comment fields
534
+ - ✅ Updated CreateMemoryArgs interface with parent_id, thread_root_id, moderation_flags
535
+ - ✅ Initialized comment fields to defaults in handleCreateMemory (null, null, [])
536
+ - ✅ Updated remember_update_memory tool schema with comment fields
537
+ - ✅ Updated UpdateMemoryArgs interface with comment fields
538
+ - ✅ Added comment field update logic in handleUpdateMemory
539
+ - ✅ All 81 tests passing (1 skipped integration test)
540
+ - ✅ Test coverage: 33.12% overall
541
+ - ✅ New memories now created with comment fields initialized
542
+ - ✅ Can create comments with parent_id and thread_root_id set
543
+ - ✅ Can update comment fields via remember_update_memory
544
+ - 📋 Ready for M12 completion: Tasks 58-59 remaining
545
+
546
+ - date: 2026-02-17
547
+ description: ACP Initialization Complete - Project Context Loaded
548
+ items:
549
+ - ✅ ACP initialization workflow executed via @acp.init command
550
+ - ⚠️ ACP updates available (v1.4.3 with improved script color output)
551
+ - ✅ All agent documentation reviewed (23 design docs, 11 milestones, 66 tasks, 5 patterns)
552
+ - ✅ Project status verified: M1-M4, M10-M11 complete (100%), M12 in progress (60%)
553
+ - ✅ Version 2.6.7 confirmed (latest release)
554
+ - ✅ 53 unit tests passing (1 skipped integration test)
555
+ - ⚠️ TypeScript compilation error: Missing 'poetry' in content-types.ts
556
+ - ✅ All 17 MCP tools implemented and working
557
+ - ✅ M12 Comment System: 3/5 tasks complete (schema, search, query updates)
558
+ - 📋 Remaining M12 tasks: Task 58 (unit tests), Task 59 (documentation)
559
+ - 📋 Build blocked by TypeScript error in content-types.ts
560
+ - 📋 Need to fix 'poetry' content type metadata
561
+
526
562
  - date: 2026-02-16
527
563
  description: Comment System, Structured Logging, and Safety Guidelines (v2.6.0-v2.6.2)
528
564
  items:
@@ -0,0 +1,431 @@
1
+ # Task 65: Migrate Old Memories to Include New Schema Fields
2
+
3
+ **Milestone**: M12 (Schema Migration)
4
+ **Estimated Time**: 3 hours
5
+ **Dependencies**: Task 63 (fetchMemoryWithAllProperties utility)
6
+ **Status**: Not Started
7
+ **Priority**: CRITICAL 🚨
8
+
9
+ ---
10
+
11
+ ## Objective
12
+
13
+ Migrate all existing memories in user collections to include new schema fields added in v2.6.0 (comment fields) and ensure schema uniformity. This prevents fetch failures when requesting properties that don't exist on old memory objects.
14
+
15
+ ---
16
+
17
+ ## Context
18
+
19
+ **Problem**:
20
+ Old memories created before v2.6.0 don't have the new comment fields:
21
+ - `parent_id` (added in v2.6.0)
22
+ - `thread_root_id` (added in v2.6.0)
23
+ - `moderation_flags` (added in v2.6.0)
24
+
25
+ When `fetchMemoryWithAllProperties()` tries to fetch these properties from old memories, Weaviate fails because the properties don't exist on those objects.
26
+
27
+ **Impact**:
28
+ - ❌ Cannot publish old memories (fetch fails)
29
+ - ❌ Cannot update old memories
30
+ - ❌ Cannot search old memories with new property filters
31
+ - ❌ Schema inconsistency across memory objects
32
+
33
+ **Root Cause**:
34
+ Weaviate doesn't automatically backfill new schema properties on existing objects. When you add a new property to the schema, existing objects don't get that property until they're updated.
35
+
36
+ ---
37
+
38
+ ## Steps
39
+
40
+ ### 1. Create Migration Script
41
+
42
+ Create a migration script in `/home/prmichaelsen/scripts/`:
43
+
44
+ ```bash
45
+ #!/bin/bash
46
+ # migrate-memory-schema.sh
47
+ # Migrates old memories to include new schema fields
48
+
49
+ set -e
50
+
51
+ echo "🔄 Starting memory schema migration..."
52
+ echo "This will add missing fields to all memories in all user collections"
53
+ echo ""
54
+
55
+ # Run the TypeScript migration script
56
+ cd /home/prmichaelsen/remember-mcp
57
+ npx tsx scripts/migrate-schema.ts
58
+
59
+ echo ""
60
+ echo "✅ Migration complete!"
61
+ ```
62
+
63
+ ### 2. Create TypeScript Migration Script
64
+
65
+ Create `scripts/migrate-schema.ts`:
66
+
67
+ ```typescript
68
+ /**
69
+ * Schema Migration Script
70
+ *
71
+ * Adds missing fields to all existing memories:
72
+ * - parent_id: null (for non-comment memories)
73
+ * - thread_root_id: null (for non-comment memories)
74
+ * - moderation_flags: [] (empty array)
75
+ */
76
+
77
+ import { initWeaviateClient, getWeaviateClient } from '../src/weaviate/client.js';
78
+ import { config } from '../src/config.js';
79
+
80
+ interface MigrationStats {
81
+ collectionsProcessed: number;
82
+ memoriesUpdated: number;
83
+ memoriesSkipped: number;
84
+ errors: number;
85
+ }
86
+
87
+ async function migrateCollection(collectionName: string): Promise<{ updated: number; skipped: number; errors: number }> {
88
+ console.log(`\n📦 Processing collection: ${collectionName}`);
89
+
90
+ const client = getWeaviateClient();
91
+ const collection = client.collections.get(collectionName);
92
+
93
+ let updated = 0;
94
+ let skipped = 0;
95
+ let errors = 0;
96
+
97
+ try {
98
+ // Fetch all objects in batches
99
+ let offset = 0;
100
+ const batchSize = 100;
101
+ let hasMore = true;
102
+
103
+ while (hasMore) {
104
+ console.log(` Fetching batch at offset ${offset}...`);
105
+
106
+ const results = await collection.query.fetchObjects({
107
+ limit: batchSize,
108
+ offset,
109
+ });
110
+
111
+ if (!results.objects || results.objects.length === 0) {
112
+ hasMore = false;
113
+ break;
114
+ }
115
+
116
+ console.log(` Processing ${results.objects.length} memories...`);
117
+
118
+ for (const obj of results.objects) {
119
+ try {
120
+ const props = obj.properties;
121
+
122
+ // Check if migration needed
123
+ const needsMigration =
124
+ props.parent_id === undefined ||
125
+ props.thread_root_id === undefined ||
126
+ props.moderation_flags === undefined;
127
+
128
+ if (!needsMigration) {
129
+ skipped++;
130
+ continue;
131
+ }
132
+
133
+ // Update with missing fields
134
+ await collection.data.update({
135
+ id: obj.uuid,
136
+ properties: {
137
+ parent_id: props.parent_id ?? null,
138
+ thread_root_id: props.thread_root_id ?? null,
139
+ moderation_flags: props.moderation_flags ?? [],
140
+ },
141
+ });
142
+
143
+ updated++;
144
+
145
+ if (updated % 10 === 0) {
146
+ console.log(` ✅ Updated ${updated} memories...`);
147
+ }
148
+ } catch (error) {
149
+ errors++;
150
+ console.error(` ❌ Error updating ${obj.uuid}:`, error);
151
+ }
152
+ }
153
+
154
+ offset += batchSize;
155
+ }
156
+ } catch (error) {
157
+ console.error(` ❌ Error processing collection:`, error);
158
+ errors++;
159
+ }
160
+
161
+ return { updated, skipped, errors };
162
+ }
163
+
164
+ async function main() {
165
+ console.log('🚀 Memory Schema Migration');
166
+ console.log('==========================\n');
167
+
168
+ // Initialize Weaviate
169
+ await initWeaviateClient();
170
+ const client = getWeaviateClient();
171
+
172
+ // Get all collections
173
+ const collections = await client.collections.listAll();
174
+
175
+ // Filter to Memory_ collections only
176
+ const memoryCollections = collections
177
+ .map(c => c.name)
178
+ .filter(name => name.startsWith('Memory_') && name !== 'Memory_public');
179
+
180
+ console.log(`Found ${memoryCollections.length} user memory collections\n`);
181
+
182
+ const stats: MigrationStats = {
183
+ collectionsProcessed: 0,
184
+ memoriesUpdated: 0,
185
+ memoriesSkipped: 0,
186
+ errors: 0,
187
+ };
188
+
189
+ // Migrate each collection
190
+ for (const collectionName of memoryCollections) {
191
+ const result = await migrateCollection(collectionName);
192
+ stats.collectionsProcessed++;
193
+ stats.memoriesUpdated += result.updated;
194
+ stats.memoriesSkipped += result.skipped;
195
+ stats.errors += result.errors;
196
+ }
197
+
198
+ // Also migrate Memory_public if it exists
199
+ const publicExists = await client.collections.exists('Memory_public');
200
+ if (publicExists) {
201
+ console.log('\n📦 Processing Memory_public collection...');
202
+ const result = await migrateCollection('Memory_public');
203
+ stats.collectionsProcessed++;
204
+ stats.memoriesUpdated += result.updated;
205
+ stats.memoriesSkipped += result.skipped;
206
+ stats.errors += result.errors;
207
+ }
208
+
209
+ // Print summary
210
+ console.log('\n\n📊 Migration Summary');
211
+ console.log('===================');
212
+ console.log(`Collections processed: ${stats.collectionsProcessed}`);
213
+ console.log(`Memories updated: ${stats.memoriesUpdated}`);
214
+ console.log(`Memories skipped (already migrated): ${stats.memoriesSkipped}`);
215
+ console.log(`Errors: ${stats.errors}`);
216
+
217
+ if (stats.errors > 0) {
218
+ console.log('\n⚠️ Some errors occurred. Check logs above.');
219
+ process.exit(1);
220
+ } else {
221
+ console.log('\n✅ Migration completed successfully!');
222
+ process.exit(0);
223
+ }
224
+ }
225
+
226
+ main().catch(error => {
227
+ console.error('💥 Migration failed:', error);
228
+ process.exit(1);
229
+ });
230
+ ```
231
+
232
+ ### 3. Make Script Executable
233
+
234
+ ```bash
235
+ chmod +x /home/prmichaelsen/scripts/migrate-memory-schema.sh
236
+ ```
237
+
238
+ ### 4. Run Migration
239
+
240
+ ```bash
241
+ # Dry run first (optional - add --dry-run flag to script)
242
+ /home/prmichaelsen/scripts/migrate-memory-schema.sh
243
+
244
+ # Or run directly with tsx
245
+ cd /home/prmichaelsen/remember-mcp
246
+ npx tsx scripts/migrate-schema.ts
247
+ ```
248
+
249
+ ### 5. Verify Migration
250
+
251
+ Check that old memories now have the new fields:
252
+
253
+ ```typescript
254
+ // Test with an old memory ID
255
+ remember_search_memory({
256
+ query: "",
257
+ limit: 1
258
+ })
259
+
260
+ // Verify returned memory has:
261
+ // - parent_id: null
262
+ // - thread_root_id: null
263
+ // - moderation_flags: []
264
+ ```
265
+
266
+ ### 6. Test Publish After Migration
267
+
268
+ ```bash
269
+ # Try publishing an old memory
270
+ remember_publish({
271
+ memory_id: "84edf86d-579d-4cb3-8b5f-2e19462d8c68",
272
+ spaces: ["the_void"]
273
+ })
274
+
275
+ # Should succeed now
276
+ ```
277
+
278
+ ---
279
+
280
+ ## Verification
281
+
282
+ - [ ] Migration script created in `/home/prmichaelsen/scripts/`
283
+ - [ ] TypeScript migration script created in `scripts/migrate-schema.ts`
284
+ - [ ] Script is executable
285
+ - [ ] Dry run completed successfully (optional)
286
+ - [ ] Migration executed on all user collections
287
+ - [ ] Migration executed on Memory_public collection
288
+ - [ ] All old memories have `parent_id: null`
289
+ - [ ] All old memories have `thread_root_id: null`
290
+ - [ ] All old memories have `moderation_flags: []`
291
+ - [ ] Can fetch old memories with `fetchMemoryWithAllProperties()`
292
+ - [ ] Can publish old memories successfully
293
+ - [ ] No errors in migration logs
294
+
295
+ ---
296
+
297
+ ## Expected Output
298
+
299
+ **Before Migration**:
300
+ ```json
301
+ {
302
+ "id": "84edf86d-579d-4cb3-8b5f-2e19462d8c68",
303
+ "properties": {
304
+ "title": "Cat grad school",
305
+ "content": "...",
306
+ "type": "note",
307
+ // ❌ No parent_id
308
+ // ❌ No thread_root_id
309
+ // ❌ No moderation_flags
310
+ }
311
+ }
312
+ ```
313
+
314
+ **After Migration**:
315
+ ```json
316
+ {
317
+ "id": "84edf86d-579d-4cb3-8b5f-2e19462d8c68",
318
+ "properties": {
319
+ "title": "Cat grad school",
320
+ "content": "...",
321
+ "type": "note",
322
+ "parent_id": null, // ✅ Added
323
+ "thread_root_id": null, // ✅ Added
324
+ "moderation_flags": [] // ✅ Added
325
+ }
326
+ }
327
+ ```
328
+
329
+ ---
330
+
331
+ ## Migration Statistics Example
332
+
333
+ ```
334
+ 📊 Migration Summary
335
+ ===================
336
+ Collections processed: 5
337
+ Memories updated: 247
338
+ Memories skipped (already migrated): 0
339
+ Errors: 0
340
+
341
+ ✅ Migration completed successfully!
342
+ ```
343
+
344
+ ---
345
+
346
+ ## Common Issues and Solutions
347
+
348
+ ### Issue 1: Permission denied
349
+
350
+ **Cause**: Script not executable
351
+ **Solution**: `chmod +x /home/prmichaelsen/scripts/migrate-memory-schema.sh`
352
+
353
+ ### Issue 2: Weaviate connection failed
354
+
355
+ **Cause**: Environment variables not set
356
+ **Solution**: Ensure `.env` file has WEAVIATE_URL and WEAVIATE_API_KEY
357
+
358
+ ### Issue 3: Some memories fail to update
359
+
360
+ **Cause**: Individual object update errors
361
+ **Solution**: Check error logs, may need to manually fix specific memories
362
+
363
+ ### Issue 4: Migration takes too long
364
+
365
+ **Cause**: Large number of memories
366
+ **Solution**: Run in batches, add progress indicators
367
+
368
+ ---
369
+
370
+ ## Safety Considerations
371
+
372
+ **Backup**:
373
+ - Weaviate doesn't have built-in backup for individual collections
374
+ - Consider exporting memories before migration
375
+ - Migration is additive (only adds fields, doesn't remove)
376
+
377
+ **Rollback**:
378
+ - If migration fails, new fields will be null/empty
379
+ - Can re-run migration safely (idempotent)
380
+ - No data loss risk (only adding fields)
381
+
382
+ **Testing**:
383
+ - Test on a single collection first
384
+ - Verify results before migrating all collections
385
+ - Check Memory_public separately
386
+
387
+ ---
388
+
389
+ ## Resources
390
+
391
+ - [Weaviate Update Objects](https://weaviate.io/developers/weaviate/manage-data/update)
392
+ - [Weaviate Batch Operations](https://weaviate.io/developers/weaviate/manage-data/import)
393
+ - [Schema Evolution Best Practices](https://weaviate.io/developers/weaviate/config-refs/schema)
394
+
395
+ ---
396
+
397
+ ## Notes
398
+
399
+ - This migration is **required** for v2.6.3+ to work with old memories
400
+ - Migration is idempotent (safe to run multiple times)
401
+ - Only updates memories that need migration (checks first)
402
+ - Processes in batches to avoid memory issues
403
+ - Logs progress for monitoring
404
+ - Can be run on production without downtime
405
+ - Consider scheduling during low-traffic period
406
+ - Estimated time: ~1-5 minutes per 1000 memories
407
+
408
+ ---
409
+
410
+ ## Alternative Approaches
411
+
412
+ ### Option 1: Lazy Migration (NOT RECOMMENDED)
413
+ - Update memories on-demand when accessed
414
+ - Pros: No bulk migration needed
415
+ - Cons: Unpredictable failures, poor UX
416
+
417
+ ### Option 2: Schema-Optional Fetch (NOT RECOMMENDED)
418
+ - Make fetchMemoryWithAllProperties handle missing properties
419
+ - Pros: No migration needed
420
+ - Cons: Inconsistent data, complex error handling
421
+
422
+ ### Option 3: Bulk Migration (RECOMMENDED)
423
+ - Run migration script once to update all memories
424
+ - Pros: Clean, predictable, one-time operation
425
+ - Cons: Requires downtime or careful execution
426
+
427
+ ---
428
+
429
+ **Status**: Not Started
430
+ **Recommendation**: Run migration immediately to unblock publish functionality
431
+ **Priority**: CRITICAL - Blocks core functionality for users with old memories
@@ -0,0 +1,294 @@
1
+ # Task 66: Support All Schema Fields in Create/Update Tools
2
+
3
+ **Milestone**: M12 (Comment System / Schema Completeness)
4
+ **Estimated Time**: 2 hours
5
+ **Dependencies**: Task 65 (migration script)
6
+ **Status**: Not Started
7
+ **Priority**: High
8
+
9
+ ---
10
+
11
+ ## Objective
12
+
13
+ Ensure all create and update tools (both personal and space tools) support ALL schema fields in their input schemas and properly initialize/update them. This includes comment fields and any other fields that may be missing from tool schemas.
14
+
15
+ ---
16
+
17
+ ## Context
18
+
19
+ **Current Problem**:
20
+ - New memories created via `remember_create_memory` don't have comment fields
21
+ - Space memories created via `remember_publish` may be missing fields
22
+ - Update tools may not support all schema fields
23
+ - After migration (Task 65), old memories will have these fields
24
+ - This creates inconsistency between old and new memories
25
+
26
+ **Missing Fields**:
27
+ - Comment fields: `parent_id`, `thread_root_id`, `moderation_flags`
28
+ - Potentially other fields not in tool schemas
29
+
30
+ **Affected Tools**:
31
+ - `remember_create_memory` - Personal memory creation
32
+ - `remember_update_memory` - Personal memory updates
33
+ - `remember_publish` / `remember_confirm` - Space memory creation (via executePublishMemory)
34
+
35
+ **Impact**:
36
+ - New memories missing fields
37
+ - Inconsistent schema across memories
38
+ - Potential query/filter issues
39
+ - Space memories may be incomplete
40
+
41
+ ---
42
+
43
+ ## Steps
44
+
45
+ ### 1. Update remember_create_memory Tool Schema
46
+
47
+ Add comment fields to input schema:
48
+
49
+ ```typescript
50
+ // src/tools/create-memory.ts
51
+
52
+ export const createMemoryTool: Tool = {
53
+ name: 'remember_create_memory',
54
+ description: '...',
55
+ inputSchema: {
56
+ type: 'object',
57
+ properties: {
58
+ // ... existing properties ...
59
+
60
+ // Comment/threading fields (optional)
61
+ parent_id: {
62
+ type: 'string',
63
+ description: 'ID of parent memory or comment (for threading). Leave null for top-level memories.',
64
+ },
65
+ thread_root_id: {
66
+ type: 'string',
67
+ description: 'Root memory ID for thread. Leave null for top-level memories.',
68
+ },
69
+ moderation_flags: {
70
+ type: 'array',
71
+ items: { type: 'string' },
72
+ description: 'Per-space moderation flags (format: "{space_id}:{flag_type}"). Usually empty.',
73
+ default: [],
74
+ },
75
+ },
76
+ required: ['type', 'content'], // parent_id, thread_root_id, moderation_flags are optional
77
+ },
78
+ };
79
+ ```
80
+
81
+ ### 2. Initialize Comment Fields in handleCreateMemory
82
+
83
+ Ensure fields are always initialized:
84
+
85
+ ```typescript
86
+ // src/tools/create-memory.ts - in handleCreateMemory function
87
+
88
+ const memory: Memory = {
89
+ // ... existing fields ...
90
+
91
+ // Comment/threading fields (initialize to defaults)
92
+ parent_id: args.parent_id || null,
93
+ thread_root_id: args.thread_root_id || null,
94
+ moderation_flags: args.moderation_flags || [],
95
+
96
+ // ... rest of fields ...
97
+ };
98
+ ```
99
+
100
+ ### 3. Update remember_update_memory Tool Schema
101
+
102
+ Add comment fields to update schema:
103
+
104
+ ```typescript
105
+ // src/tools/update-memory.ts
106
+
107
+ export const updateMemoryTool: Tool = {
108
+ name: 'remember_update_memory',
109
+ description: '...',
110
+ inputSchema: {
111
+ type: 'object',
112
+ properties: {
113
+ // ... existing properties ...
114
+
115
+ // Comment/threading fields (optional)
116
+ parent_id: {
117
+ type: 'string',
118
+ description: 'Update parent ID (for threading)',
119
+ },
120
+ thread_root_id: {
121
+ type: 'string',
122
+ description: 'Update thread root ID',
123
+ },
124
+ moderation_flags: {
125
+ type: 'array',
126
+ items: { type: 'string' },
127
+ description: 'Update moderation flags',
128
+ },
129
+ },
130
+ required: ['memory_id'],
131
+ },
132
+ };
133
+ ```
134
+
135
+ ### 4. Support Comment Fields in handleUpdateMemory
136
+
137
+ Allow updating comment fields:
138
+
139
+ ```typescript
140
+ // src/tools/update-memory.ts - in handleUpdateMemory function
141
+
142
+ const updates: Partial<Memory> = {};
143
+
144
+ // ... existing field updates ...
145
+
146
+ // Comment/threading fields
147
+ if (args.parent_id !== undefined) {
148
+ updates.parent_id = args.parent_id;
149
+ }
150
+ if (args.thread_root_id !== undefined) {
151
+ updates.thread_root_id = args.thread_root_id;
152
+ }
153
+ if (args.moderation_flags !== undefined) {
154
+ updates.moderation_flags = args.moderation_flags;
155
+ }
156
+ ```
157
+
158
+ ### 5. Update Memory Type Interface
159
+
160
+ Ensure TypeScript types include comment fields:
161
+
162
+ ```typescript
163
+ // src/types/memory.ts
164
+
165
+ export interface Memory {
166
+ // ... existing fields ...
167
+
168
+ // Comment/threading fields
169
+ parent_id?: string | null;
170
+ thread_root_id?: string | null;
171
+ moderation_flags?: string[];
172
+
173
+ // ... rest of fields ...
174
+ }
175
+ ```
176
+
177
+ ### 6. Test New Memory Creation
178
+
179
+ Verify new memories have comment fields:
180
+
181
+ ```bash
182
+ # Create a regular memory
183
+ remember_create_memory({
184
+ type: "note",
185
+ content: "Test memory"
186
+ })
187
+
188
+ # Verify it has:
189
+ # - parent_id: null
190
+ # - thread_root_id: null
191
+ # - moderation_flags: []
192
+
193
+ # Create a comment
194
+ remember_create_memory({
195
+ type: "comment",
196
+ content: "Great post!",
197
+ parent_id: "memory123",
198
+ thread_root_id: "memory123"
199
+ })
200
+
201
+ # Verify it has the parent/thread IDs set
202
+ ```
203
+
204
+ ---
205
+
206
+ ## Verification
207
+
208
+ - [ ] `remember_create_memory` input schema includes comment fields
209
+ - [ ] `handleCreateMemory` initializes comment fields to defaults
210
+ - [ ] `remember_update_memory` input schema includes comment fields
211
+ - [ ] `handleUpdateMemory` supports updating comment fields
212
+ - [ ] `Memory` type interface includes comment fields
213
+ - [ ] New memories created with `parent_id: null`
214
+ - [ ] New memories created with `thread_root_id: null`
215
+ - [ ] New memories created with `moderation_flags: []`
216
+ - [ ] Can create comments with parent_id set
217
+ - [ ] TypeScript compiles without errors
218
+ - [ ] Build successful
219
+ - [ ] All tests passing
220
+
221
+ ---
222
+
223
+ ## Expected Output
224
+
225
+ **New Regular Memory**:
226
+ ```json
227
+ {
228
+ "id": "new-memory-id",
229
+ "type": "note",
230
+ "content": "Test content",
231
+ "parent_id": null,
232
+ "thread_root_id": null,
233
+ "moderation_flags": [],
234
+ // ... other fields
235
+ }
236
+ ```
237
+
238
+ **New Comment**:
239
+ ```json
240
+ {
241
+ "id": "comment-id",
242
+ "type": "comment",
243
+ "content": "Great post!",
244
+ "parent_id": "memory123",
245
+ "thread_root_id": "memory123",
246
+ "moderation_flags": [],
247
+ // ... other fields
248
+ }
249
+ ```
250
+
251
+ ---
252
+
253
+ ## Common Issues and Solutions
254
+
255
+ ### Issue 1: TypeScript errors about new fields
256
+
257
+ **Cause**: Memory type not updated
258
+ **Solution**: Add fields to Memory interface in src/types/memory.ts
259
+
260
+ ### Issue 2: Fields not showing in created memories
261
+
262
+ **Cause**: Not initialized in handleCreateMemory
263
+ **Solution**: Ensure defaults are set (null for IDs, [] for flags)
264
+
265
+ ### Issue 3: Can't update comment fields
266
+
267
+ **Cause**: handleUpdateMemory doesn't support them
268
+ **Solution**: Add field update logic
269
+
270
+ ---
271
+
272
+ ## Resources
273
+
274
+ - [Memory Type Definition](../src/types/memory.ts)
275
+ - [remember_create_memory Tool](../src/tools/create-memory.ts)
276
+ - [remember_update_memory Tool](../src/tools/update-memory.ts)
277
+ - [Comment System Design](../design/comment-memory-type.md)
278
+
279
+ ---
280
+
281
+ ## Notes
282
+
283
+ - This ensures consistency between old (migrated) and new memories
284
+ - Comment fields are optional in input schema
285
+ - Defaults: `parent_id: null`, `thread_root_id: null`, `moderation_flags: []`
286
+ - Only comments should have non-null parent_id/thread_root_id
287
+ - Regular memories always have null for these fields
288
+ - This completes the comment system foundation
289
+
290
+ ---
291
+
292
+ **Status**: Not Started
293
+ **Recommendation**: Implement after Task 65 migration completes
294
+ **Priority**: High - Ensures schema consistency for all new memories
@@ -30,7 +30,7 @@ export declare const CONTENT_TYPE_CATEGORIES: {
30
30
  readonly communication: readonly ["email", "conversation", "meeting", "person"];
31
31
  readonly content: readonly ["article", "webpage", "social", "presentation", "spreadsheet", "pdf"];
32
32
  readonly media: readonly ["image", "video", "audio", "transcript"];
33
- readonly creative: readonly ["song", "screenplay", "recipe", "idea", "quote"];
33
+ readonly creative: readonly ["song", "screenplay", "recipe", "idea", "quote", "poetry"];
34
34
  readonly personal: readonly ["journal", "memory", "event"];
35
35
  readonly organizational: readonly ["bookmark", "form", "location"];
36
36
  readonly business: readonly ["invoice", "contract"];
@@ -981,6 +981,7 @@ var CONTENT_TYPES = [
981
981
  "recipe",
982
982
  "idea",
983
983
  "quote",
984
+ "poetry",
984
985
  // Personal
985
986
  "journal",
986
987
  "memory",
@@ -1197,6 +1198,13 @@ var CONTENT_TYPE_METADATA = {
1197
1198
  examples: ["Quotes", "Excerpts", "Highlights", "Citations"],
1198
1199
  common_fields: ["author", "source"]
1199
1200
  },
1201
+ poetry: {
1202
+ name: "poetry",
1203
+ category: "creative",
1204
+ description: "Poems and poetic content",
1205
+ examples: ["Poems", "Verses", "Haiku", "Sonnets", "Free verse"],
1206
+ common_fields: ["author", "form", "theme"]
1207
+ },
1200
1208
  // Personal
1201
1209
  journal: {
1202
1210
  name: "journal",
@@ -1391,6 +1399,20 @@ var createMemoryTool = {
1391
1399
  type: "boolean",
1392
1400
  description: "Skip automatic template suggestion",
1393
1401
  default: false
1402
+ },
1403
+ parent_id: {
1404
+ type: "string",
1405
+ description: "ID of parent memory or comment (for threading). Leave null for top-level memories."
1406
+ },
1407
+ thread_root_id: {
1408
+ type: "string",
1409
+ description: "Root memory ID for thread. Leave null for top-level memories."
1410
+ },
1411
+ moderation_flags: {
1412
+ type: "array",
1413
+ items: { type: "string" },
1414
+ description: 'Per-space moderation flags (format: "{space_id}:{flag_type}"). Usually empty.',
1415
+ default: []
1394
1416
  }
1395
1417
  },
1396
1418
  required: ["content"]
@@ -1452,7 +1474,11 @@ async function handleCreateMemory(args, userId, context) {
1452
1474
  structured_content: args.structured_content,
1453
1475
  // Computed weight
1454
1476
  base_weight: args.weight ?? 0.5,
1455
- computed_weight: args.weight ?? 0.5
1477
+ computed_weight: args.weight ?? 0.5,
1478
+ // Comment/threading fields (initialize to defaults)
1479
+ parent_id: args.parent_id ?? null,
1480
+ thread_root_id: args.thread_root_id ?? null,
1481
+ moderation_flags: args.moderation_flags ?? []
1456
1482
  };
1457
1483
  const result = await collection.data.insert({
1458
1484
  properties: memory
@@ -1889,6 +1915,19 @@ var updateMemoryTool = {
1889
1915
  structured_content: {
1890
1916
  type: "object",
1891
1917
  description: "Updated structured content"
1918
+ },
1919
+ parent_id: {
1920
+ type: "string",
1921
+ description: "Update parent ID (for threading)"
1922
+ },
1923
+ thread_root_id: {
1924
+ type: "string",
1925
+ description: "Update thread root ID"
1926
+ },
1927
+ moderation_flags: {
1928
+ type: "array",
1929
+ items: { type: "string" },
1930
+ description: "Update moderation flags"
1892
1931
  }
1893
1932
  },
1894
1933
  required: ["memory_id"]
@@ -1968,6 +2007,18 @@ async function handleUpdateMemory(args, userId) {
1968
2007
  updates.structured_content = args.structured_content;
1969
2008
  updatedFields.push("structured_content");
1970
2009
  }
2010
+ if (args.parent_id !== void 0) {
2011
+ updates.parent_id = args.parent_id;
2012
+ updatedFields.push("parent_id");
2013
+ }
2014
+ if (args.thread_root_id !== void 0) {
2015
+ updates.thread_root_id = args.thread_root_id;
2016
+ updatedFields.push("thread_root_id");
2017
+ }
2018
+ if (args.moderation_flags !== void 0) {
2019
+ updates.moderation_flags = args.moderation_flags;
2020
+ updatedFields.push("moderation_flags");
2021
+ }
1971
2022
  if (updatedFields.length === 0) {
1972
2023
  throw new Error("No fields provided for update. At least one field must be specified.");
1973
2024
  }
package/dist/server.js CHANGED
@@ -1049,6 +1049,7 @@ var CONTENT_TYPES = [
1049
1049
  "recipe",
1050
1050
  "idea",
1051
1051
  "quote",
1052
+ "poetry",
1052
1053
  // Personal
1053
1054
  "journal",
1054
1055
  "memory",
@@ -1265,6 +1266,13 @@ var CONTENT_TYPE_METADATA = {
1265
1266
  examples: ["Quotes", "Excerpts", "Highlights", "Citations"],
1266
1267
  common_fields: ["author", "source"]
1267
1268
  },
1269
+ poetry: {
1270
+ name: "poetry",
1271
+ category: "creative",
1272
+ description: "Poems and poetic content",
1273
+ examples: ["Poems", "Verses", "Haiku", "Sonnets", "Free verse"],
1274
+ common_fields: ["author", "form", "theme"]
1275
+ },
1268
1276
  // Personal
1269
1277
  journal: {
1270
1278
  name: "journal",
@@ -1459,6 +1467,20 @@ var createMemoryTool = {
1459
1467
  type: "boolean",
1460
1468
  description: "Skip automatic template suggestion",
1461
1469
  default: false
1470
+ },
1471
+ parent_id: {
1472
+ type: "string",
1473
+ description: "ID of parent memory or comment (for threading). Leave null for top-level memories."
1474
+ },
1475
+ thread_root_id: {
1476
+ type: "string",
1477
+ description: "Root memory ID for thread. Leave null for top-level memories."
1478
+ },
1479
+ moderation_flags: {
1480
+ type: "array",
1481
+ items: { type: "string" },
1482
+ description: 'Per-space moderation flags (format: "{space_id}:{flag_type}"). Usually empty.',
1483
+ default: []
1462
1484
  }
1463
1485
  },
1464
1486
  required: ["content"]
@@ -1520,7 +1542,11 @@ async function handleCreateMemory(args, userId, context) {
1520
1542
  structured_content: args.structured_content,
1521
1543
  // Computed weight
1522
1544
  base_weight: args.weight ?? 0.5,
1523
- computed_weight: args.weight ?? 0.5
1545
+ computed_weight: args.weight ?? 0.5,
1546
+ // Comment/threading fields (initialize to defaults)
1547
+ parent_id: args.parent_id ?? null,
1548
+ thread_root_id: args.thread_root_id ?? null,
1549
+ moderation_flags: args.moderation_flags ?? []
1524
1550
  };
1525
1551
  const result = await collection.data.insert({
1526
1552
  properties: memory
@@ -1957,6 +1983,19 @@ var updateMemoryTool = {
1957
1983
  structured_content: {
1958
1984
  type: "object",
1959
1985
  description: "Updated structured content"
1986
+ },
1987
+ parent_id: {
1988
+ type: "string",
1989
+ description: "Update parent ID (for threading)"
1990
+ },
1991
+ thread_root_id: {
1992
+ type: "string",
1993
+ description: "Update thread root ID"
1994
+ },
1995
+ moderation_flags: {
1996
+ type: "array",
1997
+ items: { type: "string" },
1998
+ description: "Update moderation flags"
1960
1999
  }
1961
2000
  },
1962
2001
  required: ["memory_id"]
@@ -2036,6 +2075,18 @@ async function handleUpdateMemory(args, userId) {
2036
2075
  updates.structured_content = args.structured_content;
2037
2076
  updatedFields.push("structured_content");
2038
2077
  }
2078
+ if (args.parent_id !== void 0) {
2079
+ updates.parent_id = args.parent_id;
2080
+ updatedFields.push("parent_id");
2081
+ }
2082
+ if (args.thread_root_id !== void 0) {
2083
+ updates.thread_root_id = args.thread_root_id;
2084
+ updatedFields.push("thread_root_id");
2085
+ }
2086
+ if (args.moderation_flags !== void 0) {
2087
+ updates.moderation_flags = args.moderation_flags;
2088
+ updatedFields.push("moderation_flags");
2089
+ }
2039
2090
  if (updatedFields.length === 0) {
2040
2091
  throw new Error("No fields provided for update. At least one field must be specified.");
2041
2092
  }
@@ -60,6 +60,22 @@ export declare const createMemoryTool: {
60
60
  description: string;
61
61
  default: boolean;
62
62
  };
63
+ parent_id: {
64
+ type: string;
65
+ description: string;
66
+ };
67
+ thread_root_id: {
68
+ type: string;
69
+ description: string;
70
+ };
71
+ moderation_flags: {
72
+ type: string;
73
+ items: {
74
+ type: string;
75
+ };
76
+ description: string;
77
+ default: never[];
78
+ };
63
79
  };
64
80
  required: string[];
65
81
  };
@@ -78,6 +94,9 @@ export interface CreateMemoryArgs {
78
94
  template_id?: string;
79
95
  skip_template_suggestion?: boolean;
80
96
  structured_content?: Record<string, any>;
97
+ parent_id?: string | null;
98
+ thread_root_id?: string | null;
99
+ moderation_flags?: string[];
81
100
  }
82
101
  /**
83
102
  * Create memory result
@@ -57,6 +57,21 @@ export declare const updateMemoryTool: {
57
57
  type: string;
58
58
  description: string;
59
59
  };
60
+ parent_id: {
61
+ type: string;
62
+ description: string;
63
+ };
64
+ thread_root_id: {
65
+ type: string;
66
+ description: string;
67
+ };
68
+ moderation_flags: {
69
+ type: string;
70
+ items: {
71
+ type: string;
72
+ };
73
+ description: string;
74
+ };
60
75
  };
61
76
  required: string[];
62
77
  };
@@ -74,6 +89,9 @@ export interface UpdateMemoryArgs {
74
89
  tags?: string[];
75
90
  references?: string[];
76
91
  structured_content?: Record<string, any>;
92
+ parent_id?: string | null;
93
+ thread_root_id?: string | null;
94
+ moderation_flags?: string[];
77
95
  }
78
96
  /**
79
97
  * Update memory result
@@ -5,7 +5,7 @@
5
5
  * Content types for memories
6
6
  * Based on agent/design/content-types-expansion.md
7
7
  */
8
- export type ContentType = 'code' | 'note' | 'documentation' | 'reference' | 'todo' | 'checklist' | 'project' | 'goal' | 'habit' | 'email' | 'conversation' | 'meeting' | 'person' | 'article' | 'webpage' | 'social' | 'image' | 'video' | 'audio' | 'song' | 'transcript' | 'presentation' | 'spreadsheet' | 'pdf' | 'screenplay' | 'recipe' | 'idea' | 'quote' | 'journal' | 'memory' | 'event' | 'bookmark' | 'form' | 'location' | 'invoice' | 'contract' | 'system' | 'action' | 'audit' | 'history';
8
+ export type ContentType = 'code' | 'note' | 'documentation' | 'reference' | 'todo' | 'checklist' | 'project' | 'goal' | 'habit' | 'email' | 'conversation' | 'meeting' | 'person' | 'article' | 'webpage' | 'social' | 'image' | 'video' | 'audio' | 'song' | 'transcript' | 'presentation' | 'spreadsheet' | 'pdf' | 'screenplay' | 'recipe' | 'idea' | 'quote' | 'poetry' | 'journal' | 'memory' | 'event' | 'bookmark' | 'form' | 'location' | 'invoice' | 'contract' | 'system' | 'action' | 'audit' | 'history';
9
9
  /**
10
10
  * GPS coordinates
11
11
  */
@@ -111,6 +111,9 @@ export interface Memory {
111
111
  structured_content?: Record<string, any>;
112
112
  base_weight: number;
113
113
  computed_weight?: number;
114
+ parent_id?: string | null;
115
+ thread_root_id?: string | null;
116
+ moderation_flags?: string[];
114
117
  }
115
118
  /**
116
119
  * Relationship interface
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/remember-mcp",
3
- "version": "2.6.7",
3
+ "version": "2.6.8",
4
4
  "description": "Multi-tenant memory system MCP server with vector search and relationships",
5
5
  "main": "dist/server.js",
6
6
  "type": "module",
@@ -42,6 +42,7 @@ export const CONTENT_TYPES: readonly ContentType[] = [
42
42
  'recipe',
43
43
  'idea',
44
44
  'quote',
45
+ 'poetry',
45
46
  // Personal
46
47
  'journal',
47
48
  'memory',
@@ -277,6 +278,13 @@ export const CONTENT_TYPE_METADATA: Record<ContentType, ContentTypeMetadata> = {
277
278
  examples: ['Quotes', 'Excerpts', 'Highlights', 'Citations'],
278
279
  common_fields: ['author', 'source'],
279
280
  },
281
+ poetry: {
282
+ name: 'poetry',
283
+ category: 'creative',
284
+ description: 'Poems and poetic content',
285
+ examples: ['Poems', 'Verses', 'Haiku', 'Sonnets', 'Free verse'],
286
+ common_fields: ['author', 'form', 'theme'],
287
+ },
280
288
 
281
289
  // Personal
282
290
  journal: {
@@ -379,7 +387,7 @@ export const CONTENT_TYPE_CATEGORIES = {
379
387
  communication: ['email', 'conversation', 'meeting', 'person'],
380
388
  content: ['article', 'webpage', 'social', 'presentation', 'spreadsheet', 'pdf'],
381
389
  media: ['image', 'video', 'audio', 'transcript'],
382
- creative: ['song', 'screenplay', 'recipe', 'idea', 'quote'],
390
+ creative: ['song', 'screenplay', 'recipe', 'idea', 'quote', 'poetry'],
383
391
  personal: ['journal', 'memory', 'event'],
384
392
  organizational: ['bookmark', 'form', 'location'],
385
393
  business: ['invoice', 'contract'],
@@ -80,6 +80,20 @@ export const createMemoryTool = {
80
80
  description: 'Skip automatic template suggestion',
81
81
  default: false,
82
82
  },
83
+ parent_id: {
84
+ type: 'string',
85
+ description: 'ID of parent memory or comment (for threading). Leave null for top-level memories.',
86
+ },
87
+ thread_root_id: {
88
+ type: 'string',
89
+ description: 'Root memory ID for thread. Leave null for top-level memories.',
90
+ },
91
+ moderation_flags: {
92
+ type: 'array',
93
+ items: { type: 'string' },
94
+ description: 'Per-space moderation flags (format: "{space_id}:{flag_type}"). Usually empty.',
95
+ default: [],
96
+ },
83
97
  },
84
98
  required: ['content'],
85
99
  },
@@ -99,6 +113,10 @@ export interface CreateMemoryArgs {
99
113
  template_id?: string;
100
114
  skip_template_suggestion?: boolean;
101
115
  structured_content?: Record<string, any>;
116
+ // Comment/threading fields
117
+ parent_id?: string | null;
118
+ thread_root_id?: string | null;
119
+ moderation_flags?: string[];
102
120
  }
103
121
 
104
122
  /**
@@ -186,6 +204,11 @@ export async function handleCreateMemory(
186
204
  // Computed weight
187
205
  base_weight: args.weight ?? 0.5,
188
206
  computed_weight: args.weight ?? 0.5,
207
+
208
+ // Comment/threading fields (initialize to defaults)
209
+ parent_id: args.parent_id ?? null,
210
+ thread_root_id: args.thread_root_id ?? null,
211
+ moderation_flags: args.moderation_flags ?? [],
189
212
  };
190
213
 
191
214
  // Insert into Weaviate v3 API
@@ -70,6 +70,19 @@ export const updateMemoryTool = {
70
70
  type: 'object',
71
71
  description: 'Updated structured content',
72
72
  },
73
+ parent_id: {
74
+ type: 'string',
75
+ description: 'Update parent ID (for threading)',
76
+ },
77
+ thread_root_id: {
78
+ type: 'string',
79
+ description: 'Update thread root ID',
80
+ },
81
+ moderation_flags: {
82
+ type: 'array',
83
+ items: { type: 'string' },
84
+ description: 'Update moderation flags',
85
+ },
73
86
  },
74
87
  required: ['memory_id'],
75
88
  },
@@ -88,6 +101,10 @@ export interface UpdateMemoryArgs {
88
101
  tags?: string[];
89
102
  references?: string[];
90
103
  structured_content?: Record<string, any>;
104
+ // Comment/threading fields
105
+ parent_id?: string | null;
106
+ thread_root_id?: string | null;
107
+ moderation_flags?: string[];
91
108
  }
92
109
 
93
110
  /**
@@ -204,6 +221,22 @@ export async function handleUpdateMemory(
204
221
  updatedFields.push('structured_content');
205
222
  }
206
223
 
224
+ // Update comment/threading fields
225
+ if (args.parent_id !== undefined) {
226
+ updates.parent_id = args.parent_id;
227
+ updatedFields.push('parent_id');
228
+ }
229
+
230
+ if (args.thread_root_id !== undefined) {
231
+ updates.thread_root_id = args.thread_root_id;
232
+ updatedFields.push('thread_root_id');
233
+ }
234
+
235
+ if (args.moderation_flags !== undefined) {
236
+ updates.moderation_flags = args.moderation_flags;
237
+ updatedFields.push('moderation_flags');
238
+ }
239
+
207
240
  // Check if any fields were provided
208
241
  if (updatedFields.length === 0) {
209
242
  throw new Error('No fields provided for update. At least one field must be specified.');
@@ -40,6 +40,7 @@ export type ContentType =
40
40
  | 'recipe'
41
41
  | 'idea'
42
42
  | 'quote'
43
+ | 'poetry'
43
44
  // Personal
44
45
  | 'journal'
45
46
  | 'memory'
@@ -190,6 +191,11 @@ export interface Memory {
190
191
  // Computed Weight (for search ranking)
191
192
  base_weight: number; // User-specified
192
193
  computed_weight?: number; // Calculated with access multipliers
194
+
195
+ // Comment/Threading Fields (for threaded discussions in shared spaces)
196
+ parent_id?: string | null; // ID of parent memory or comment (null for top-level)
197
+ thread_root_id?: string | null; // Root memory ID for fetching entire thread (null for top-level)
198
+ moderation_flags?: string[]; // Per-space moderation flags (format: "{space_id}:{flag_type}")
193
199
  }
194
200
 
195
201
  /**