@prmichaelsen/remember-mcp 3.13.0 → 3.14.0

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.
Files changed (61) hide show
  1. package/agent/milestones/milestone-17-remember-core-migration.md +140 -0
  2. package/agent/progress.yaml +123 -6
  3. package/agent/tasks/milestone-17-remember-core-migration/task-193-foundation-setup.md +58 -0
  4. package/agent/tasks/milestone-17-remember-core-migration/task-194-migrate-relationship-tools.md +47 -0
  5. package/agent/tasks/milestone-17-remember-core-migration/task-195-migrate-preference-tools.md +34 -0
  6. package/agent/tasks/milestone-17-remember-core-migration/task-196-migrate-memory-tools.md +46 -0
  7. package/agent/tasks/milestone-17-remember-core-migration/task-197-migrate-space-confirmation-tools.md +49 -0
  8. package/agent/tasks/milestone-17-remember-core-migration/task-198-migrate-space-search-moderate.md +46 -0
  9. package/agent/tasks/milestone-17-remember-core-migration/task-199-migrate-delete-memory.md +43 -0
  10. package/agent/tasks/milestone-17-remember-core-migration/task-200-code-cleanup-verification.md +52 -0
  11. package/dist/core-services.d.ts +25 -0
  12. package/dist/server-factory.js +3578 -4485
  13. package/dist/server.js +3070 -3973
  14. package/dist/tools/confirm-publish-moderation.spec.d.ts +3 -2
  15. package/dist/tools/create-memory.d.ts +1 -1
  16. package/dist/tools/query-space.d.ts +1 -1
  17. package/dist/tools/search-space.d.ts +10 -14
  18. package/jest.config.js +11 -0
  19. package/package.json +2 -1
  20. package/src/core-services.ts +50 -0
  21. package/src/tools/confirm-publish-moderation.spec.ts +120 -176
  22. package/src/tools/confirm.ts +70 -1035
  23. package/src/tools/create-memory.ts +16 -67
  24. package/src/tools/create-relationship.ts +13 -181
  25. package/src/tools/delete-memory.ts +7 -72
  26. package/src/tools/delete-relationship.ts +7 -91
  27. package/src/tools/deny.ts +4 -14
  28. package/src/tools/find-similar.ts +16 -110
  29. package/src/tools/get-preferences.ts +3 -8
  30. package/src/tools/moderate.spec.ts +65 -81
  31. package/src/tools/moderate.ts +18 -121
  32. package/src/tools/publish.ts +7 -204
  33. package/src/tools/query-space.ts +28 -140
  34. package/src/tools/retract.ts +7 -185
  35. package/src/tools/revise.ts +4 -136
  36. package/src/tools/search-relationship.ts +17 -116
  37. package/src/tools/search-space.ts +58 -304
  38. package/src/tools/set-preference.ts +3 -8
  39. package/src/tools/update-memory.ts +22 -190
  40. package/src/tools/update-relationship.ts +16 -90
  41. package/src/v2-smoke.e2e.ts +3 -2
  42. package/dist/collections/composite-ids.d.ts +0 -106
  43. package/dist/collections/core-infrastructure.spec.d.ts +0 -11
  44. package/dist/collections/dot-notation.d.ts +0 -106
  45. package/dist/collections/tracking-arrays.d.ts +0 -176
  46. package/dist/constants/content-types.d.ts +0 -61
  47. package/dist/services/confirmation-token.service.d.ts +0 -99
  48. package/dist/services/confirmation-token.service.spec.d.ts +0 -5
  49. package/dist/services/preferences-database.service.d.ts +0 -22
  50. package/dist/services/space-config.service.d.ts +0 -23
  51. package/dist/services/space-config.service.spec.d.ts +0 -2
  52. package/src/collections/composite-ids.ts +0 -193
  53. package/src/collections/core-infrastructure.spec.ts +0 -353
  54. package/src/collections/dot-notation.ts +0 -212
  55. package/src/collections/tracking-arrays.ts +0 -298
  56. package/src/constants/content-types.ts +0 -490
  57. package/src/services/confirmation-token.service.spec.ts +0 -254
  58. package/src/services/confirmation-token.service.ts +0 -328
  59. package/src/services/preferences-database.service.ts +0 -120
  60. package/src/services/space-config.service.spec.ts +0 -102
  61. package/src/services/space-config.service.ts +0 -79
