@prmichaelsen/remember-mcp 2.5.2 → 2.6.2

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.
@@ -393,6 +393,99 @@ var require_main = __commonJS({
393
393
  }
394
394
  });
395
395
 
396
+ // src/config.ts
397
+ var import_dotenv, config;
398
+ var init_config = __esm({
399
+ "src/config.ts"() {
400
+ "use strict";
401
+ import_dotenv = __toESM(require_main(), 1);
402
+ import_dotenv.default.config();
403
+ config = {
404
+ // Weaviate
405
+ weaviate: {
406
+ url: process.env.WEAVIATE_REST_URL || "http://localhost:8080",
407
+ apiKey: process.env.WEAVIATE_API_KEY || ""
408
+ },
409
+ // OpenAI (for embeddings)
410
+ openai: {
411
+ apiKey: process.env.OPENAI_EMBEDDINGS_API_KEY || process.env.OPENAI_APIKEY || ""
412
+ },
413
+ // Firebase (using firebase-admin-sdk-v8)
414
+ firebase: {
415
+ serviceAccount: process.env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY || "",
416
+ projectId: process.env.FIREBASE_PROJECT_ID || ""
417
+ },
418
+ // Server
419
+ server: {
420
+ port: parseInt(process.env.PORT || "3000", 10),
421
+ nodeEnv: process.env.NODE_ENV || "development",
422
+ logLevel: process.env.LOG_LEVEL || "info"
423
+ },
424
+ // MCP
425
+ mcp: {
426
+ transport: process.env.MCP_TRANSPORT || "sse"
427
+ }
428
+ };
429
+ }
430
+ });
431
+
432
+ // src/utils/logger.ts
433
+ function shouldLog(level) {
434
+ return LOG_LEVELS[level] >= currentLevel;
435
+ }
436
+ var LOG_LEVELS, currentLevel, logger;
437
+ var init_logger = __esm({
438
+ "src/utils/logger.ts"() {
439
+ "use strict";
440
+ init_config();
441
+ LOG_LEVELS = {
442
+ debug: 0,
443
+ info: 1,
444
+ warn: 2,
445
+ error: 3
446
+ };
447
+ currentLevel = LOG_LEVELS[config.server.logLevel] ?? LOG_LEVELS.info;
448
+ logger = {
449
+ debug: (message, data) => {
450
+ if (shouldLog("debug")) {
451
+ if (data) {
452
+ console.debug(JSON.stringify({ level: "DEBUG", message, ...data }));
453
+ } else {
454
+ console.debug(`[DEBUG] ${message}`);
455
+ }
456
+ }
457
+ },
458
+ info: (message, data) => {
459
+ if (shouldLog("info")) {
460
+ if (data) {
461
+ console.info(JSON.stringify({ level: "INFO", message, ...data }));
462
+ } else {
463
+ console.info(`[INFO] ${message}`);
464
+ }
465
+ }
466
+ },
467
+ warn: (message, data) => {
468
+ if (shouldLog("warn")) {
469
+ if (data) {
470
+ console.warn(JSON.stringify({ level: "WARN", message, ...data }));
471
+ } else {
472
+ console.warn(`[WARN] ${message}`);
473
+ }
474
+ }
475
+ },
476
+ error: (message, data) => {
477
+ if (shouldLog("error")) {
478
+ if (data) {
479
+ console.error(JSON.stringify({ level: "ERROR", message, ...data }));
480
+ } else {
481
+ console.error(`[ERROR] ${message}`);
482
+ }
483
+ }
484
+ }
485
+ };
486
+ }
487
+ });
488
+
396
489
  // src/types/space-memory.ts
397
490
  var SUPPORTED_SPACES;
