@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.
package/dist/server.js CHANGED
@@ -19,6 +19,10 @@ var __esm = (fn, res) => function __init() {
19
19
  var __commonJS = (cb, mod) => function __require2() {
20
20
  return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
21
21
  };
22
+ var __export = (target, all) => {
23
+ for (var name in all)
24
+ __defProp(target, name, { get: all[name], enumerable: true });
25
+ };
22
26
  var __copyProps = (to, from, except, desc) => {
23
27
  if (from && typeof from === "object" || typeof from === "function") {
24
28
  for (let key of __getOwnPropNames(from))
@@ -394,54 +398,68 @@ var require_main = __commonJS({
394
398
  }
395
399
  });
396
400
 
397
- // src/types/space-memory.ts
398
- var SUPPORTED_SPACES;
399
- var init_space_memory = __esm({
400
- "src/types/space-memory.ts"() {
401
+ // src/utils/logger.ts
402
+ var logger_exports = {};
403
+ __export(logger_exports, {
404
+ logger: () => logger
405
+ });
406
+ function shouldLog(level) {
407
+ return LOG_LEVELS[level] >= currentLevel;
408
+ }
409
+ var LOG_LEVELS, currentLevel, logger;
410
+ var init_logger = __esm({
411
+ "src/utils/logger.ts"() {
401
412
  "use strict";
402
- SUPPORTED_SPACES = ["the_void"];
413
+ init_config();
414
+ LOG_LEVELS = {
415
+ debug: 0,
416
+ info: 1,
417
+ warn: 2,
418
+ error: 3
419
+ };
420
+ currentLevel = LOG_LEVELS[config.server.logLevel] ?? LOG_LEVELS.info;
421
+ logger = {
422
+ debug: (message, data) => {
423
+ if (shouldLog("debug")) {
424
+ if (data) {
425
+ console.debug(JSON.stringify({ level: "DEBUG", message, ...data }));
426
+ } else {
427
+ console.debug(`[DEBUG] ${message}`);
428
+ }
429
+ }
430
+ },
431
+ info: (message, data) => {
432
+ if (shouldLog("info")) {
433
+ if (data) {
434
+ console.info(JSON.stringify({ level: "INFO", message, ...data }));
435
+ } else {
436
+ console.info(`[INFO] ${message}`);
437
+ }
438
+ }
439
+ },
440
+ warn: (message, data) => {
441
+ if (shouldLog("warn")) {
442
+ if (data) {
443
+ console.warn(JSON.stringify({ level: "WARN", message, ...data }));
444
+ } else {
445
+ console.warn(`[WARN] ${message}`);
446
+ }
447
+ }
448
+ },
449
+ error: (message, data) => {
450
+ if (shouldLog("error")) {
451
+ if (data) {
452
+ console.error(JSON.stringify({ level: "ERROR", message, ...data }));
453
+ } else {
454
+ console.error(`[ERROR] ${message}`);
455
+ }
456
+ }
457
+ }
458
+ };
403
459
  }
404
460
  });
405
461
 
406
- // src/server.ts
407
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
408
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
409
- import {
410
- CallToolRequestSchema,
411
- ListToolsRequestSchema,
412
- ErrorCode,
413
- McpError
414
- } from "@modelcontextprotocol/sdk/types.js";
415
-
416
462
  // src/config.ts
417
- var import_dotenv = __toESM(require_main(), 1);
418
- import_dotenv.default.config();
419
- var config = {
420
- // Weaviate
421
- weaviate: {
422
- url: process.env.WEAVIATE_REST_URL || "http://localhost:8080",
423
- apiKey: process.env.WEAVIATE_API_KEY || ""
424
- },
425
- // OpenAI (for embeddings)
426
- openai: {
427
- apiKey: process.env.OPENAI_EMBEDDINGS_API_KEY || process.env.OPENAI_APIKEY || ""
428
- },
429
- // Firebase (using firebase-admin-sdk-v8)
430
- firebase: {
431
- serviceAccount: process.env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY || "",
432
- projectId: process.env.FIREBASE_PROJECT_ID || ""
433
- },
434
- // Server
435
- server: {
436
- port: parseInt(process.env.PORT || "3000", 10),
437
- nodeEnv: process.env.NODE_ENV || "development",
438
- logLevel: process.env.LOG_LEVEL || "info"
439
- },
440
- // MCP
441
- mcp: {
442
- transport: process.env.MCP_TRANSPORT || "sse"
443
- }
444
- };
445
463
  function validateConfig() {
446
464
  const required = [
447
465
  { key: "WEAVIATE_REST_URL", value: config.weaviate.url },
@@ -455,10 +473,70 @@ function validateConfig() {
455
473
  `Missing required environment variables: ${missing.map((m) => m.key).join(", ")}`
456
474
  );
457
475
  }
458
- console.log("[Config] Configuration validated");
476
+ Promise.resolve().then(() => (init_logger(), logger_exports)).then(({ logger: logger2 }) => {
477
+ logger2.info("Configuration validated", {
478
+ module: "config"
479
+ });
480
+ });
459
481
  }
482
+ var import_dotenv, config;
483
+ var init_config = __esm({
484
+ "src/config.ts"() {
485
+ "use strict";
486
+ import_dotenv = __toESM(require_main(), 1);
487
+ import_dotenv.default.config();
488
+ config = {
489
+ // Weaviate
490
+ weaviate: {
491
+ url: process.env.WEAVIATE_REST_URL || "http://localhost:8080",
492
+ apiKey: process.env.WEAVIATE_API_KEY || ""
493
+ },
494
+ // OpenAI (for embeddings)
495
+ openai: {
496
+ apiKey: process.env.OPENAI_EMBEDDINGS_API_KEY || process.env.OPENAI_APIKEY || ""
497
+ },
498
+ // Firebase (using firebase-admin-sdk-v8)
499
+ firebase: {
500
+ serviceAccount: process.env.FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY || "",
501
+ projectId: process.env.FIREBASE_PROJECT_ID || ""
502
+ },
503
+ // Server
504
+ server: {
505
+ port: parseInt(process.env.PORT || "3000", 10),
506
+ nodeEnv: process.env.NODE_ENV || "development",
507
+ logLevel: process.env.LOG_LEVEL || "info"
508
+ },
509
+ // MCP
510
+ mcp: {
511
+ transport: process.env.MCP_TRANSPORT || "sse"
512
+ }
513
+ };
514
+ }
515
+ });
516
+
517
+ // src/types/space-memory.ts
518
+ var SUPPORTED_SPACES;
519
+ var init_space_memory = __esm({
520
+ "src/types/space-memory.ts"() {
521
+ "use strict";
522
+ SUPPORTED_SPACES = ["the_void"];
523
+ }
524
+ });
525
+
526
+ // src/server.ts
527
+ init_config();
528
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
529
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
530
+ import {
531
+ CallToolRequestSchema,
532
+ ListToolsRequestSchema,
533
+ ErrorCode,
534
+ McpError
535
+ } from "@modelcontextprotocol/sdk/types.js";
460
536
 
461
537
  // src/weaviate/client.ts
538
+ init_config();
539
+ init_logger();
462
540
  import weaviate from "weaviate-client";
463
541
  var client = null;
464
542
  async function initWeaviateClient() {
@@ -468,13 +546,19 @@ async function initWeaviateClient() {
468
546
  const weaviateUrl = config.weaviate.url;
469
547
  const isLocal = weaviateUrl.includes("localhost") || weaviateUrl.includes("127.0.0.1");
470
548
  if (!isLocal) {
471
- console.log("[Weaviate] Connecting to remote Weaviate:", weaviateUrl);
549
+ logger.info("Connecting to remote Weaviate", {
550
+ module: "weaviate-client",
551
+ url: weaviateUrl
552
+ });
472
553
  client = await weaviate.connectToWeaviateCloud(weaviateUrl, {
473
554
  authCredentials: config.weaviate.apiKey ? new weaviate.ApiKey(config.weaviate.apiKey) : void 0,
474
555
  headers: config.openai.apiKey ? { "X-OpenAI-Api-Key": config.openai.apiKey } : void 0
475
556
  });
476
557
  } else {
477
- console.log("[Weaviate] Connecting to local Weaviate:", weaviateUrl);
558
+ logger.info("Connecting to local Weaviate", {
559
+ module: "weaviate-client",
560
+ url: weaviateUrl
561
+ });
478
562
  const localConfig = {
479
563
  host: weaviateUrl.replace(/^https?:\/\//, "").split(":")[0],
480
564
  port: weaviateUrl.includes(":") ? parseInt(weaviateUrl.split(":").pop() || "8080") : 8080,
@@ -488,7 +572,10 @@ async function initWeaviateClient() {
488
572
  }
489
573
  client = await weaviate.connectToLocal(localConfig);
490
574
  }
491
- console.log("[Weaviate] Client initialized successfully");
575
+ logger.info("Weaviate client initialized successfully", {
576
+ module: "weaviate-client",
577
+ isLocal
578
+ });
492
579
  return client;
493
580
  }
494
581
  function getWeaviateClient() {
@@ -501,10 +588,16 @@ async function testWeaviateConnection() {
501
588
  try {
502
589
  const weaviateClient = getWeaviateClient();
503
590
  const isReady = await weaviateClient.isReady();
504
- console.log("[Weaviate] Connection successful, ready:", isReady);
591
+ logger.info("Weaviate connection test successful", {
592
+ module: "weaviate-client",
593
+ isReady
594
+ });
505
595
  return isReady;
506
596
  } catch (error) {
507
- console.error("[Weaviate] Connection failed:", error);
597
+ logger.error("Weaviate connection test failed", {
598
+ module: "weaviate-client",
599
+ error: error instanceof Error ? error.message : String(error)
600
+ });
508
601
  return false;
509
602
  }
510
603
  }
@@ -520,6 +613,8 @@ function getMemoryCollectionName(userId) {
520
613
  }
521
614
 
522
615
  // src/firestore/init.ts
616
+ init_config();
617
+ init_logger();
523
618
  import { initializeApp } from "@prmichaelsen/firebase-admin-sdk-v8";
524
619
  import {
525
620
  getDocument,
@@ -544,11 +639,20 @@ function initFirestore() {
544
639
  projectId: config.firebase.projectId
545
640
  });
546
641
  initialized = true;
547
- console.log("[Firestore] Initialized successfully");
642
+ logger.info("Firestore initialized successfully", {
643
+ module: "firestore-init"
644
+ });
548
645
  } catch (error) {
549
- console.error("[Firestore] Initialization failed:", error);
550
- console.error("[Firestore] Make sure FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY is valid JSON");
551
- console.error("[Firestore] Check for proper escaping in .env file");
646
+ logger.error("Firestore initialization failed", {
647
+ module: "firestore-init",
648
+ error: error instanceof Error ? error.message : String(error)
649
+ });
650
+ logger.error("Make sure FIREBASE_ADMIN_SERVICE_ACCOUNT_KEY is valid JSON", {
651
+ module: "firestore-init"
652
+ });
653
+ logger.error("Check for proper escaping in .env file", {
654
+ module: "firestore-init"
655
+ });
552
656
  throw error;
553
657
  }
554
658
  }
@@ -559,75 +663,40 @@ async function testFirestoreConnection() {
559
663
  }
560
664
  const { getDocument: getDocument3 } = await import("@prmichaelsen/firebase-admin-sdk-v8");
561
665
  await getDocument3("_health_check", "test");
562
- console.log("[Firestore] Connection successful");
666
+ logger.info("Firestore connection test successful", {
667
+ module: "firestore-init"
668
+ });
563
669
  return true;
564
670
  } catch (error) {
565
- console.error("[Firestore] Connection test failed:", error);
671
+ logger.error("Firestore connection test failed", {
672
+ module: "firestore-init",
673
+ error: error instanceof Error ? error.message : String(error)
674
+ });
566
675
  return false;
567
676
  }
568
677
  }
569
678
 
570
- // src/utils/logger.ts
571
- var LOG_LEVELS = {
572
- debug: 0,
573
- info: 1,
574
- warn: 2,
575
- error: 3
576
- };
577
- var currentLevel = LOG_LEVELS[config.server.logLevel] ?? LOG_LEVELS.info;
578
- function shouldLog(level) {
579
- return LOG_LEVELS[level] >= currentLevel;
580
- }
581
- var logger = {
582
- debug: (message, data) => {
583
- if (shouldLog("debug")) {
584
- if (data) {
585
- console.debug(JSON.stringify({ level: "DEBUG", message, ...data }));
586
- } else {
587
- console.debug(`[DEBUG] ${message}`);
588
- }
589
- }
590
- },
591
- info: (message, data) => {
592
- if (shouldLog("info")) {
593
- if (data) {
594
- console.info(JSON.stringify({ level: "INFO", message, ...data }));
595
- } else {
596
- console.info(`[INFO] ${message}`);
597
- }
598
- }
599
- },
600
- warn: (message, data) => {
601
- if (shouldLog("warn")) {
602
- if (data) {
603
- console.warn(JSON.stringify({ level: "WARN", message, ...data }));
604
- } else {
605
- console.warn(`[WARN] ${message}`);
606
- }
607
- }
608
- },
609
- error: (message, data) => {
610
- if (shouldLog("error")) {
611
- if (data) {
612
- console.error(JSON.stringify({ level: "ERROR", message, ...data }));
613
- } else {
614
- console.error(`[ERROR] ${message}`);
615
- }
616
- }
617
- }
618
- };
679
+ // src/server.ts
680
+ init_logger();
619
681
 
620
682
  // src/weaviate/schema.ts
621
683
  import weaviate2 from "weaviate-client";
684
+ init_logger();
622
685
  async function createMemoryCollection(userId) {
623
686
  const client2 = getWeaviateClient();
624
687
  const collectionName = `Memory_${sanitizeUserId(userId)}`;
625
688
  const exists = await client2.collections.exists(collectionName);
626
689
  if (exists) {
627
- console.log(`[Weaviate] Collection ${collectionName} already exists`);
690
+ logger.debug("Collection already exists", {
691
+ module: "weaviate-schema",
692
+ collectionName
693
+ });
628
694
  return;
629
695
  }
630
- console.log(`[Weaviate] Creating collection ${collectionName}...`);
696
+ logger.info("Creating memory collection", {
697
+ module: "weaviate-schema",
698
+ collectionName
699
+ });
631
700
  await client2.collections.create({
632
701
  name: collectionName,
633
702
  // Vectorizer configuration
@@ -824,10 +893,29 @@ async function createMemoryCollection(userId) {
824
893
  name: "computed_weight",
825
894
  dataType: "number",
826
895
  description: "Calculated effective weight"
896
+ },
897
+ // Comment/threading fields (for threaded discussions in shared spaces)
898
+ {
899
+ name: "parent_id",
900
+ dataType: "text",
901
+ description: "ID of parent memory or comment (for threading)"
902
+ },
903
+ {
904
+ name: "thread_root_id",
905
+ dataType: "text",
906
+ description: "Root memory ID for fetching entire thread"
907
+ },
908
+ {
909
+ name: "moderation_flags",
910
+ dataType: "text[]",
911
+ description: 'Per-space moderation flags (format: "{space_id}:{flag_type}")'
827
912
  }
828
913
  ]
829
914
  });
830
- console.log(`[Weaviate] Collection ${collectionName} created successfully`);
915
+ logger.info("Memory collection created successfully", {
916
+ module: "weaviate-schema",
917
+ collectionName
918
+ });
831
919
  }
832
920
  async function ensureMemoryCollection(userId) {
833
921
  const client2 = getWeaviateClient();
@@ -843,7 +931,11 @@ function getMemoryCollection(userId) {
843
931
  return client2.collections.get(collectionName);
844
932
  }
845
933
 
934
+ // src/tools/create-memory.ts
935
+ init_logger();
936
+
846
937
  // src/utils/error-handler.ts
938
+ init_logger();
847
939
  function formatDetailedError(error, context) {
848
940
  const errorMessage = error instanceof Error ? error.message : String(error);
849
941
  const errorStack = error instanceof Error ? error.stack : void 0;
@@ -1395,6 +1487,9 @@ async function handleCreateMemory(args, userId, context) {
1395
1487
  }
1396
1488
  }
1397
1489
 
1490
+ // src/tools/search-memory.ts
1491
+ init_logger();
1492
+
1398
1493
  // src/utils/weaviate-filters.ts
1399
1494
  import { Filters } from "weaviate-client";
1400
1495
  function buildCombinedSearchFilters(collection, filters) {
@@ -1662,6 +1757,7 @@ async function handleSearchMemory(args, userId) {
1662
1757
  }
1663
1758
 
1664
1759
  // src/tools/delete-memory.ts
1760
+ init_logger();
1665
1761
  var deleteMemoryTool = {
1666
1762
  name: "remember_delete_memory",
1667
1763
  description: `Delete a memory from your collection.
@@ -1742,6 +1838,7 @@ async function handleDeleteMemory(args, userId) {
1742
1838
  }
1743
1839
 
1744
1840
  // src/tools/update-memory.ts
1841
+ init_logger();
1745
1842
  var updateMemoryTool = {
1746
1843
  name: "remember_update_memory",
1747
1844
  description: `Update an existing memory with partial updates.
@@ -1927,6 +2024,7 @@ async function handleUpdateMemory(args, userId) {
1927
2024
  }
1928
2025
 
1929
2026
  // src/tools/find-similar.ts
2027
+ init_logger();
1930
2028
  var findSimilarTool = {
1931
2029
  name: "remember_find_similar",
1932
2030
  description: `Find memories similar to a given memory or text using vector similarity.
@@ -2058,6 +2156,7 @@ async function handleFindSimilar(args, userId) {
2058
2156
  }
2059
2157
 
2060
2158
  // src/tools/query-memory.ts
2159
+ init_logger();
2061
2160
  var queryMemoryTool = {
2062
2161
  name: "remember_query_memory",
2063
2162
  description: `Query memories using natural language for RAG (Retrieval-Augmented Generation).
@@ -2239,6 +2338,7 @@ ${content}${tags}`;
2239
2338
  }
2240
2339
 
2241
2340
  // src/tools/create-relationship.ts
2341
+ init_logger();
2242
2342
  var createRelationshipTool = {
2243
2343
  name: "remember_create_relationship",
2244
2344
  description: `Create a relationship connecting 2 or more memories.
@@ -2445,6 +2545,7 @@ async function handleCreateRelationship(args, userId, context) {
2445
2545
  }
2446
2546
 
2447
2547
  // src/tools/update-relationship.ts
2548
+ init_logger();
2448
2549
  var updateRelationshipTool = {
2449
2550
  name: "remember_update_relationship",
2450
2551
  description: `Update an existing relationship with partial updates.
@@ -2575,6 +2676,7 @@ async function handleUpdateRelationship(args, userId) {
2575
2676
 
2576
2677
  // src/tools/search-relationship.ts
2577
2678
  import { Filters as Filters2 } from "weaviate-client";
2679
+ init_logger();
2578
2680
  var searchRelationshipTool = {
2579
2681
  name: "remember_search_relationship",
2580
2682
  description: `Search relationships by observation text or relationship type.
@@ -2728,6 +2830,7 @@ async function handleSearchRelationship(args, userId) {
2728
2830
  }
2729
2831
 
2730
2832
  // src/tools/delete-relationship.ts
2833
+ init_logger();
2731
2834
  var deleteRelationshipTool = {
2732
2835
  name: "remember_delete_relationship",
2733
2836
  description: `Delete a relationship from your collection.
@@ -2855,6 +2958,9 @@ function getUserPreferencesPath(userId) {
2855
2958
  return `${BASE}.users/${userId}/preferences`;
2856
2959
  }
2857
2960
 
2961
+ // src/services/preferences-database.service.ts
2962
+ init_logger();
2963
+
2858
2964
  // src/types/preferences.ts
2859
2965
  var DEFAULT_PREFERENCES = {
2860
2966
  templates: {
@@ -3119,6 +3225,7 @@ var PreferencesDatabaseService = class {
3119
3225
  };
3120
3226
 
3121
3227
  // src/tools/set-preference.ts
3228
+ init_logger();
3122
3229
  var setPreferenceTool = {
3123
3230
  name: "remember_set_preference",
3124
3231
  description: `Update user preferences for system behavior through natural conversation.
@@ -3209,6 +3316,7 @@ async function handleSetPreference(args, userId) {
3209
3316
  }
3210
3317
 
3211
3318
  // src/tools/get-preferences.ts
3319
+ init_logger();
3212
3320
  var getPreferencesTool = {
3213
3321
  name: "remember_get_preferences",
3214
3322
  description: `Get current user preferences.
@@ -3271,6 +3379,7 @@ async function handleGetPreferences(args, userId) {
3271
3379
 
3272
3380
  // src/services/confirmation-token.service.ts
3273
3381
  import { randomUUID } from "crypto";
3382
+ init_logger();
3274
3383
  var ConfirmationTokenService = class {
3275
3384
  EXPIRY_MINUTES = 5;
3276
3385
  /**
@@ -3298,27 +3407,29 @@ var ConfirmationTokenService = class {
3298
3407
  status: "pending"
3299
3408
  };
3300
3409
  const collectionPath = `users/${userId}/requests`;
3301
- console.log("[ConfirmationTokenService] Creating request:", {
3410
+ logger.info("Creating confirmation request", {
3411
+ service: "ConfirmationTokenService",
3302
3412
  userId,
3303
3413
  action,
3304
3414
  targetCollection,
3305
3415
  collectionPath,
3306
- requestData: {
3307
- token,
3308
- action,
3309
- payloadKeys: Object.keys(payload)
3310
- }
3416
+ payloadKeys: Object.keys(payload)
3417
+ });
3418
+ logger.debug("Calling Firestore addDocument", {
3419
+ service: "ConfirmationTokenService",
3420
+ collectionPath
3311
3421
  });
3312
- console.log("[ConfirmationTokenService] Calling addDocument...");
3313
3422
  const docRef = await addDocument(collectionPath, request);
3314
- console.log("[ConfirmationTokenService] addDocument returned:", {
3423
+ logger.debug("Firestore addDocument returned", {
3424
+ service: "ConfirmationTokenService",
3315
3425
  hasDocRef: !!docRef,
3316
3426
  hasId: !!docRef?.id,
3317
3427
  docRefId: docRef?.id
3318
3428
  });
3319
3429
  if (!docRef) {
3320
3430
  const error = new Error("Firestore addDocument returned null/undefined");
3321
- console.error("[ConfirmationTokenService] CRITICAL: addDocument returned null", {
3431
+ logger.error("CRITICAL: addDocument returned null", {
3432
+ service: "ConfirmationTokenService",
3322
3433
  userId,
3323
3434
  collectionPath
3324
3435
  });
@@ -3326,21 +3437,24 @@ var ConfirmationTokenService = class {
3326
3437
  }
3327
3438
  if (!docRef.id) {
3328
3439
  const error = new Error("Firestore addDocument returned docRef without ID");
3329
- console.error("[ConfirmationTokenService] CRITICAL: docRef has no ID", {
3440
+ logger.error("CRITICAL: docRef has no ID", {
3441
+ service: "ConfirmationTokenService",
3330
3442
  userId,
3331
3443
  collectionPath,
3332
3444
  docRef
3333
3445
  });
3334
3446
  throw error;
3335
3447
  }
3336
- console.log("[ConfirmationTokenService] Request created successfully:", {
3448
+ logger.info("Confirmation request created successfully", {
3449
+ service: "ConfirmationTokenService",
3337
3450
  requestId: docRef.id,
3338
3451
  token,
3339
3452
  expiresAt: request.expires_at
3340
3453
  });
3341
3454
  return { requestId: docRef.id, token };
3342
3455
  } catch (error) {
3343
- console.error("[ConfirmationTokenService] FAILED to create request:", {
3456
+ logger.error("Failed to create confirmation request", {
3457
+ service: "ConfirmationTokenService",
3344
3458
  error: error instanceof Error ? error.message : String(error),
3345
3459
  stack: error instanceof Error ? error.stack : void 0,
3346
3460
  userId,
@@ -3359,7 +3473,8 @@ var ConfirmationTokenService = class {
3359
3473
  */
3360
3474
  async validateToken(userId, token) {
3361
3475
  const collectionPath = `users/${userId}/requests`;
3362
- console.log("[ConfirmationTokenService] Validating token:", {
3476
+ logger.debug("Validating confirmation token", {
3477
+ service: "ConfirmationTokenService",
3363
3478
  userId,
3364
3479
  token,
3365
3480
  collectionPath
@@ -3372,17 +3487,22 @@ var ConfirmationTokenService = class {
3372
3487
  limit: 1
3373
3488
  };
3374
3489
  const results = await queryDocuments(collectionPath, queryOptions);
3375
- console.log("[ConfirmationTokenService] Query results:", {
3490
+ logger.debug("Token query results", {
3491
+ service: "ConfirmationTokenService",
3376
3492
  resultsFound: results.length,
3377
3493
  hasResults: results.length > 0
3378
3494
  });
3379
3495
  if (results.length === 0) {
3380
- console.log("[ConfirmationTokenService] Token not found or not pending");
3496
+ logger.info("Token not found or not pending", {
3497
+ service: "ConfirmationTokenService",
3498
+ userId
3499
+ });
3381
3500
  return null;
3382
3501
  }
3383
3502
  const doc = results[0];
3384
3503
  const request = doc.data;
3385
- console.log("[ConfirmationTokenService] Request found:", {
3504
+ logger.info("Confirmation request found", {
3505
+ service: "ConfirmationTokenService",
3386
3506
  requestId: doc.id,
3387
3507
  action: request.action,
3388
3508
  status: request.status,
@@ -3390,7 +3510,11 @@ var ConfirmationTokenService = class {
3390
3510
  });
3391
3511
  const expiresAt = new Date(request.expires_at);
3392
3512
  if (expiresAt.getTime() < Date.now()) {
3393
- console.log("[ConfirmationTokenService] Token expired");
3513
+ logger.info("Token expired", {
3514
+ service: "ConfirmationTokenService",
3515
+ requestId: doc.id,
3516
+ expiresAt: request.expires_at
3517
+ });
3394
3518
  await this.updateStatus(userId, doc.id, "expired");
3395
3519
  return null;
3396
3520
  }
@@ -3476,7 +3600,10 @@ var ConfirmationTokenService = class {
3476
3600
  * @returns Count of deleted requests
3477
3601
  */
3478
3602
  async cleanupExpired() {
3479
- console.warn("[ConfirmationTokenService] cleanupExpired not implemented - rely on Firestore TTL");
3603
+ logger.warn("cleanupExpired not implemented - relying on Firestore TTL", {
3604
+ service: "ConfirmationTokenService",
3605
+ note: "Configure Firestore TTL policy on requests collection group"
3606
+ });
3480
3607
  return 0;
3481
3608
  }
3482
3609
  };
@@ -3484,6 +3611,7 @@ var confirmationTokenService = new ConfirmationTokenService();
3484
3611
 
3485
3612
  // src/weaviate/space-schema.ts
3486
3613
  init_space_memory();
3614
+ init_logger();
3487
3615
  import weaviate3 from "weaviate-client";
3488
3616
  var PUBLIC_COLLECTION_NAME = "Memory_public";
3489
3617
  function getSpaceCollectionName(spaceId) {
@@ -3494,7 +3622,11 @@ function isValidSpaceId(spaceId) {
3494
3622
  }
3495
3623
  async function createSpaceCollection(client2, spaceId) {
3496
3624
  const collectionName = spaceId === "public" ? PUBLIC_COLLECTION_NAME : getSpaceCollectionName(spaceId);
3497
- console.log(`[Weaviate] Creating space collection ${collectionName}...`);
3625
+ logger.info("Creating space collection", {
3626
+ module: "weaviate-space-schema",
3627
+ collectionName,
3628
+ spaceId
3629
+ });
3498
3630
  await client2.collections.create({
3499
3631
  name: collectionName,
3500
3632
  // Vectorizer configuration
@@ -3648,10 +3780,29 @@ async function createSpaceCollection(client2, spaceId) {
3648
3780
  name: "version",
3649
3781
  dataType: "number",
3650
3782
  description: "Version number (increments on update)"
3783
+ },
3784
+ // Comment/threading fields (for threaded discussions in shared spaces)
3785
+ {
3786
+ name: "parent_id",
3787
+ dataType: "text",
3788
+ description: "ID of parent memory or comment (for threading)"
3789
+ },
3790
+ {
3791
+ name: "thread_root_id",
3792
+ dataType: "text",
3793
+ description: "Root memory ID for fetching entire thread"
3794
+ },
3795
+ {
3796
+ name: "moderation_flags",
3797
+ dataType: "text[]",
3798
+ description: 'Per-space moderation flags (format: "{space_id}:{flag_type}")'
3651
3799
  }
3652
3800
  ]
3653
3801
  });
3654
- console.log(`[Weaviate] Space collection ${collectionName} created successfully`);
3802
+ logger.info("Space collection created successfully", {
3803
+ module: "weaviate-space-schema",
3804
+ collectionName
3805
+ });
3655
3806
  }
3656
3807
  async function ensurePublicCollection(client2) {
3657
3808
  const collectionName = PUBLIC_COLLECTION_NAME;
@@ -3664,6 +3815,7 @@ async function ensurePublicCollection(client2) {
3664
3815
 
3665
3816
  // src/tools/publish.ts
3666
3817
  init_space_memory();
3818
+ init_logger();
3667
3819
  var publishTool = {
3668
3820
  name: "remember_publish",
3669
3821
  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.',
@@ -3696,7 +3848,8 @@ var publishTool = {
3696
3848
  };
3697
3849
  async function handlePublish(args, userId) {
3698
3850
  try {
3699
- console.log("[remember_publish] Starting publish request:", {
3851
+ logger.info("Starting publish request", {
3852
+ tool: "remember_publish",
3700
3853
  userId,
3701
3854
  memoryId: args.memory_id,
3702
3855
  spaces: args.spaces,
@@ -3705,7 +3858,11 @@ async function handlePublish(args, userId) {
3705
3858
  });
3706
3859
  const invalidSpaces = args.spaces.filter((s) => !isValidSpaceId(s));
3707
3860
  if (invalidSpaces.length > 0) {
3708
- console.log("[remember_publish] Invalid space IDs:", invalidSpaces);
3861
+ logger.warn("Invalid space IDs provided", {
3862
+ tool: "remember_publish",
3863
+ invalidSpaces,
3864
+ providedSpaces: args.spaces
3865
+ });
3709
3866
  return JSON.stringify(
3710
3867
  {
3711
3868
  success: false,
@@ -3722,7 +3879,10 @@ async function handlePublish(args, userId) {
3722
3879
  );
3723
3880
  }
3724
3881
  if (args.spaces.length === 0) {
3725
- console.log("[remember_publish] Empty spaces array");
3882
+ logger.warn("Empty spaces array provided", {
3883
+ tool: "remember_publish",
3884
+ userId
3885
+ });
3726
3886
  return JSON.stringify(
3727
3887
  {
3728
3888
  success: false,
@@ -3735,15 +3895,24 @@ async function handlePublish(args, userId) {
3735
3895
  }
3736
3896
  const weaviateClient = getWeaviateClient();
3737
3897
  const collectionName = getMemoryCollectionName(userId);
3738
- console.log("[remember_publish] Fetching memory from collection:", collectionName);
3898
+ logger.debug("Fetching memory from collection", {
3899
+ tool: "remember_publish",
3900
+ collectionName,
3901
+ memoryId: args.memory_id
3902
+ });
3739
3903
  const userCollection = weaviateClient.collections.get(collectionName);
3740
3904
  const memory = await userCollection.query.fetchObjectById(args.memory_id);
3741
- console.log("[remember_publish] Memory fetch result:", {
3905
+ logger.debug("Memory fetch result", {
3906
+ tool: "remember_publish",
3742
3907
  found: !!memory,
3743
3908
  memoryId: args.memory_id
3744
3909
  });
3745
3910
  if (!memory) {
3746
- console.log("[remember_publish] Memory not found");
3911
+ logger.info("Memory not found", {
3912
+ tool: "remember_publish",
3913
+ memoryId: args.memory_id,
3914
+ collectionName
3915
+ });
3747
3916
  return JSON.stringify(
3748
3917
  {
3749
3918
  success: false,
@@ -3794,7 +3963,12 @@ async function handlePublish(args, userId) {
3794
3963
  spaces: args.spaces,
3795
3964
  additional_tags: args.additional_tags || []
3796
3965
  };
3797
- console.log("[remember_publish] Generating confirmation token");
3966
+ logger.info("Generating confirmation token", {
3967
+ tool: "remember_publish",
3968
+ userId,
3969
+ memoryId: args.memory_id,
3970
+ spaces: args.spaces
3971
+ });
3798
3972
  const { requestId, token } = await confirmationTokenService.createRequest(
3799
3973
  userId,
3800
3974
  "publish_memory",
@@ -3802,10 +3976,12 @@ async function handlePublish(args, userId) {
3802
3976
  void 0
3803
3977
  // No single target_collection anymore
3804
3978
  );
3805
- console.log("[remember_publish] Token generated:", {
3979
+ logger.info("Confirmation token generated", {
3980
+ tool: "remember_publish",
3806
3981
  requestId,
3807
3982
  token,
3808
- action: "publish_memory"
3983
+ action: "publish_memory",
3984
+ spaces: args.spaces
3809
3985
  });
3810
3986
  return JSON.stringify(
3811
3987
  {
@@ -3827,9 +4003,20 @@ async function handlePublish(args, userId) {
3827
4003
  }
3828
4004
 
3829
4005
  // src/tools/confirm.ts
4006
+ init_logger();
3830
4007
  var confirmTool = {
3831
4008
  name: "remember_confirm",
3832
- description: "Confirm and execute a pending action using the token. Works for any action that requires confirmation (publish, delete, etc.).",
4009
+ description: `Confirm and execute a pending action using the token. Works for any action that requires confirmation (publish, delete, etc.).
4010
+
4011
+ \u26A0\uFE0F CRITICAL SAFETY REQUIREMENTS:
4012
+ Before executing this tool, you MUST:
4013
+ 1. Have received the confirmation token in a PREVIOUS tool response
4014
+ 2. Have presented the token details to the user for review
4015
+ 3. Have received EXPLICIT user confirmation in a SEPARATE user message
4016
+ 4. NEVER chain this tool with other tool calls in the same response
4017
+ 5. ALWAYS treat confirmations as standalone, deliberate actions
4018
+
4019
+ Violating these requirements bypasses user consent and is a security violation.`,
3833
4020
  inputSchema: {
3834
4021
  type: "object",
3835
4022
  properties: {
@@ -3843,17 +4030,22 @@ var confirmTool = {
3843
4030
  };
3844
4031
  async function handleConfirm(args, userId) {
3845
4032
  try {
3846
- console.log("[remember_confirm] Starting confirmation:", {
4033
+ logger.info("Starting confirmation", {
4034
+ tool: "remember_confirm",
3847
4035
  userId,
3848
4036
  token: args.token
3849
4037
  });
3850
4038
  const request = await confirmationTokenService.confirmRequest(userId, args.token);
3851
- console.log("[remember_confirm] Token validation result:", {
4039
+ logger.debug("Token validation result", {
4040
+ tool: "remember_confirm",
3852
4041
  requestFound: !!request,
3853
4042
  action: request?.action
3854
4043
  });
3855
4044
  if (!request) {
3856
- console.log("[remember_confirm] Token invalid or expired");
4045
+ logger.info("Token invalid or expired", {
4046
+ tool: "remember_confirm",
4047
+ userId
4048
+ });
3857
4049
  return JSON.stringify(
3858
4050
  {
3859
4051
  success: false,
@@ -3864,7 +4056,11 @@ async function handleConfirm(args, userId) {
3864
4056
  2
3865
4057
  );
3866
4058
  }
3867
- console.log("[remember_confirm] Executing action:", request.action);
4059
+ logger.info("Executing confirmed action", {
4060
+ tool: "remember_confirm",
4061
+ action: request.action,
4062
+ userId
4063
+ });
3868
4064
  if (request.action === "publish_memory") {
3869
4065
  return await executePublishMemory(request, userId);
3870
4066
  }
@@ -3880,7 +4076,8 @@ async function handleConfirm(args, userId) {
3880
4076
  }
3881
4077
  async function executePublishMemory(request, userId) {
3882
4078
  try {
3883
- console.log("[executePublishMemory] Starting execution:", {
4079
+ logger.info("Executing publish memory action", {
4080
+ function: "executePublishMemory",
3884
4081
  userId,
3885
4082
  memoryId: request.payload.memory_id,
3886
4083
  spaces: request.payload.spaces,
@@ -3890,16 +4087,24 @@ async function executePublishMemory(request, userId) {
3890
4087
  const userCollection = weaviateClient.collections.get(
3891
4088
  getMemoryCollectionName(userId)
3892
4089
  );
3893
- console.log("[executePublishMemory] Fetching original memory from:", getMemoryCollectionName(userId));
4090
+ logger.debug("Fetching original memory", {
4091
+ function: "executePublishMemory",
4092
+ collectionName: getMemoryCollectionName(userId),
4093
+ memoryId: request.payload.memory_id
4094
+ });
3894
4095
  const originalMemory = await userCollection.query.fetchObjectById(
3895
4096
  request.payload.memory_id
3896
4097
  );
3897
- console.log("[executePublishMemory] Original memory fetch result:", {
4098
+ logger.debug("Original memory fetch result", {
4099
+ function: "executePublishMemory",
3898
4100
  found: !!originalMemory,
3899
4101
  memoryId: request.payload.memory_id
3900
4102
  });
3901
4103
  if (!originalMemory) {
3902
- console.log("[executePublishMemory] Memory not found");
4104
+ logger.info("Original memory not found", {
4105
+ function: "executePublishMemory",
4106
+ memoryId: request.payload.memory_id
4107
+ });
3903
4108
  return JSON.stringify(
3904
4109
  {
3905
4110
  success: false,
@@ -3911,7 +4116,12 @@ async function executePublishMemory(request, userId) {
3911
4116
  );
3912
4117
  }
3913
4118
  if (originalMemory.properties.user_id !== userId) {
3914
- console.log("[executePublishMemory] Permission denied - wrong owner");
4119
+ logger.warn("Permission denied - wrong owner", {
4120
+ function: "executePublishMemory",
4121
+ memoryId: request.payload.memory_id,
4122
+ memoryOwner: originalMemory.properties.user_id,
4123
+ requestingUser: userId
4124
+ });
3915
4125
  return JSON.stringify(
3916
4126
  {
3917
4127
  success: false,
@@ -3922,9 +4132,14 @@ async function executePublishMemory(request, userId) {
3922
4132
  2
3923
4133
  );
3924
4134
  }
3925
- console.log("[executePublishMemory] Ensuring public collection");
4135
+ logger.debug("Ensuring public collection exists", {
4136
+ function: "executePublishMemory"
4137
+ });
3926
4138
  const publicCollection = await ensurePublicCollection(weaviateClient);
3927
- console.log("[executePublishMemory] Public collection ready");
4139
+ logger.debug("Public collection ready", {
4140
+ function: "executePublishMemory",
4141
+ collectionName: "Memory_public"
4142
+ });
3928
4143
  const originalTags = Array.isArray(originalMemory.properties.tags) ? originalMemory.properties.tags : [];
3929
4144
  const additionalTags = Array.isArray(request.payload.additional_tags) ? request.payload.additional_tags : [];
3930
4145
  const publishedMemory = {
@@ -3945,7 +4160,8 @@ async function executePublishMemory(request, userId) {
3945
4160
  updated_at: (/* @__PURE__ */ new Date()).toISOString(),
3946
4161
  version: 1
3947
4162
  };
3948
- console.log("[executePublishMemory] Inserting into Memory_public:", {
4163
+ logger.info("Inserting memory into Memory_public", {
4164
+ function: "executePublishMemory",
3949
4165
  spaces: request.payload.spaces,
3950
4166
  spaceCount: request.payload.spaces?.length || 0,
3951
4167
  memoryId: request.payload.memory_id,
@@ -3953,9 +4169,10 @@ async function executePublishMemory(request, userId) {
3953
4169
  hasAuthorId: !!publishedMemory.author_id
3954
4170
  });
3955
4171
  const result = await publicCollection.data.insert(publishedMemory);
3956
- console.log("[executePublishMemory] Insert result:", {
3957
- success: !!result,
3958
- spaceMemoryId: result
4172
+ logger.info("Memory published successfully", {
4173
+ function: "executePublishMemory",
4174
+ spaceMemoryId: result,
4175
+ spaces: request.payload.spaces
3959
4176
  });
3960
4177
  return JSON.stringify(
3961
4178
  {
@@ -3979,7 +4196,17 @@ async function executePublishMemory(request, userId) {
3979
4196
  // src/tools/deny.ts
3980
4197
  var denyTool = {
3981
4198
  name: "remember_deny",
3982
- description: "Deny a pending action. The request will be marked as denied and the token invalidated. Works for any action that requires confirmation.",
4199
+ description: `Deny a pending action. The request will be marked as denied and the token invalidated. Works for any action that requires confirmation.
4200
+
4201
+ \u26A0\uFE0F CRITICAL SAFETY REQUIREMENTS:
4202
+ Before executing this tool, you MUST:
4203
+ 1. Have received the confirmation token in a PREVIOUS tool response
4204
+ 2. Have presented the token details to the user for review
4205
+ 3. Have received EXPLICIT user denial in a SEPARATE user message
4206
+ 4. NEVER chain this tool with other tool calls in the same response
4207
+ 5. ALWAYS treat denials as standalone, deliberate actions
4208
+
4209
+ This ensures proper user consent workflow is followed.`,
3983
4210
  inputSchema: {
3984
4211
  type: "object",
3985
4212
  properties: {
@@ -4027,7 +4254,7 @@ import { Filters as Filters3 } from "weaviate-client";
4027
4254
  init_space_memory();
4028
4255
  var searchSpaceTool = {
4029
4256
  name: "remember_search_space",
4030
- 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.",
4257
+ 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.",
4031
4258
  inputSchema: {
4032
4259
  type: "object",
4033
4260
  properties: {
@@ -4074,6 +4301,11 @@ var searchSpaceTool = {
4074
4301
  type: "string",
4075
4302
  description: "Filter memories created before this date (ISO 8601)"
4076
4303
  },
4304
+ include_comments: {
4305
+ type: "boolean",
4306
+ description: "Include comments in search results (default: false)",
4307
+ default: false
4308
+ },
4077
4309
  limit: {
4078
4310
  type: "number",
4079
4311
  default: 10,
@@ -4126,6 +4358,9 @@ async function handleSearchSpace(args, userId) {
4126
4358
  if (args.content_type) {
4127
4359
  filterList.push(publicCollection.filter.byProperty("type").equal(args.content_type));
4128
4360
  }
4361
+ if (!args.include_comments && !args.content_type) {
4362
+ filterList.push(publicCollection.filter.byProperty("type").notEqual("comment"));
4363
+ }
4129
4364
  if (args.tags && args.tags.length > 0) {
4130
4365
  args.tags.forEach((tag) => {
4131
4366
  filterList.push(publicCollection.filter.byProperty("tags").containsAny([tag]));
@@ -4178,7 +4413,7 @@ import { Filters as Filters4 } from "weaviate-client";
4178
4413
  init_space_memory();
4179
4414
  var querySpaceTool = {
4180
4415
  name: "remember_query_space",
4181
- description: "Ask natural language questions about memories in shared spaces. Works like remember_query_memory but queries shared spaces.",
4416
+ 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.",
4182
4417
  inputSchema: {
4183
4418
  type: "object",
4184
4419
  properties: {
@@ -4186,11 +4421,15 @@ var querySpaceTool = {
4186
4421
  type: "string",
4187
4422
  description: "Natural language question"
4188
4423
  },
4189
- space: {
4190
- type: "string",
4191
- description: "Which space to query",
4192
- enum: SUPPORTED_SPACES,
4193
- default: "the_void"
4424
+ spaces: {
4425
+ type: "array",
4426
+ items: {
4427
+ type: "string",
4428
+ enum: SUPPORTED_SPACES
4429
+ },
4430
+ description: 'Spaces to query (e.g., ["the_void", "dogs"])',
4431
+ minItems: 1,
4432
+ default: ["the_void"]
4194
4433
  },
4195
4434
  content_type: {
4196
4435
  type: "string",
@@ -4215,6 +4454,11 @@ var querySpaceTool = {
4215
4454
  type: "string",
4216
4455
  description: "Filter memories created before this date (ISO 8601)"
4217
4456
  },
4457
+ include_comments: {
4458
+ type: "boolean",
4459
+ description: "Include comments in query results (default: false)",
4460
+ default: false
4461
+ },
4218
4462
  limit: {
4219
4463
  type: "number",
4220
4464
  default: 10,
@@ -4263,6 +4507,9 @@ async function handleQuerySpace(args, userId) {
4263
4507
  if (args.content_type) {
4264
4508
  filterList.push(publicCollection.filter.byProperty("type").equal(args.content_type));
4265
4509
  }
4510
+ if (!args.include_comments && !args.content_type) {
4511
+ filterList.push(publicCollection.filter.byProperty("type").notEqual("comment"));
4512
+ }
4266
4513
  if (args.tags && args.tags.length > 0) {
4267
4514
  args.tags.forEach((tag) => {
4268
4515
  filterList.push(publicCollection.filter.byProperty("tags").containsAny([tag]));