@@ -1,176 +0,0 @@
1
- /**
2
- * Tracking Array Management
3
- *
4
- * Provides utilities for managing space_ids and group_ids tracking arrays
5
- * in Memory Collection Pattern v2. These arrays track where memories have
6
- * been published.
7
- */
8
- /**
9
- * Memory with tracking arrays
10
- */
11
- export interface MemoryWithTracking {
12
- space_ids: string[];
13
- group_ids: string[];
14
- [key: string]: any;
15
- }
16
- /**
17
- * Published locations summary
18
- */
19
- export interface PublishedLocations {
20
- spaces: string[];
21
- groups: string[];
22
- }
23
- /**
24
- * Add a space ID to the space_ids array (immutable)
25
- *
26
- * @param memory - Memory object with tracking arrays
27
- * @param spaceId - Space ID to add
28
- * @returns New memory object with updated space_ids
29
- *
30
- * @example
31
- * const memory = { space_ids: ['cooking'], group_ids: [] }
32
- * addToSpaceIds(memory, 'recipes')
33
- * // Returns: { space_ids: ['cooking', 'recipes'], group_ids: [] }
34
- */
35
- export declare function addToSpaceIds<T extends MemoryWithTracking>(memory: T, spaceId: string): T;
36
- /**
37
- * Remove a space ID from the space_ids array (immutable)
38
- *
39
- * @param memory - Memory object with tracking arrays
40
- * @param spaceId - Space ID to remove
41
- * @returns New memory object with updated space_ids
42
- *
43
- * @example
44
- * const memory = { space_ids: ['cooking', 'recipes'], group_ids: [] }
45
- * removeFromSpaceIds(memory, 'cooking')
46
- * // Returns: { space_ids: ['recipes'], group_ids: [] }
47
- */
48
- export declare function removeFromSpaceIds<T extends MemoryWithTracking>(memory: T, spaceId: string): T;
49
- /**
50
- * Add a group ID to the group_ids array (immutable)
51
- *
52
- * @param memory - Memory object with tracking arrays
53
- * @param groupId - Group ID to add
54
- * @returns New memory object with updated group_ids
55
- *
56
- * @example
57
- * const memory = { space_ids: [], group_ids: ['family'] }
58
- * addToGroupIds(memory, 'friends')
59
- * // Returns: { space_ids: [], group_ids: ['family', 'friends'] }
60
- */
61
- export declare function addToGroupIds<T extends MemoryWithTracking>(memory: T, groupId: string): T;
62
- /**
63
- * Remove a group ID from the group_ids array (immutable)
64
- *
65
- * @param memory - Memory object with tracking arrays
66
- * @param groupId - Group ID to remove
67
- * @returns New memory object with updated group_ids
68
- *
69
- * @example
70
- * const memory = { space_ids: [], group_ids: ['family', 'friends'] }
71
- * removeFromGroupIds(memory, 'family')
72
- * // Returns: { space_ids: [], group_ids: ['friends'] }
73
- */
74
- export declare function removeFromGroupIds<T extends MemoryWithTracking>(memory: T, groupId: string): T;
75
- /**
76
- * Check if memory is published to a specific space
77
- *
78
- * @param memory - Memory object with tracking arrays
79
- * @param spaceId - Space ID to check
80
- * @returns true if published to space, false otherwise
81
- *
82
- * @example
83
- * const memory = { space_ids: ['cooking'], group_ids: [] }
84
- * isPublishedToSpace(memory, 'cooking') // true
85
- * isPublishedToSpace(memory, 'recipes') // false
86
- */
87
- export declare function isPublishedToSpace(memory: MemoryWithTracking, spaceId: string): boolean;
88
- /**
89
- * Check if memory is published to a specific group
90
- *
91
- * @param memory - Memory object with tracking arrays
92
- * @param groupId - Group ID to check
93
- * @returns true if published to group, false otherwise
94
- *
95
- * @example
96
- * const memory = { space_ids: [], group_ids: ['family'] }
97
- * isPublishedToGroup(memory, 'family') // true
98
- * isPublishedToGroup(memory, 'friends') // false
99
- */
100
- export declare function isPublishedToGroup(memory: MemoryWithTracking, groupId: string): boolean;
101
- /**
102
- * Get all published locations for a memory
103
- *
104
- * @param memory - Memory object with tracking arrays
105
- * @returns Object with spaces and groups arrays
106
- *
107
- * @example
108
- * const memory = { space_ids: ['cooking', 'recipes'], group_ids: ['family'] }
109
- * getPublishedLocations(memory)
110
- * // Returns: { spaces: ['cooking', 'recipes'], groups: ['family'] }
111
- */
112
- export declare function getPublishedLocations(memory: MemoryWithTracking): PublishedLocations;
113
- /**
114
- * Check if memory is published anywhere
115
- *
116
- * @param memory - Memory object with tracking arrays
117
- * @returns true if published to any space or group, false otherwise
118
- *
119
- * @example
120
- * const memory = { space_ids: ['cooking'], group_ids: [] }
121
- * isPublished(memory) // true
122
- *
123
- * const unpublished = { space_ids: [], group_ids: [] }
124
- * isPublished(unpublished) // false
125
- */
126
- export declare function isPublished(memory: MemoryWithTracking): boolean;
127
- /**
128
- * Get count of published locations
129
- *
130
- * @param memory - Memory object with tracking arrays
131
- * @returns Total number of spaces and groups memory is published to
132
- *
133
- * @example
134
- * const memory = { space_ids: ['cooking', 'recipes'], group_ids: ['family'] }
135
- * getPublishedCount(memory) // 3
136
- */
137
- export declare function getPublishedCount(memory: MemoryWithTracking): number;
138
- /**
139
- * Initialize tracking arrays on a memory object (immutable)
140
- *
141
- * @param memory - Memory object (may not have tracking arrays)
142
- * @returns New memory object with initialized tracking arrays
143
- *
144
- * @example
145
- * const memory = { id: '123', content: 'test' }
146
- * initializeTracking(memory)
147
- * // Returns: { id: '123', content: 'test', space_ids: [], group_ids: [] }
148
- */
149
- export declare function initializeTracking<T extends Record<string, any>>(memory: T): T & MemoryWithTracking;
150
- /**
151
- * Add multiple space IDs at once (immutable)
152
- *
153
- * @param memory - Memory object with tracking arrays
154
- * @param spaceIds - Array of space IDs to add
155
- * @returns New memory object with updated space_ids
156
- *
157
- * @example
158
- * const memory = { space_ids: ['cooking'], group_ids: [] }
159
- * addMultipleSpaceIds(memory, ['recipes', 'baking'])
160
- * // Returns: { space_ids: ['cooking', 'recipes', 'baking'], group_ids: [] }
161
- */
162
- export declare function addMultipleSpaceIds<T extends MemoryWithTracking>(memory: T, spaceIds: string[]): T;
163
- /**
164
- * Add multiple group IDs at once (immutable)
165
- *
166
- * @param memory - Memory object with tracking arrays
167
- * @param groupIds - Array of group IDs to add
168
- * @returns New memory object with updated group_ids
169
- *
170
- * @example
171
- * const memory = { space_ids: [], group_ids: ['family'] }
172
- * addMultipleGroupIds(memory, ['friends', 'coworkers'])
173
- * // Returns: { space_ids: [], group_ids: ['family', 'friends', 'coworkers'] }
174
- */
175
- export declare function addMultipleGroupIds<T extends MemoryWithTracking>(memory: T, groupIds: string[]): T;
176
- //# sourceMappingURL=tracking-arrays.d.ts.map
@@ -1,61 +0,0 @@
1
- /**
2
- * Content type constants and descriptions
3
- * Based on agent/design/content-types-expansion.md and default-template-library.md
4
- */
5
- import type { ContentType } from '../types/memory.js';
6
- /**
7
- * All available content types
8
- */
9
- export declare const CONTENT_TYPES: readonly ContentType[];
10
- /**
11
- * Content type metadata
12
- */
13
- export interface ContentTypeMetadata {
14
- name: ContentType;
15
- category: string;
16
- description: string;
17
- examples: string[];
18
- common_fields?: string[];
19
- }
20
- /**
21
- * Comprehensive content type descriptions
22
- */
23
- export declare const CONTENT_TYPE_METADATA: Record<ContentType, ContentTypeMetadata>;
24
- /**
25
- * Content type categories
26
- */
27
- export declare const CONTENT_TYPE_CATEGORIES: {
28
- readonly core: readonly ["code", "note", "documentation", "reference"];
29
- readonly task: readonly ["todo", "checklist", "project", "goal", "habit"];
30
- readonly communication: readonly ["email", "conversation", "meeting", "person"];
31
- readonly content: readonly ["article", "webpage", "social", "presentation", "spreadsheet", "pdf"];
32
- readonly media: readonly ["image", "video", "audio", "transcript"];
33
- readonly creative: readonly ["song", "screenplay", "recipe", "idea", "quote", "poetry"];
34
- readonly personal: readonly ["journal", "memory", "event"];
35
- readonly organizational: readonly ["bookmark", "form", "location"];
36
- readonly business: readonly ["invoice", "contract"];
37
- readonly system: readonly ["system", "action", "audit", "history"];
38
- readonly cross_user: readonly ["ghost", "comment"];
39
- };
40
- /**
41
- * Get content type metadata
42
- */
43
- export declare function getContentTypeMetadata(type: ContentType): ContentTypeMetadata;
44
- /**
45
- * Get content types by category
46
- */
47
- export declare function getContentTypesByCategory(category: keyof typeof CONTENT_TYPE_CATEGORIES): ContentType[];
48
- /**
49
- * Validate content type
50
- */
51
- export declare function isValidContentType(type: string): type is ContentType;
52
- /**
53
- * Get content type description for LLM prompts
54
- * Generated dynamically from CONTENT_TYPE_METADATA
55
- */
56
- export declare function getContentTypeDescription(): string;
57
- /**
58
- * Default content type
59
- */
60
- export declare const DEFAULT_CONTENT_TYPE: ContentType;
61
- //# sourceMappingURL=content-types.d.ts.map
@@ -1,99 +0,0 @@
1
- /**
2
- * Confirmation Token Service
3
- *
4
- * Manages confirmation tokens for sensitive operations like publishing memories.
5
- * Tokens are one-time use with 5-minute expiry.
6
- */
7
- /**
8
- * Confirmation request stored in Firestore
9
- */
10
- export interface ConfirmationRequest {
11
- user_id: string;
12
- token: string;
13
- action: string;
14
- target_collection?: string;
15
- payload: any;
16
- created_at: string;
17
- expires_at: string;
18
- status: 'pending' | 'confirmed' | 'denied' | 'expired' | 'retracted';
19
- confirmed_at?: string;
20
- }
21
- /**
22
- * Service for managing confirmation tokens
23
- */
24
- export declare class ConfirmationTokenService {
25
- private readonly EXPIRY_MINUTES;
26
- /**
27
- * Create a new confirmation request
28
- *
29
- * @param userId - User ID who initiated the request
30
- * @param action - Action type (e.g., 'publish_memory')
31
- * @param payload - Data to store with the request
32
- * @param targetCollection - Optional target collection (e.g., 'the_void')
33
- * @returns Request ID and token
34
- */
35
- createRequest(userId: string, action: string, payload: any, targetCollection?: string): Promise<{
36
- requestId: string;
37
- token: string;
38
- }>;
39
- /**
40
- * Validate and retrieve a confirmation request
41
- *
42
- * @param userId - User ID
43
- * @param token - Confirmation token
44
- * @returns Request with request_id if valid, null otherwise
45
- */
46
- validateToken(userId: string, token: string): Promise<(ConfirmationRequest & {
47
- request_id: string;
48
- }) | null>;
49
- /**
50
- * Confirm a request
51
- *
52
- * @param userId - User ID
53
- * @param token - Confirmation token
54
- * @returns Confirmed request if valid, null otherwise
55
- */
56
- confirmRequest(userId: string, token: string): Promise<(ConfirmationRequest & {
57
- request_id: string;
58
- }) | null>;
59
- /**
60
- * Deny a request
61
- *
62
- * @param userId - User ID
63
- * @param token - Confirmation token
64
- * @returns True if denied successfully, false otherwise
65
- */
66
- denyRequest(userId: string, token: string): Promise<boolean>;
67
- /**
68
- * Retract a request
69
- *
70
- * @param userId - User ID
71
- * @param token - Confirmation token
72
- * @returns True if retracted successfully, false otherwise
73
- */
74
- retractRequest(userId: string, token: string): Promise<boolean>;
75
- /**
76
- * Update request status
77
- *
78
- * @param userId - User ID
79
- * @param requestId - Request document ID
80
- * @param status - New status
81
- */
82
- private updateStatus;
83
- /**
84
- * Clean up expired requests (optional - Firestore TTL handles deletion)
85
- *
86
- * Note: Configure Firestore TTL policy on 'requests' collection group
87
- * with 'expires_at' field for automatic deletion within 24 hours.
88
- *
89
- * This method is optional for immediate cleanup if needed.
90
- *
91
- * @returns Count of deleted requests
92
- */
93
- cleanupExpired(): Promise<number>;
94
- }
95
- /**
96
- * Singleton instance of the confirmation token service
97
- */
98
- export declare const confirmationTokenService: ConfirmationTokenService;
99
- //# sourceMappingURL=confirmation-token.service.d.ts.map
@@ -1,5 +0,0 @@
1
- /**
2
- * Unit tests for Confirmation Token Service
3
- */
4
- export {};
5
- //# sourceMappingURL=confirmation-token.service.spec.d.ts.map
@@ -1,22 +0,0 @@
1
- /**
2
- * Preferences Database Service
3
- * Handles all Firestore operations for user preferences
4
- */
5
- import { UserPreferences } from '../types/preferences.js';
6
- export declare class PreferencesDatabaseService {
7
- /**
8
- * Get user preferences
9
- * Returns defaults if preferences don't exist
10
- */
11
- static getPreferences(userId: string): Promise<UserPreferences>;
12
- /**
13
- * Update user preferences (partial update with merge)
14
- * Creates with defaults if preferences don't exist
15
- */
16
- static updatePreferences(userId: string, updates: Partial<Omit<UserPreferences, 'user_id' | 'created_at'>>): Promise<UserPreferences>;
17
- /**
18
- * Create preferences with defaults
19
- */
20
- static createPreferences(userId: string): Promise<UserPreferences>;
21
- }
22
- //# sourceMappingURL=preferences-database.service.d.ts.map
@@ -1,23 +0,0 @@
1
- /**
2
- * Space/Group Configuration Service
3
- *
4
- * Per-space and per-group behavioral configuration stored in Firestore.
5
- * Controls moderation requirements, write modes, and other behavioral rules.
6
- */
7
- import type { WriteMode } from '../types/auth.js';
8
- export interface SpaceConfig {
9
- require_moderation: boolean;
10
- default_write_mode: WriteMode;
11
- }
12
- export declare const DEFAULT_SPACE_CONFIG: SpaceConfig;
13
- /**
14
- * Get configuration for a space or group.
15
- * Returns defaults merged with any stored config.
16
- */
17
- export declare function getSpaceConfig(id: string, type: 'space' | 'group'): Promise<SpaceConfig>;
18
- /**
19
- * Set configuration for a space or group.
20
- * Merges partial config with existing values.
21
- */
22
- export declare function setSpaceConfig(id: string, type: 'space' | 'group', config: Partial<SpaceConfig>): Promise<void>;
23
- //# sourceMappingURL=space-config.service.d.ts.map
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=space-config.service.spec.d.ts.map
@@ -1,193 +0,0 @@
1
- /**
2
- * Composite ID Utilities
3
- *
4
- * Provides utilities for working with composite IDs in Memory Collection Pattern v2.
5
- * Composite IDs preserve the source reference when memories are published to spaces or groups.
6
- *
7
- * Format: {userId}.{memoryId}
8
- * Example: "user123.my-recipe"
9
- */
10
-
11
- /**
12
- * Components of a composite ID
13
- */
14
- export interface CompositeIdComponents {
15
- userId: string
16
- memoryId: string
17
- }
18
-
19
- /**
20
- * Error thrown when composite ID is invalid
21
- */
22
- export class InvalidCompositeIdError extends Error {
23
- constructor(message: string) {
24
- super(message)
25
- this.name = 'InvalidCompositeIdError'
26
- }
27
- }
28
-
29
- /**
30
- * Generate a composite ID from user ID and memory ID
31
- *
32
- * @param userId - User ID (must not contain dots)
33
- * @param memoryId - Memory ID (must not contain dots)
34
- * @returns Composite ID in format {userId}.{memoryId}
35
- * @throws {InvalidCompositeIdError} If userId or memoryId contains dots
36
- *
37
- * @example
38
- * generateCompositeId('user123', 'my-recipe')
39
- * // Returns: 'user123.my-recipe'
40
- */
41
- export function generateCompositeId(userId: string, memoryId: string): string {
42
- // Validate that neither component contains dots
43
- if (userId.includes('.')) {
44
- throw new InvalidCompositeIdError(
45
- `User ID cannot contain dots: ${userId}`
46
- )
47
- }
48
-
49
- if (memoryId.includes('.')) {
50
- throw new InvalidCompositeIdError(
51
- `Memory ID cannot contain dots: ${memoryId}`
52
- )
53
- }
54
-
55
- // Validate that components are not empty
56
- if (!userId.trim()) {
57
- throw new InvalidCompositeIdError('User ID cannot be empty')
58
- }
59
-
60
- if (!memoryId.trim()) {
61
- throw new InvalidCompositeIdError('Memory ID cannot be empty')
62
- }
63
-
64
- return `${userId}.${memoryId}`
65
- }
66
-
67
- /**
68
- * Parse a composite ID into its components
69
- *
70
- * @param compositeId - Composite ID to parse
71
- * @returns Object with userId and memoryId
72
- * @throws {InvalidCompositeIdError} If composite ID format is invalid
73
- *
74
- * @example
75
- * parseCompositeId('user123.my-recipe')
76
- * // Returns: { userId: 'user123', memoryId: 'my-recipe' }
77
- */
78
- export function parseCompositeId(compositeId: string): CompositeIdComponents {
79
- // Split on first dot only (in case memoryId was generated with dashes that look like dots)
80
- const parts = compositeId.split('.')
81
-
82
- if (parts.length !== 2) {
83
- throw new InvalidCompositeIdError(
84
- `Invalid composite ID format: ${compositeId}. Composite ID must be exactly 2 parts separated by a dot. Expected format: {userId}.{memoryId}`
85
- )
86
- }
87
-
88
- const [userId, memoryId] = parts
89
-
90
- // Validate components are not empty
91
- if (!userId.trim()) {
92
- throw new InvalidCompositeIdError(
93
- `Invalid composite ID: ${compositeId}. User ID is empty`
94
- )
95
- }
96
-
97
- if (!memoryId.trim()) {
98
- throw new InvalidCompositeIdError(
99
- `Invalid composite ID: ${compositeId}. Memory ID is empty`
100
- )
101
- }
102
-
103
- return { userId, memoryId }
104
- }
105
-
106
- /**
107
- * Check if a string is a composite ID
108
- *
109
- * @param id - String to check
110
- * @returns true if valid composite ID, false otherwise
111
- *
112
- * @example
113
- * isCompositeId('user123.my-recipe') // true
114
- * isCompositeId('simple-id') // false
115
- * isCompositeId('too.many.dots') // false
116
- */
117
- export function isCompositeId(id: string): boolean {
118
- try {
119
- parseCompositeId(id)
120
- return true
121
- } catch (error) {
122
- if (error instanceof InvalidCompositeIdError) {
123
- return false
124
- }
125
- throw error
126
- }
127
- }
128
-
129
- /**
130
- * Validate a composite ID (returns true on valid, throws on invalid)
131
- *
132
- * @param id - Composite ID to validate
133
- * @returns true if valid
134
- * @throws {InvalidCompositeIdError} If composite ID is invalid
135
- *
136
- * @example
137
- * validateCompositeId('user123.my-recipe') // Returns true
138
- * validateCompositeId('invalid') // Throws InvalidCompositeIdError
139
- */
140
- export function validateCompositeId(id: string): true {
141
- parseCompositeId(id) // Will throw if invalid
142
- return true
143
- }
144
-
145
- /**
146
- * Extract user ID from a composite ID
147
- *
148
- * @param compositeId - Composite ID
149
- * @returns User ID component
150
- *
151
- * @example
152
- * getUserIdFromComposite('user123.my-recipe')
153
- * // Returns: 'user123'
154
- */
155
- export function getUserIdFromComposite(compositeId: string): string {
156
- const { userId } = parseCompositeId(compositeId)
157
- return userId
158
- }
159
-
160
- /**
161
- * Extract memory ID from a composite ID
162
- *
163
- * @param compositeId - Composite ID
164
- * @returns Memory ID component
165
- *
166
- * @example
167
- * getMemoryIdFromComposite('user123.my-recipe')
168
- * // Returns: 'my-recipe'
169
- */
170
- export function getMemoryIdFromComposite(compositeId: string): string {
171
- const { memoryId } = parseCompositeId(compositeId)
172
- return memoryId
173
- }
174
-
175
- /**
176
- * Check if an ID belongs to a specific user
177
- *
178
- * @param compositeId - Composite ID to check
179
- * @param userId - User ID to match
180
- * @returns true if composite ID belongs to user, false otherwise
181
- *
182
- * @example
183
- * belongsToUser('user123.my-recipe', 'user123') // true
184
- * belongsToUser('user123.my-recipe', 'user456') // false
185
- */
186
- export function belongsToUser(compositeId: string, userId: string): boolean {
187
- try {
188
- const { userId: idUserId } = parseCompositeId(compositeId)
189
- return idUserId === userId
190
- } catch {
191
- return false
192
- }
193
- }