398
491
  var init_space_memory = __esm({
@@ -403,6 +496,7 @@ var init_space_memory = __esm({
403
496
  });
404
497
 
405
498
  // src/server-factory.ts
499
+ init_logger();
406
500
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
407
501
  import {
408
502
  CallToolRequestSchema,
@@ -411,87 +505,9 @@ import {
411
505
  McpError
412
506
  } from "@modelcontextprotocol/sdk/types.js";
413
507
 
414
- // src/config.ts
415
- var import_dotenv = __toESM(require_main(), 1);
416
- import_dotenv.default.config();
417
- var config = {
418
- // Weaviate
419
- weaviate: {
420
- url: process.env.WEAVIATE_REST_URL || "http://localhost:8080",
421
- apiKey: process.env.WEAVIATE_API_KEY || ""
422
- },
423
- // OpenAI (for embeddings)
424
- openai: {
425
- apiKey: process.env.OPENAI_EMBEDDINGS_API_KEY || process.env.OPENAI_APIKEY || ""
426
- },
427
- // Firebase (using firebase-admin-sdk-v8)
428
- firebase: {
429
- serviceAccount: process.env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY || "",
430
- projectId: process.env.FIREBASE_PROJECT_ID || ""
431
- },
432
- // Server
433
- server: {
434
- port: parseInt(process.env.PORT || "3000", 10),
435
- nodeEnv: process.env.NODE_ENV || "development",
436
- logLevel: process.env.LOG_LEVEL || "info"
437
- },
438
- // MCP
439
- mcp: {
440
- transport: process.env.MCP_TRANSPORT || "sse"
441
- }
442
- };
443
-
444
- // src/utils/logger.ts
445
- var LOG_LEVELS = {
446
- debug: 0,
447
- info: 1,
448
- warn: 2,
449
- error: 3
450
- };
451
- var currentLevel = LOG_LEVELS[config.server.logLevel] ?? LOG_LEVELS.info;
452
- function shouldLog(level) {
453
- return LOG_LEVELS[level] >= currentLevel;
454
- }
455
- var logger = {
456
- debug: (message, data) => {
457
- if (shouldLog("debug")) {
458
- if (data) {
459
- console.debug(JSON.stringify({ level: "DEBUG", message, ...data }));
460
- } else {
461
- console.debug(`[DEBUG] ${message}`);
462
- }
463
- }
464
- },
465
- info: (message, data) => {
466
- if (shouldLog("info")) {
467
- if (data) {
468
- console.info(JSON.stringify({ level: "INFO", message, ...data }));
469
- } else {
470
- console.info(`[INFO] ${message}`);
471
- }
472
- }
473
- },
474
- warn: (message, data) => {
475
- if (shouldLog("warn")) {
476
- if (data) {
477
- console.warn(JSON.stringify({ level: "WARN", message, ...data }));
478
- } else {
479
- console.warn(`[WARN] ${message}`);
480
- }
481
- }
482
- },
483
- error: (message, data) => {
484
- if (shouldLog("error")) {
485
- if (data) {
486
- console.error(JSON.stringify({ level: "ERROR", message, ...data }));
487
- } else {
488
- console.error(`[ERROR] ${message}`);
489
- }
490
- }
491
- }
492
- };
493
-
494
508
  // src/weaviate/client.ts
509
+ init_config();
510
+ init_logger();
495
511
  import weaviate from "weaviate-client";
496
512
  var client = null;
497
513
  async function initWeaviateClient() {
@@ -501,13 +517,19 @@ async function initWeaviateClient() {
501
517
  const weaviateUrl = config.weaviate.url;
502
518
  const isLocal = weaviateUrl.includes("localhost") || weaviateUrl.includes("127.0.0.1");
503
519
  if (!isLocal) {
504
- console.log("[Weaviate] Connecting to remote Weaviate:", weaviateUrl);
520
+ logger.info("Connecting to remote Weaviate", {
521
+ module: "weaviate-client",
522
+ url: weaviateUrl
523
+ });
505
524
  client = await weaviate.connectToWeaviateCloud(weaviateUrl, {
506
525
  authCredentials: config.weaviate.apiKey ? new weaviate.ApiKey(config.weaviate.apiKey) : void 0,
507
526
  headers: config.openai.apiKey ? { "X-OpenAI-Api-Key": config.openai.apiKey } : void 0
508
527
  });
509
528
  } else {
510
- console.log("[Weaviate] Connecting to local Weaviate:", weaviateUrl);
529
+ logger.info("Connecting to local Weaviate", {
530
+ module: "weaviate-client",
531
+ url: weaviateUrl
532
+ });
511
533
  const localConfig = {
512
534
  host: weaviateUrl.replace(/^https?:\/\//, "").split(":")[0],
513
535
  port: weaviateUrl.includes(":") ? parseInt(weaviateUrl.split(":").pop() || "8080") : 8080,
@@ -521,7 +543,10 @@ async function initWeaviateClient() {
521
543
  }
522
544
  client = await weaviate.connectToLocal(localConfig);
523
545
  }
524
- console.log("[Weaviate] Client initialized successfully");
546
+ logger.info("Weaviate client initialized successfully", {
547
+ module: "weaviate-client",
548
+ isLocal
549
+ });
525
550
  return client;
526
551
  }
527
552
  function getWeaviateClient() {
@@ -542,6 +567,8 @@ function getMemoryCollectionName(userId) {
542
567
  }
543
568
 
544
569
  // src/firestore/init.ts
570
+ init_config();
571
+ init_logger();
545
572
  import { initializeApp } from "@prmichaelsen/firebase-admin-sdk-v8";
546
573
  import {
547
574
  getDocument,
@@ -566,26 +593,42 @@ function initFirestore() {
566
593
  projectId: config.firebase.projectId
567
594
  });
568
595
  initialized = true;
569
- console.log("[Firestore] Initialized successfully");
596
+ logger.info("Firestore initialized successfully", {
597
+ module: "firestore-init"
598
+ });
570
599
  } catch (error) {
571
- console.error("[Firestore] Initialization failed:", error);
572
- console.error("[Firestore] Make sure FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY is valid JSON");
573
- console.error("[Firestore] Check for proper escaping in .env file");
600
+ logger.error("Firestore initialization failed", {
601
+ module: "firestore-init",
602
+ error: error instanceof Error ? error.message : String(error)
603
+ });
604
+ logger.error("Make sure FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY is valid JSON", {
605
+ module: "firestore-init"
606
+ });
607
+ logger.error("Check for proper escaping in .env file", {
608
+ module: "firestore-init"
609
+ });
574
610
  throw error;
575
611
  }
576
612
  }
577
613
 
578
614
  // src/weaviate/schema.ts
579
615
  import weaviate2 from "weaviate-client";
616
+ init_logger();
580
617
  async function createMemoryCollection(userId) {
581
618
  const client2 = getWeaviateClient();
582
619
  const collectionName = `Memory_${sanitizeUserId(userId)}`;
583
620
  const exists = await client2.collections.exists(collectionName);
584
621
  if (exists) {
585
- console.log(`[Weaviate] Collection ${collectionName} already exists`);
622
+ logger.debug("Collection already exists", {
623
+ module: "weaviate-schema",
624
+ collectionName
625
+ });
586
626
  return;
587
627
  }
588
- console.log(`[Weaviate] Creating collection ${collectionName}...`);
628
+ logger.info("Creating memory collection", {
629
+ module: "weaviate-schema",
630
+ collectionName
631
+ });
589
632
  await client2.collections.create({
590
633
  name: collectionName,
591
634
  // Vectorizer configuration
@@ -782,10 +825,29 @@ async function createMemoryCollection(userId) {
782
825
  name: "computed_weight",
783
826
  dataType: "number",
784
827
  description: "Calculated effective weight"
828
+ },
829
+ // Comment/threading fields (for threaded discussions in shared spaces)
830
+ {
831
+ name: "parent_id",
832
+ dataType: "text",
833
+ description: "ID of parent memory or comment (for threading)"
834
+ },
835
+ {
836
+ name: "thread_root_id",
837
+ dataType: "text",
838
+ description: "Root memory ID for fetching entire thread"
839
+ },
840
+ {
841
+ name: "moderation_flags",
842
+ dataType: "text[]",
843
+ description: 'Per-space moderation flags (format: "{space_id}:{flag_type}")'
785
844
  }
786
845
  ]
787
846
  });
788
- console.log(`[Weaviate] Collection ${collectionName} created successfully`);
847
+ logger.info("Memory collection created successfully", {
848
+ module: "weaviate-schema",
849
+ collectionName
850
+ });
789
851
  }
790
852
  async function ensureMemoryCollection(userId) {
791
853
  const client2 = getWeaviateClient();
@@ -801,7 +863,11 @@ function getMemoryCollection(userId) {
801
863
  return client2.collections.get(collectionName);
802
864
  }
803
865
 
866
+ // src/tools/create-memory.ts
867
+ init_logger();
868
+
804
869
  // src/utils/error-handler.ts
870
+ init_logger();
805
871
  function formatDetailedError(error, context) {
806
872
  const errorMessage = error instanceof Error ? error.message : String(error);
807
873
  const errorStack = error instanceof Error ? error.stack : void 0;
@@ -1353,6 +1419,9 @@ async function handleCreateMemory(args, userId, context) {
1353
1419
  }
1354
1420
  }
1355
1421
 
1422
+ // src/tools/search-memory.ts
1423
+ init_logger();
1424
+
1356
1425
  // src/utils/weaviate-filters.ts
1357
1426
  import { Filters } from "weaviate-client";
1358
1427
  function buildCombinedSearchFilters(collection, filters) {
@@ -1620,6 +1689,7 @@ async function handleSearchMemory(args, userId) {
1620
1689
  }
1621
1690
 
1622
1691
  // src/tools/delete-memory.ts
1692
+ init_logger();
1623
1693
  var deleteMemoryTool = {
1624
1694
  name: "remember_delete_memory",
1625
1695
  description: `Delete a memory from your collection.
@@ -1700,6 +1770,7 @@ async function handleDeleteMemory(args, userId) {
1700
1770
  }
1701
1771
 
1702
1772
  // src/tools/update-memory.ts
1773
+ init_logger();
1703
1774
  var updateMemoryTool = {
1704
1775
  name: "remember_update_memory",
1705
1776
  description: `Update an existing memory with partial updates.
@@ -1885,6 +1956,7 @@ async function handleUpdateMemory(args, userId) {
1885
1956
  }
1886
1957
 
1887
1958
  // src/tools/find-similar.ts
1959
+ init_logger();
1888
1960
  var findSimilarTool = {
1889
1961
  name: "remember_find_similar",
1890
1962
  description: `Find memories similar to a given memory or text using vector similarity.
@@ -2016,6 +2088,7 @@ async function handleFindSimilar(args, userId) {
2016
2088
  }
2017
2089
 
2018
2090
  // src/tools/query-memory.ts
2091
+ init_logger();
2019
2092
  var queryMemoryTool = {
2020
2093
  name: "remember_query_memory",
2021
2094
  description: `Query memories using natural language for RAG (Retrieval-Augmented Generation).
@@ -2197,6 +2270,7 @@ ${content}${tags}`;
2197
2270
  }
2198
2271
 
2199
2272
  // src/tools/create-relationship.ts
2273
+ init_logger();
2200
2274
  var createRelationshipTool = {
2201
2275
  name: "remember_create_relationship",
2202
2276
  description: `Create a relationship connecting 2 or more memories.
@@ -2403,6 +2477,7 @@ async function handleCreateRelationship(args, userId, context) {
2403
2477
  }
2404
2478
 
2405
2479
  // src/tools/update-relationship.ts
2480
+ init_logger();
2406
2481
  var updateRelationshipTool = {
2407
2482
  name: "remember_update_relationship",
2408
2483
  description: `Update an existing relationship with partial updates.
@@ -2533,6 +2608,7 @@ async function handleUpdateRelationship(args, userId) {
2533
2608
 
2534
2609
  // src/tools/search-relationship.ts
2535
2610
  import { Filters as Filters2 } from "weaviate-client";
2611
+ init_logger();
2536
2612
  var searchRelationshipTool = {
2537
2613
  name: "remember_search_relationship",
2538
2614
  description: `Search relationships by observation text or relationship type.
@@ -2686,6 +2762,7 @@ async function handleSearchRelationship(args, userId) {
2686
2762
  }
2687
2763
 
2688
2764
  // src/tools/delete-relationship.ts
2765
+ init_logger();
2689
2766
  var deleteRelationshipTool = {
2690
2767
  name: "remember_delete_relationship",
2691
2768
  description: `Delete a relationship from your collection.
@@ -2813,6 +2890,9 @@ function getUserPreferencesPath(userId) {
2813
2890
  return `${BASE}.users/${userId}/preferences`;
2814
2891
  }
2815
2892
 
2893
+ // src/services/preferences-database.service.ts
2894
+ init_logger();
2895
+
2816
2896
  // src/types/preferences.ts
2817
2897
  var DEFAULT_PREFERENCES = {
2818
2898
  templates: {
@@ -3077,6 +3157,7 @@ var PreferencesDatabaseService = class {
3077
3157
  };
3078
3158
 
3079
3159
  // src/tools/set-preference.ts
3160
+ init_logger();
3080
3161
  var setPreferenceTool = {
3081
3162
  name: "remember_set_preference",
3082
3163
  description: `Update user preferences for system behavior through natural conversation.
@@ -3167,6 +3248,7 @@ async function handleSetPreference(args, userId) {
3167
3248
  }
3168
3249
 
3169
3250
  // src/tools/get-preferences.ts
3251
+ init_logger();
3170
3252
  var getPreferencesTool = {
3171
3253
  name: "remember_get_preferences",
3172
3254
  description: `Get current user preferences.
@@ -3229,6 +3311,7 @@ async function handleGetPreferences(args, userId) {
3229
3311
 
3230
3312
  // src/services/confirmation-token.service.ts
3231
3313
  import { randomUUID } from "crypto";
3314
+ init_logger();
3232
3315
  var ConfirmationTokenService = class {
3233
3316
  EXPIRY_MINUTES = 5;
3234
3317
  /**
@@ -3256,27 +3339,29 @@ var ConfirmationTokenService = class {
3256
3339
  status: "pending"
3257
3340
  };
3258
3341
  const collectionPath = `users/${userId}/requests`;
3259
- console.log("[ConfirmationTokenService] Creating request:", {
3342
+ logger.info("Creating confirmation request", {
3343
+ service: "ConfirmationTokenService",
3260
3344
  userId,
3261
3345
  action,
3262
3346
  targetCollection,
3263
3347
  collectionPath,
3264
- requestData: {
3265
- token,
3266
- action,
3267
- payloadKeys: Object.keys(payload)
3268
- }
3348
+ payloadKeys: Object.keys(payload)
3349
+ });
3350
+ logger.debug("Calling Firestore addDocument", {
3351
+ service: "ConfirmationTokenService",
3352
+ collectionPath
3269
3353
  });
3270
- console.log("[ConfirmationTokenService] Calling addDocument...");
3271
3354
  const docRef = await addDocument(collectionPath, request);
3272
- console.log("[ConfirmationTokenService] addDocument returned:", {
3355
+ logger.debug("Firestore addDocument returned", {
3356
+ service: "ConfirmationTokenService",
3273
3357
  hasDocRef: !!docRef,
3274
3358
  hasId: !!docRef?.id,
3275
3359
  docRefId: docRef?.id
3276
3360
  });
3277
3361
  if (!docRef) {
3278
3362
  const error = new Error("Firestore addDocument returned null/undefined");
3279
- console.error("[ConfirmationTokenService] CRITICAL: addDocument returned null", {
3363
+ logger.error("CRITICAL: addDocument returned null", {
3364
+ service: "ConfirmationTokenService",
3280
3365
  userId,
3281
3366
  collectionPath
3282
3367
  });
@@ -3284,21 +3369,24 @@ var ConfirmationTokenService = class {
3284
3369
  }
3285
3370
  if (!docRef.id) {
3286
3371
  const error = new Error("Firestore addDocument returned docRef without ID");
3287
- console.error("[ConfirmationTokenService] CRITICAL: docRef has no ID", {
3372
+ logger.error("CRITICAL: docRef has no ID", {
3373
+ service: "ConfirmationTokenService",
3288
3374
  userId,
3289
3375
  collectionPath,
3290
3376
  docRef
3291
3377
  });
3292
3378
  throw error;
3293
3379
  }
3294
- console.log("[ConfirmationTokenService] Request created successfully:", {
3380
+ logger.info("Confirmation request created successfully", {
3381
+ service: "ConfirmationTokenService",
3295
3382
  requestId: docRef.id,
3296
3383
  token,
3297
3384
  expiresAt: request.expires_at
3298
3385
  });
3299
3386
  return { requestId: docRef.id, token };
3300
3387
  } catch (error) {
3301
- console.error("[ConfirmationTokenService] FAILED to create request:", {
3388
+ logger.error("Failed to create confirmation request", {
3389
+ service: "ConfirmationTokenService",
3302
3390
  error: error instanceof Error ? error.message : String(error),
3303
3391
  stack: error instanceof Error ? error.stack : void 0,
3304
3392
  userId,
@@ -3317,7 +3405,8 @@ var ConfirmationTokenService = class {
3317
3405
  */
3318
3406
  async validateToken(userId, token) {
3319
3407
  const collectionPath = `users/${userId}/requests`;
3320
- console.log("[ConfirmationTokenService] Validating token:", {
3408
+ logger.debug("Validating confirmation token", {
3409
+ service: "ConfirmationTokenService",
3321
3410
  userId,
3322
3411
  token,
3323
3412
  collectionPath
@@ -3330,17 +3419,22 @@ var ConfirmationTokenService = class {
3330
3419
  limit: 1
3331
3420
  };
3332
3421
  const results = await queryDocuments(collectionPath, queryOptions);
3333
- console.log("[ConfirmationTokenService] Query results:", {
3422
+ logger.debug("Token query results", {
3423
+ service: "ConfirmationTokenService",
3334
3424
  resultsFound: results.length,
3335
3425
  hasResults: results.length > 0
3336
3426
  });
3337
3427
  if (results.length === 0) {
3338
- console.log("[ConfirmationTokenService] Token not found or not pending");
3428
+ logger.info("Token not found or not pending", {
3429
+ service: "ConfirmationTokenService",
3430
+ userId
3431
+ });
3339
3432
  return null;
3340
3433
  }
3341
3434
  const doc = results[0];
3342
3435
  const request = doc.data;
3343
- console.log("[ConfirmationTokenService] Request found:", {
3436
+ logger.info("Confirmation request found", {
3437
+ service: "ConfirmationTokenService",
3344
3438
  requestId: doc.id,
3345
3439
  action: request.action,
3346
3440
  status: request.status,
@@ -3348,7 +3442,11 @@ var ConfirmationTokenService = class {
3348
3442
  });
3349
3443
  const expiresAt = new Date(request.expires_at);
3350
3444
  if (expiresAt.getTime() < Date.now()) {
3351
- console.log("[ConfirmationTokenService] Token expired");
3445
+ logger.info("Token expired", {
3446
+ service: "ConfirmationTokenService",
3447
+ requestId: doc.id,
3448
+ expiresAt: request.expires_at
3449
+ });
3352
3450
  await this.updateStatus(userId, doc.id, "expired");
3353
3451
  return null;
3354
3452
  }
@@ -3434,7 +3532,10 @@ var ConfirmationTokenService = class {
3434
3532
  * @returns Count of deleted requests
3435
3533
  */
3436
3534
  async cleanupExpired() {
3437
- console.warn("[ConfirmationTokenService] cleanupExpired not implemented - rely on Firestore TTL");
3535
+ logger.warn("cleanupExpired not implemented - relying on Firestore TTL", {
3536
+ service: "ConfirmationTokenService",
3537
+ note: "Configure Firestore TTL policy on requests collection group"
3538
+ });
3438
3539
  return 0;
3439
3540
  }
3440
3541
  };
@@ -3442,6 +3543,7 @@ var confirmationTokenService = new ConfirmationTokenService();
3442
3543
 
3443
3544
  // src/weaviate/space-schema.ts
3444
3545
  init_space_memory();
3546
+ init_logger();
3445
3547
  import weaviate3 from "weaviate-client";
3446
3548
  var PUBLIC_COLLECTION_NAME = "Memory_public";
3447
3549
  function getSpaceCollectionName(spaceId) {
@@ -3452,7 +3554,11 @@ function isValidSpaceId(spaceId) {
3452
3554
  }
3453
3555
  async function createSpaceCollection(client2, spaceId) {
3454
3556
  const collectionName = spaceId === "public" ? PUBLIC_COLLECTION_NAME : getSpaceCollectionName(spaceId);
3455
- console.log(`[Weaviate] Creating space collection ${collectionName}...`);
3557
+ logger.info("Creating space collection", {
3558
+ module: "weaviate-space-schema",
3559
+ collectionName,
3560
+ spaceId
3561
+ });
3456
3562
  await client2.collections.create({
3457
3563
  name: collectionName,
3458
3564
  // Vectorizer configuration
@@ -3606,10 +3712,29 @@ async function createSpaceCollection(client2, spaceId) {
3606
3712
  name: "version",
3607
3713
  dataType: "number",
3608
3714
  description: "Version number (increments on update)"
3715
+ },
3716
+ // Comment/threading fields (for threaded discussions in shared spaces)
3717
+ {
3718
+ name: "parent_id",
3719
+ dataType: "text",
3720
+ description: "ID of parent memory or comment (for threading)"
3721
+ },
3722
+ {
3723
+ name: "thread_root_id",
3724
+ dataType: "text",
3725
+ description: "Root memory ID for fetching entire thread"
3726
+ },
3727
+ {
3728
+ name: "moderation_flags",
3729
+ dataType: "text[]",
3730
+ description: 'Per-space moderation flags (format: "{space_id}:{flag_type}")'
3609
3731
  }
3610
3732
  ]
3611
3733
  });
3612
- console.log(`[Weaviate] Space collection ${collectionName} created successfully`);
3734
+ logger.info("Space collection created successfully", {
3735
+ module: "weaviate-space-schema",
3736
+ collectionName
3737
+ });
3613
3738
  }
3614
3739
  async function ensurePublicCollection(client2) {
3615
3740
  const collectionName = PUBLIC_COLLECTION_NAME;
@@ -3622,6 +3747,7 @@ async function ensurePublicCollection(client2) {
3622
3747
 
3623
3748
  // src/tools/publish.ts
3624
3749
  init_space_memory();
3750
+ init_logger();
3625
3751
  var publishTool = {
3626
3752
  name: "remember_publish",
3627
3753
  description: 'Publish a memory to one or more shared spaces (like "The Void"). The memory will be COPIED (not moved) from your personal collection. Generates a confirmation token. Use remember_confirm to execute.',
@@ -3654,7 +3780,8 @@ var publishTool = {
3654
3780
  };
3655
3781
  async function handlePublish(args, userId) {
3656
3782
  try {
3657
- console.log("[remember_publish] Starting publish request:", {
3783
+ logger.info("Starting publish request", {
3784
+ tool: "remember_publish",
3658
3785
  userId,
3659
3786
  memoryId: args.memory_id,
3660
3787
  spaces: args.spaces,
@@ -3663,7 +3790,11 @@ async function handlePublish(args, userId) {
3663
3790
  });
3664
3791
  const invalidSpaces = args.spaces.filter((s) => !isValidSpaceId(s));
3665
3792
  if (invalidSpaces.length > 0) {
3666
- console.log("[remember_publish] Invalid space IDs:", invalidSpaces);
3793
+ logger.warn("Invalid space IDs provided", {
3794
+ tool: "remember_publish",
3795
+ invalidSpaces,
3796
+ providedSpaces: args.spaces
3797
+ });
3667
3798
  return JSON.stringify(
3668
3799
  {
3669
3800
  success: false,
@@ -3680,7 +3811,10 @@ async function handlePublish(args, userId) {
3680
3811
  );
3681
3812
  }
3682
3813
  if (args.spaces.length === 0) {
3683
- console.log("[remember_publish] Empty spaces array");
3814
+ logger.warn("Empty spaces array provided", {
3815
+ tool: "remember_publish",
3816
+ userId
3817
+ });
3684
3818
  return JSON.stringify(
3685
3819
  {
3686
3820
  success: false,
@@ -3693,15 +3827,24 @@ async function handlePublish(args, userId) {
3693
3827
  }
3694
3828
  const weaviateClient = getWeaviateClient();
3695
3829
  const collectionName = getMemoryCollectionName(userId);
3696
- console.log("[remember_publish] Fetching memory from collection:", collectionName);
3830
+ logger.debug("Fetching memory from collection", {
3831
+ tool: "remember_publish",
3832
+ collectionName,
3833
+ memoryId: args.memory_id
3834
+ });
3697
3835
  const userCollection = weaviateClient.collections.get(collectionName);
3698
3836
  const memory = await userCollection.query.fetchObjectById(args.memory_id);
3699
- console.log("[remember_publish] Memory fetch result:", {
3837
+ logger.debug("Memory fetch result", {
3838
+ tool: "remember_publish",
3700
3839
  found: !!memory,
3701
3840
  memoryId: args.memory_id
3702
3841
  });
3703
3842
  if (!memory) {
3704
- console.log("[remember_publish] Memory not found");
3843
+ logger.info("Memory not found", {
3844
+ tool: "remember_publish",
3845
+ memoryId: args.memory_id,
3846
+ collectionName
3847
+ });
3705
3848
  return JSON.stringify(
3706
3849
  {
3707
3850
  success: false,
@@ -3752,7 +3895,12 @@ async function handlePublish(args, userId) {
3752
3895
  spaces: args.spaces,
3753
3896
  additional_tags: args.additional_tags || []
3754
3897
  };
3755
- console.log("[remember_publish] Generating confirmation token");
3898
+ logger.info("Generating confirmation token", {
3899
+ tool: "remember_publish",
3900
+ userId,
3901
+ memoryId: args.memory_id,
3902
+ spaces: args.spaces
3903
+ });
3756
3904
  const { requestId, token } = await confirmationTokenService.createRequest(
3757
3905
  userId,
3758
3906
  "publish_memory",
@@ -3760,10 +3908,12 @@ async function handlePublish(args, userId) {
3760
3908
  void 0
3761
3909
  // No single target_collection anymore
3762
3910
  );
3763
- console.log("[remember_publish] Token generated:", {
3911
+ logger.info("Confirmation token generated", {
3912
+ tool: "remember_publish",
3764
3913
  requestId,
3765
3914
  token,
3766
- action: "publish_memory"
3915
+ action: "publish_memory",
3916
+ spaces: args.spaces
3767
3917
  });
3768
3918
  return JSON.stringify(
3769
3919
  {
@@ -3785,9 +3935,20 @@ async function handlePublish(args, userId) {
3785
3935
  }
3786
3936
 
3787
3937
  // src/tools/confirm.ts
3938
+ init_logger();
3788
3939
  var confirmTool = {
3789
3940
  name: "remember_confirm",
3790
- description: "Confirm and execute a pending action using the token. Works for any action that requires confirmation (publish, delete, etc.).",
3941
+ description: `Confirm and execute a pending action using the token. Works for any action that requires confirmation (publish, delete, etc.).
3942
+
3943
+ \u26A0\uFE0F CRITICAL SAFETY REQUIREMENTS:
3944
+ Before executing this tool, you MUST:
3945
+ 1. Have received the confirmation token in a PREVIOUS tool response
3946
+ 2. Have presented the token details to the user for review
3947
+ 3. Have received EXPLICIT user confirmation in a SEPARATE user message
3948
+ 4. NEVER chain this tool with other tool calls in the same response
3949
+ 5. ALWAYS treat confirmations as standalone, deliberate actions
3950
+
3951
+ Violating these requirements bypasses user consent and is a security violation.`,
3791
3952
  inputSchema: {
3792
3953
  type: "object",
3793
3954
  properties: {
@@ -3801,17 +3962,22 @@ var confirmTool = {
3801
3962
  };
3802
3963
  async function handleConfirm(args, userId) {
3803
3964
  try {
3804
- console.log("[remember_confirm] Starting confirmation:", {
3965
+ logger.info("Starting confirmation", {
3966
+ tool: "remember_confirm",
3805
3967
  userId,
3806
3968
  token: args.token
3807
3969
  });
3808
3970
  const request = await confirmationTokenService.confirmRequest(userId, args.token);
3809
- console.log("[remember_confirm] Token validation result:", {
3971
+ logger.debug("Token validation result", {
3972
+ tool: "remember_confirm",
3810
3973
  requestFound: !!request,
3811
3974
  action: request?.action
3812
3975
  });
3813
3976
  if (!request) {
3814
- console.log("[remember_confirm] Token invalid or expired");
3977
+ logger.info("Token invalid or expired", {
3978
+ tool: "remember_confirm",
3979
+ userId
3980
+ });
3815
3981
  return JSON.stringify(
3816
3982
  {
3817
3983
  success: false,
@@ -3822,7 +3988,11 @@ async function handleConfirm(args, userId) {
3822
3988
  2
3823
3989
  );
3824
3990
  }
3825
- console.log("[remember_confirm] Executing action:", request.action);
3991
+ logger.info("Executing confirmed action", {
3992
+ tool: "remember_confirm",
3993
+ action: request.action,
3994
+ userId
3995
+ });
3826
3996
  if (request.action === "publish_memory") {
3827
3997
  return await executePublishMemory(request, userId);
3828
3998
  }
@@ -3838,7 +4008,8 @@ async function handleConfirm(args, userId) {
3838
4008
  }
3839
4009
  async function executePublishMemory(request, userId) {
3840
4010
  try {
3841
- console.log("[executePublishMemory] Starting execution:", {
4011
+ logger.info("Executing publish memory action", {
4012
+ function: "executePublishMemory",
3842
4013
  userId,
3843
4014
  memoryId: request.payload.memory_id,
3844
4015
  spaces: request.payload.spaces,
@@ -3848,16 +4019,24 @@ async function executePublishMemory(request, userId) {
3848
4019
  const userCollection = weaviateClient.collections.get(
3849
4020
  getMemoryCollectionName(userId)
3850
4021
  );
3851
- console.log("[executePublishMemory] Fetching original memory from:", getMemoryCollectionName(userId));
4022
+ logger.debug("Fetching original memory", {
4023
+ function: "executePublishMemory",
4024
+ collectionName: getMemoryCollectionName(userId),
4025
+ memoryId: request.payload.memory_id
4026
+ });
3852
4027
  const originalMemory = await userCollection.query.fetchObjectById(
3853
4028
  request.payload.memory_id
3854
4029
  );
3855
- console.log("[executePublishMemory] Original memory fetch result:", {
4030
+ logger.debug("Original memory fetch result", {
4031
+ function: "executePublishMemory",
3856
4032
  found: !!originalMemory,
3857
4033
  memoryId: request.payload.memory_id
3858
4034
  });
3859
4035
  if (!originalMemory) {
3860
- console.log("[executePublishMemory] Memory not found");
4036
+ logger.info("Original memory not found", {
4037
+ function: "executePublishMemory",
4038
+ memoryId: request.payload.memory_id
4039
+ });
3861
4040
  return JSON.stringify(
3862
4041
  {
3863
4042
  success: false,
@@ -3869,7 +4048,12 @@ async function executePublishMemory(request, userId) {
3869
4048
  );
3870
4049
  }
3871
4050
  if (originalMemory.properties.user_id !== userId) {
3872
- console.log("[executePublishMemory] Permission denied - wrong owner");
4051
+ logger.warn("Permission denied - wrong owner", {
4052
+ function: "executePublishMemory",
4053
+ memoryId: request.payload.memory_id,
4054
+ memoryOwner: originalMemory.properties.user_id,
4055
+ requestingUser: userId
4056
+ });
3873
4057
  return JSON.stringify(
3874
4058
  {
3875
4059
  success: false,
@@ -3880,9 +4064,14 @@ async function executePublishMemory(request, userId) {
3880
4064
  2
3881
4065
  );
3882
4066
  }
3883
- console.log("[executePublishMemory] Ensuring public collection");
4067
+ logger.debug("Ensuring public collection exists", {
4068
+ function: "executePublishMemory"
4069
+ });
3884
4070
  const publicCollection = await ensurePublicCollection(weaviateClient);
3885
- console.log("[executePublishMemory] Public collection ready");
4071
+ logger.debug("Public collection ready", {
4072
+ function: "executePublishMemory",
4073
+ collectionName: "Memory_public"
4074
+ });
3886
4075
  const originalTags = Array.isArray(originalMemory.properties.tags) ? originalMemory.properties.tags : [];
3887
4076
  const additionalTags = Array.isArray(request.payload.additional_tags) ? request.payload.additional_tags : [];
3888
4077
  const publishedMemory = {
@@ -3903,7 +4092,8 @@ async function executePublishMemory(request, userId) {
3903
4092
  updated_at: (/* @__PURE__ */ new Date()).toISOString(),
3904
4093
  version: 1
3905
4094
  };
3906
- console.log("[executePublishMemory] Inserting into Memory_public:", {
4095
+ logger.info("Inserting memory into Memory_public", {
4096
+ function: "executePublishMemory",
3907
4097
  spaces: request.payload.spaces,
3908
4098
  spaceCount: request.payload.spaces?.length || 0,
3909
4099
  memoryId: request.payload.memory_id,
@@ -3911,9 +4101,10 @@ async function executePublishMemory(request, userId) {
3911
4101
  hasAuthorId: !!publishedMemory.author_id
3912
4102
  });
3913
4103
  const result = await publicCollection.data.insert(publishedMemory);
3914
- console.log("[executePublishMemory] Insert result:", {
3915
- success: !!result,
3916
- spaceMemoryId: result
4104
+ logger.info("Memory published successfully", {
4105
+ function: "executePublishMemory",
4106
+ spaceMemoryId: result,
4107
+ spaces: request.payload.spaces
3917
4108
  });
3918
4109
  return JSON.stringify(
3919
4110
  {
@@ -3937,7 +4128,17 @@ async function executePublishMemory(request, userId) {
3937
4128
  // src/tools/deny.ts
3938
4129
  var denyTool = {
3939
4130
  name: "remember_deny",
3940
- description: "Deny a pending action. The request will be marked as denied and the token invalidated. Works for any action that requires confirmation.",
4131
+ description: `Deny a pending action. The request will be marked as denied and the token invalidated. Works for any action that requires confirmation.
4132
+
4133
+ \u26A0\uFE0F CRITICAL SAFETY REQUIREMENTS:
4134
+ Before executing this tool, you MUST:
4135
+ 1. Have received the confirmation token in a PREVIOUS tool response
4136
+ 2. Have presented the token details to the user for review
4137
+ 3. Have received EXPLICIT user denial in a SEPARATE user message
4138
+ 4. NEVER chain this tool with other tool calls in the same response
4139
+ 5. ALWAYS treat denials as standalone, deliberate actions
4140
+
4141
+ This ensures proper user consent workflow is followed.`,
3941
4142
  inputSchema: {
3942
4143
  type: "object",
3943
4144
  properties: {
@@ -3985,7 +4186,7 @@ import { Filters as Filters3 } from "weaviate-client";
3985
4186
  init_space_memory();
3986
4187
  var searchSpaceTool = {
3987
4188
  name: "remember_search_space",
3988
- description: "Search one or more shared spaces to discover thoughts, ideas, and memories. Works like remember_search_memory but searches shared spaces instead of personal memories. Can search multiple spaces in a single query.",
4189
+ description: "Search one or more shared spaces to discover thoughts, ideas, and memories. By default, excludes comments to keep discovery clean. Set include_comments: true to include threaded discussions. Can search multiple spaces in a single query.",
3989
4190
  inputSchema: {
3990
4191
  type: "object",
3991
4192
  properties: {
@@ -4032,6 +4233,11 @@ var searchSpaceTool = {
4032
4233
  type: "string",
4033
4234
  description: "Filter memories created before this date (ISO 8601)"
4034
4235
  },
4236
+ include_comments: {
4237
+ type: "boolean",
4238
+ description: "Include comments in search results (default: false)",
4239
+ default: false
4240
+ },
4035
4241
  limit: {
4036
4242
  type: "number",
4037
4243
  default: 10,
@@ -4084,6 +4290,9 @@ async function handleSearchSpace(args, userId) {
4084
4290
  if (args.content_type) {
4085
4291
  filterList.push(publicCollection.filter.byProperty("type").equal(args.content_type));
4086
4292
  }
4293
+ if (!args.include_comments && !args.content_type) {
4294
+ filterList.push(publicCollection.filter.byProperty("type").notEqual("comment"));
4295
+ }
4087
4296
  if (args.tags && args.tags.length > 0) {
4088
4297
  args.tags.forEach((tag) => {
4089
4298
  filterList.push(publicCollection.filter.byProperty("tags").containsAny([tag]));
@@ -4136,7 +4345,7 @@ import { Filters as Filters4 } from "weaviate-client";
4136
4345
  init_space_memory();
4137
4346
  var querySpaceTool = {
4138
4347
  name: "remember_query_space",
4139
- description: "Ask natural language questions about memories in shared spaces. Works like remember_query_memory but queries shared spaces.",
4348
+ description: "Ask natural language questions about memories in shared spaces. By default, excludes comments to focus on original content. Set include_comments: true to include discussions in answers.",
4140
4349
  inputSchema: {
4141
4350
  type: "object",
4142
4351
  properties: {
@@ -4144,11 +4353,15 @@ var querySpaceTool = {
4144
4353
  type: "string",
4145
4354
  description: "Natural language question"
4146
4355
  },
4147
- space: {
4148
- type: "string",
4149
- description: "Which space to query",
4150
- enum: SUPPORTED_SPACES,
4151
- default: "the_void"
4356
+ spaces: {
4357
+ type: "array",
4358
+ items: {
4359
+ type: "string",
4360
+ enum: SUPPORTED_SPACES
4361
+ },
4362
+ description: 'Spaces to query (e.g., ["the_void", "dogs"])',
4363
+ minItems: 1,
4364
+ default: ["the_void"]
4152
4365
  },
4153
4366
  content_type: {
4154
4367
  type: "string",
@@ -4173,6 +4386,11 @@ var querySpaceTool = {
4173
4386
  type: "string",
4174
4387
  description: "Filter memories created before this date (ISO 8601)"
4175
4388
  },
4389
+ include_comments: {
4390
+ type: "boolean",
4391
+ description: "Include comments in query results (default: false)",
4392
+ default: false
4393
+ },
4176
4394
  limit: {
4177
4395
  type: "number",
4178
4396
  default: 10,
@@ -4221,6 +4439,9 @@ async function handleQuerySpace(args, userId) {
4221
4439
  if (args.content_type) {
4222
4440
  filterList.push(publicCollection.filter.byProperty("type").equal(args.content_type));
4223
4441
  }
4442
+ if (!args.include_comments && !args.content_type) {
4443
+ filterList.push(publicCollection.filter.byProperty("type").notEqual("comment"));
4444
+ }
4224
4445
  if (args.tags && args.tags.length > 0) {
4225
4446
  args.tags.forEach((tag) => {
4226
4447
  filterList.push(publicCollection.filter.byProperty("tags").containsAny([tag]));