{"version":3,"sources":["../src/server/events.ts","../src/server/sqlite.ts","../src/server/http.ts","../src/server/mcp.ts","../src/server/store.ts","../src/index.ts","../src/server/tenant-store.ts"],"sourcesContent":["/**\n * EventBus for real-time event distribution.\n * Coordinates SSE streams, MCP notifications, and future webhooks.\n */\n\nimport type { AFSEvent, AFSEventType, Annotation, Session, ThreadMessage, ActionRequest } from \"../types.js\";\n\ntype EventHandler = (event: AFSEvent) => void;\n\n// Global sequence counter for event ordering\nlet globalSequence = 0;\n\n/**\n * Simple pub/sub event bus for AFS events.\n */\nclass EventBus {\n  private handlers = new Set<EventHandler>();\n  private sessionHandlers = new Map<string, Set<EventHandler>>();\n\n  /**\n   * Subscribe to all events.\n   */\n  subscribe(handler: EventHandler): () => void {\n    this.handlers.add(handler);\n    return () => this.handlers.delete(handler);\n  }\n\n  /**\n   * Subscribe to events for a specific session.\n   */\n  subscribeToSession(sessionId: string, handler: EventHandler): () => void {\n    if (!this.sessionHandlers.has(sessionId)) {\n      this.sessionHandlers.set(sessionId, new Set());\n    }\n    this.sessionHandlers.get(sessionId)!.add(handler);\n\n    return () => {\n      const handlers = this.sessionHandlers.get(sessionId);\n      if (handlers) {\n        handlers.delete(handler);\n        if (handlers.size === 0) {\n          this.sessionHandlers.delete(sessionId);\n        }\n      }\n    };\n  }\n\n  /**\n   * Emit an event to all subscribers.\n   */\n  emit(\n    type: AFSEventType,\n    sessionId: string,\n    payload: Annotation | Session | ThreadMessage | ActionRequest\n  ): AFSEvent {\n    const event: AFSEvent = {\n      type,\n      timestamp: new Date().toISOString(),\n      sessionId,\n      sequence: ++globalSequence,\n      payload,\n    };\n\n    // Notify global subscribers\n    for (const handler of this.handlers) {\n      try {\n        handler(event);\n      } catch (err) {\n        console.error(\"[EventBus] Handler error:\", err);\n      }\n    }\n\n    // Notify session-specific subscribers\n    const sessionHandlers = this.sessionHandlers.get(sessionId);\n    if (sessionHandlers) {\n      for (const handler of sessionHandlers) {\n        try {\n          handler(event);\n        } catch (err) {\n          console.error(\"[EventBus] Session handler error:\", err);\n        }\n      }\n    }\n\n    return event;\n  }\n\n  /**\n   * Get current sequence number (for reconnect logic).\n   */\n  getSequence(): number {\n    return globalSequence;\n  }\n\n  /**\n   * Set sequence from persisted state (for server restart).\n   */\n  setSequence(seq: number): void {\n    globalSequence = seq;\n  }\n}\n\n// Singleton instance\nexport const eventBus = new EventBus();\n\n// -----------------------------------------------------------------------------\n// User-Scoped Event Bus\n// -----------------------------------------------------------------------------\n\n/**\n * User-scoped event bus that filters events by user ID.\n * Prevents data leakage between users in multi-tenant environments.\n */\nclass UserEventBus {\n  private userHandlers = new Map<string, Set<EventHandler>>();\n  private userSessionHandlers = new Map<string, Map<string, Set<EventHandler>>>();\n\n  /**\n   * Subscribe to all events for a specific user.\n   */\n  subscribeForUser(userId: string, handler: EventHandler): () => void {\n    if (!this.userHandlers.has(userId)) {\n      this.userHandlers.set(userId, new Set());\n    }\n    this.userHandlers.get(userId)!.add(handler);\n\n    return () => {\n      const handlers = this.userHandlers.get(userId);\n      if (handlers) {\n        handlers.delete(handler);\n        if (handlers.size === 0) {\n          this.userHandlers.delete(userId);\n        }\n      }\n    };\n  }\n\n  /**\n   * Subscribe to events for a specific session of a specific user.\n   */\n  subscribeToSessionForUser(\n    userId: string,\n    sessionId: string,\n    handler: EventHandler\n  ): () => void {\n    if (!this.userSessionHandlers.has(userId)) {\n      this.userSessionHandlers.set(userId, new Map());\n    }\n    const userSessions = this.userSessionHandlers.get(userId)!;\n\n    if (!userSessions.has(sessionId)) {\n      userSessions.set(sessionId, new Set());\n    }\n    userSessions.get(sessionId)!.add(handler);\n\n    return () => {\n      const userSessions = this.userSessionHandlers.get(userId);\n      if (userSessions) {\n        const handlers = userSessions.get(sessionId);\n        if (handlers) {\n          handlers.delete(handler);\n          if (handlers.size === 0) {\n            userSessions.delete(sessionId);\n          }\n        }\n        if (userSessions.size === 0) {\n          this.userSessionHandlers.delete(userId);\n        }\n      }\n    };\n  }\n\n  /**\n   * Emit an event scoped to a specific user.\n   * Only handlers for that user will receive the event.\n   */\n  emitForUser(\n    userId: string,\n    type: AFSEventType,\n    sessionId: string,\n    payload: Annotation | Session | ThreadMessage | ActionRequest\n  ): AFSEvent {\n    const event: AFSEvent = {\n      type,\n      timestamp: new Date().toISOString(),\n      sessionId,\n      sequence: ++globalSequence,\n      payload,\n    };\n\n    // Notify user-specific global subscribers\n    const userHandlers = this.userHandlers.get(userId);\n    if (userHandlers) {\n      for (const handler of userHandlers) {\n        try {\n          handler(event);\n        } catch (err) {\n          console.error(\"[UserEventBus] Handler error:\", err);\n        }\n      }\n    }\n\n    // Notify user-specific session subscribers\n    const userSessions = this.userSessionHandlers.get(userId);\n    if (userSessions) {\n      const sessionHandlers = userSessions.get(sessionId);\n      if (sessionHandlers) {\n        for (const handler of sessionHandlers) {\n          try {\n            handler(event);\n          } catch (err) {\n            console.error(\"[UserEventBus] Session handler error:\", err);\n          }\n        }\n      }\n    }\n\n    return event;\n  }\n\n  /**\n   * Check if a user has any active listeners.\n   */\n  hasListenersForUser(userId: string): boolean {\n    const hasGlobal = this.userHandlers.has(userId) && this.userHandlers.get(userId)!.size > 0;\n    const hasSessions = this.userSessionHandlers.has(userId) && this.userSessionHandlers.get(userId)!.size > 0;\n    return hasGlobal || hasSessions;\n  }\n\n  /**\n   * Get count of listeners for a user.\n   */\n  getListenerCountForUser(userId: string): number {\n    let count = 0;\n    const handlers = this.userHandlers.get(userId);\n    if (handlers) count += handlers.size;\n\n    const sessions = this.userSessionHandlers.get(userId);\n    if (sessions) {\n      for (const sessionHandlers of sessions.values()) {\n        count += sessionHandlers.size;\n      }\n    }\n    return count;\n  }\n}\n\n// Singleton instance for user-scoped events\nexport const userEventBus = new UserEventBus();\n","/**\n * SQLite-backed store for sessions, annotations, and events.\n * Provides persistence across server restarts.\n */\n\nimport Database from \"better-sqlite3\";\nimport { createHash, randomBytes } from \"crypto\";\nimport { mkdirSync, existsSync } from \"fs\";\nimport { join } from \"path\";\nimport { homedir } from \"os\";\nimport type {\n  AFSStore,\n  AFSEvent,\n  AFSEventType,\n  Session,\n  SessionStatus,\n  SessionWithAnnotations,\n  Annotation,\n  AnnotationStatus,\n  ThreadMessage,\n  Organization,\n  User,\n  UserRole,\n  ApiKey,\n  UserContext,\n} from \"../types.js\";\nimport { eventBus } from \"./events.js\";\n\n// -----------------------------------------------------------------------------\n// Database Setup\n// -----------------------------------------------------------------------------\n\nfunction getDbPath(): string {\n  const dataDir = join(homedir(), \".agentation\");\n  if (!existsSync(dataDir)) {\n    mkdirSync(dataDir, { recursive: true });\n  }\n  return join(dataDir, \"store.db\");\n}\n\nfunction initDatabase(db: Database.Database): void {\n  db.exec(`\n    -- Multi-tenant tables\n    CREATE TABLE IF NOT EXISTS organizations (\n      id TEXT PRIMARY KEY,\n      name TEXT NOT NULL,\n      created_at TEXT NOT NULL,\n      updated_at TEXT\n    );\n\n    CREATE TABLE IF NOT EXISTS users (\n      id TEXT PRIMARY KEY,\n      email TEXT NOT NULL UNIQUE,\n      org_id TEXT NOT NULL,\n      role TEXT NOT NULL DEFAULT 'member',\n      created_at TEXT NOT NULL,\n      updated_at TEXT,\n      FOREIGN KEY (org_id) REFERENCES organizations(id)\n    );\n\n    CREATE TABLE IF NOT EXISTS api_keys (\n      id TEXT PRIMARY KEY,\n      key_prefix TEXT NOT NULL,\n      key_hash TEXT NOT NULL UNIQUE,\n      user_id TEXT NOT NULL,\n      name TEXT NOT NULL,\n      created_at TEXT NOT NULL,\n      expires_at TEXT,\n      last_used_at TEXT,\n      FOREIGN KEY (user_id) REFERENCES users(id)\n    );\n\n    CREATE TABLE IF NOT EXISTS sessions (\n      id TEXT PRIMARY KEY,\n      url TEXT NOT NULL,\n      status TEXT NOT NULL DEFAULT 'active',\n      created_at TEXT NOT NULL,\n      updated_at TEXT,\n      project_id TEXT,\n      metadata TEXT,\n      user_id TEXT,\n      FOREIGN KEY (user_id) REFERENCES users(id)\n    );\n\n    CREATE TABLE IF NOT EXISTS annotations (\n      id TEXT PRIMARY KEY,\n      session_id TEXT NOT NULL,\n      x REAL NOT NULL,\n      y REAL NOT NULL,\n      comment TEXT NOT NULL,\n      element TEXT NOT NULL,\n      element_path TEXT NOT NULL,\n      timestamp INTEGER NOT NULL,\n      selected_text TEXT,\n      bounding_box TEXT,\n      nearby_text TEXT,\n      css_classes TEXT,\n      nearby_elements TEXT,\n      computed_styles TEXT,\n      full_path TEXT,\n      accessibility TEXT,\n      is_multi_select INTEGER DEFAULT 0,\n      is_fixed INTEGER DEFAULT 0,\n      react_components TEXT,\n      url TEXT,\n      intent TEXT,\n      severity TEXT,\n      status TEXT DEFAULT 'pending',\n      thread TEXT,\n      created_at TEXT NOT NULL,\n      updated_at TEXT,\n      resolved_at TEXT,\n      resolved_by TEXT,\n      author_id TEXT,\n      FOREIGN KEY (session_id) REFERENCES sessions(id)\n    );\n\n    CREATE TABLE IF NOT EXISTS events (\n      id INTEGER PRIMARY KEY AUTOINCREMENT,\n      type TEXT NOT NULL,\n      timestamp TEXT NOT NULL,\n      session_id TEXT NOT NULL,\n      sequence INTEGER NOT NULL UNIQUE,\n      payload TEXT NOT NULL,\n      user_id TEXT,\n      FOREIGN KEY (user_id) REFERENCES users(id)\n    );\n\n    -- Indexes\n    CREATE INDEX IF NOT EXISTS idx_users_org ON users(org_id);\n    CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);\n    CREATE INDEX IF NOT EXISTS idx_api_keys_user ON api_keys(user_id);\n    CREATE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash);\n    CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(user_id);\n    CREATE INDEX IF NOT EXISTS idx_annotations_session ON annotations(session_id);\n    CREATE INDEX IF NOT EXISTS idx_events_session_seq ON events(session_id, sequence);\n    CREATE INDEX IF NOT EXISTS idx_events_user ON events(user_id);\n  `);\n}\n\n// -----------------------------------------------------------------------------\n// Helpers\n// -----------------------------------------------------------------------------\n\nfunction generateId(): string {\n  return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction rowToSession(row: Record<string, unknown>): Session & { userId?: string } {\n  return {\n    id: row.id as string,\n    url: row.url as string,\n    status: row.status as SessionStatus,\n    createdAt: row.created_at as string,\n    updatedAt: row.updated_at as string | undefined,\n    projectId: row.project_id as string | undefined,\n    metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n    userId: row.user_id as string | undefined,\n  };\n}\n\nfunction rowToOrganization(row: Record<string, unknown>): Organization {\n  return {\n    id: row.id as string,\n    name: row.name as string,\n    createdAt: row.created_at as string,\n    updatedAt: row.updated_at as string | undefined,\n  };\n}\n\nfunction rowToUser(row: Record<string, unknown>): User {\n  return {\n    id: row.id as string,\n    email: row.email as string,\n    orgId: row.org_id as string,\n    role: row.role as UserRole,\n    createdAt: row.created_at as string,\n    updatedAt: row.updated_at as string | undefined,\n  };\n}\n\nfunction rowToApiKey(row: Record<string, unknown>): ApiKey {\n  return {\n    id: row.id as string,\n    keyPrefix: row.key_prefix as string,\n    keyHash: row.key_hash as string,\n    userId: row.user_id as string,\n    name: row.name as string,\n    createdAt: row.created_at as string,\n    expiresAt: row.expires_at as string | undefined,\n    lastUsedAt: row.last_used_at as string | undefined,\n  };\n}\n\nfunction rowToAnnotation(row: Record<string, unknown>): Annotation {\n  return {\n    id: row.id as string,\n    sessionId: row.session_id as string,\n    x: row.x as number,\n    y: row.y as number,\n    comment: row.comment as string,\n    element: row.element as string,\n    elementPath: row.element_path as string,\n    timestamp: row.timestamp as number,\n    selectedText: row.selected_text as string | undefined,\n    boundingBox: row.bounding_box ? JSON.parse(row.bounding_box as string) : undefined,\n    nearbyText: row.nearby_text as string | undefined,\n    cssClasses: row.css_classes as string | undefined,\n    nearbyElements: row.nearby_elements as string | undefined,\n    computedStyles: row.computed_styles as string | undefined,\n    fullPath: row.full_path as string | undefined,\n    accessibility: row.accessibility as string | undefined,\n    isMultiSelect: Boolean(row.is_multi_select),\n    isFixed: Boolean(row.is_fixed),\n    reactComponents: row.react_components as string | undefined,\n    url: row.url as string | undefined,\n    intent: row.intent as Annotation[\"intent\"],\n    severity: row.severity as Annotation[\"severity\"],\n    status: row.status as AnnotationStatus | undefined,\n    thread: row.thread ? JSON.parse(row.thread as string) : undefined,\n    createdAt: row.created_at as string | undefined,\n    updatedAt: row.updated_at as string | undefined,\n    resolvedAt: row.resolved_at as string | undefined,\n    resolvedBy: row.resolved_by as Annotation[\"resolvedBy\"],\n    authorId: row.author_id as string | undefined,\n  };\n}\n\n// -----------------------------------------------------------------------------\n// SQLite Store Implementation\n// -----------------------------------------------------------------------------\n\nexport function createSQLiteStore(dbPath?: string): AFSStore {\n  const db = new Database(dbPath ?? getDbPath());\n  db.pragma(\"journal_mode = WAL\");\n  initDatabase(db);\n\n  // Restore event sequence from last event\n  const lastEvent = db.prepare(\"SELECT MAX(sequence) as seq FROM events\").get() as { seq: number | null };\n  if (lastEvent?.seq) {\n    eventBus.setSequence(lastEvent.seq);\n  }\n\n  // Prepared statements\n  const stmts = {\n    // Sessions\n    insertSession: db.prepare(`\n      INSERT INTO sessions (id, url, status, created_at, project_id, metadata)\n      VALUES (@id, @url, @status, @createdAt, @projectId, @metadata)\n    `),\n    getSession: db.prepare(\"SELECT * FROM sessions WHERE id = ?\"),\n    updateSessionStatus: db.prepare(`\n      UPDATE sessions SET status = @status, updated_at = @updatedAt WHERE id = @id\n    `),\n    listSessions: db.prepare(\"SELECT * FROM sessions ORDER BY created_at DESC\"),\n\n    // Annotations\n    insertAnnotation: db.prepare(`\n      INSERT INTO annotations (\n        id, session_id, x, y, comment, element, element_path, timestamp,\n        selected_text, bounding_box, nearby_text, css_classes, nearby_elements,\n        computed_styles, full_path, accessibility, is_multi_select, is_fixed,\n        react_components, url, intent, severity, status, thread, created_at,\n        updated_at, resolved_at, resolved_by, author_id\n      ) VALUES (\n        @id, @sessionId, @x, @y, @comment, @element, @elementPath, @timestamp,\n        @selectedText, @boundingBox, @nearbyText, @cssClasses, @nearbyElements,\n        @computedStyles, @fullPath, @accessibility, @isMultiSelect, @isFixed,\n        @reactComponents, @url, @intent, @severity, @status, @thread, @createdAt,\n        @updatedAt, @resolvedAt, @resolvedBy, @authorId\n      )\n    `),\n    getAnnotation: db.prepare(\"SELECT * FROM annotations WHERE id = ?\"),\n    getAnnotationsBySession: db.prepare(\"SELECT * FROM annotations WHERE session_id = ? ORDER BY timestamp\"),\n    getPendingAnnotations: db.prepare(\"SELECT * FROM annotations WHERE session_id = ? AND status = 'pending' ORDER BY timestamp\"),\n    deleteAnnotation: db.prepare(\"DELETE FROM annotations WHERE id = ?\"),\n    updateAnnotation: db.prepare(`\n      UPDATE annotations SET\n        comment = COALESCE(@comment, comment),\n        status = COALESCE(@status, status),\n        updated_at = @updatedAt,\n        resolved_at = COALESCE(@resolvedAt, resolved_at),\n        resolved_by = COALESCE(@resolvedBy, resolved_by),\n        thread = COALESCE(@thread, thread),\n        intent = COALESCE(@intent, intent),\n        severity = COALESCE(@severity, severity)\n      WHERE id = @id\n    `),\n\n    // Events\n    insertEvent: db.prepare(`\n      INSERT INTO events (type, timestamp, session_id, sequence, payload)\n      VALUES (@type, @timestamp, @sessionId, @sequence, @payload)\n    `),\n    getEventsSince: db.prepare(`\n      SELECT * FROM events WHERE session_id = ? AND sequence > ? ORDER BY sequence\n    `),\n    pruneOldEvents: db.prepare(`\n      DELETE FROM events WHERE timestamp < ?\n    `),\n  };\n\n  // Prune events older than retention period on startup\n  const retentionDays = parseInt(process.env.AGENTATION_EVENT_RETENTION_DAYS || \"7\", 10);\n  const cutoff = new Date(Date.now() - retentionDays * 24 * 60 * 60 * 1000).toISOString();\n  stmts.pruneOldEvents.run(cutoff);\n\n  function persistEvent(event: AFSEvent): void {\n    stmts.insertEvent.run({\n      type: event.type,\n      timestamp: event.timestamp,\n      sessionId: event.sessionId,\n      sequence: event.sequence,\n      payload: JSON.stringify(event.payload),\n    });\n  }\n\n  return {\n    // Sessions\n    createSession(url: string, projectId?: string): Session {\n      const session: Session = {\n        id: generateId(),\n        url,\n        status: \"active\",\n        createdAt: new Date().toISOString(),\n        projectId,\n      };\n\n      stmts.insertSession.run({\n        id: session.id,\n        url: session.url,\n        status: session.status,\n        createdAt: session.createdAt,\n        projectId: session.projectId ?? null,\n        metadata: null,\n      });\n\n      const event = eventBus.emit(\"session.created\", session.id, session);\n      persistEvent(event);\n\n      return session;\n    },\n\n    getSession(id: string): Session | undefined {\n      const row = stmts.getSession.get(id) as Record<string, unknown> | undefined;\n      return row ? rowToSession(row) : undefined;\n    },\n\n    getSessionWithAnnotations(id: string): SessionWithAnnotations | undefined {\n      const sessionRow = stmts.getSession.get(id) as Record<string, unknown> | undefined;\n      if (!sessionRow) return undefined;\n\n      const annotationRows = stmts.getAnnotationsBySession.all(id) as Record<string, unknown>[];\n\n      return {\n        ...rowToSession(sessionRow),\n        annotations: annotationRows.map(rowToAnnotation),\n      };\n    },\n\n    updateSessionStatus(id: string, status: SessionStatus): Session | undefined {\n      const updatedAt = new Date().toISOString();\n      const result = stmts.updateSessionStatus.run({ id, status, updatedAt });\n      if (result.changes === 0) return undefined;\n\n      const session = this.getSession(id);\n      if (session) {\n        const eventType: AFSEventType = status === \"closed\" ? \"session.closed\" : \"session.updated\";\n        const event = eventBus.emit(eventType, id, session);\n        persistEvent(event);\n      }\n      return session;\n    },\n\n    listSessions(): Session[] {\n      const rows = stmts.listSessions.all() as Record<string, unknown>[];\n      return rows.map(rowToSession);\n    },\n\n    // Annotations\n    addAnnotation(\n      sessionId: string,\n      data: Omit<Annotation, \"id\" | \"sessionId\" | \"status\" | \"createdAt\">\n    ): Annotation | undefined {\n      const session = this.getSession(sessionId);\n      if (!session) return undefined;\n\n      const annotation: Annotation = {\n        ...data,\n        id: generateId(),\n        sessionId,\n        status: \"pending\",\n        createdAt: new Date().toISOString(),\n      };\n\n      stmts.insertAnnotation.run({\n        id: annotation.id,\n        sessionId: annotation.sessionId,\n        x: annotation.x,\n        y: annotation.y,\n        comment: annotation.comment,\n        element: annotation.element,\n        elementPath: annotation.elementPath,\n        timestamp: annotation.timestamp,\n        selectedText: annotation.selectedText ?? null,\n        boundingBox: annotation.boundingBox ? JSON.stringify(annotation.boundingBox) : null,\n        nearbyText: annotation.nearbyText ?? null,\n        cssClasses: annotation.cssClasses ?? null,\n        nearbyElements: annotation.nearbyElements ?? null,\n        computedStyles: annotation.computedStyles ?? null,\n        fullPath: annotation.fullPath ?? null,\n        accessibility: annotation.accessibility ?? null,\n        isMultiSelect: annotation.isMultiSelect ? 1 : 0,\n        isFixed: annotation.isFixed ? 1 : 0,\n        reactComponents: annotation.reactComponents ?? null,\n        url: annotation.url ?? null,\n        intent: annotation.intent ?? null,\n        severity: annotation.severity ?? null,\n        status: annotation.status ?? \"pending\",\n        thread: annotation.thread ? JSON.stringify(annotation.thread) : null,\n        createdAt: annotation.createdAt ?? new Date().toISOString(),\n        updatedAt: null,\n        resolvedAt: null,\n        resolvedBy: null,\n        authorId: annotation.authorId ?? null,\n      });\n\n      const event = eventBus.emit(\"annotation.created\", sessionId, annotation);\n      persistEvent(event);\n\n      return annotation;\n    },\n\n    getAnnotation(id: string): Annotation | undefined {\n      const row = stmts.getAnnotation.get(id) as Record<string, unknown> | undefined;\n      return row ? rowToAnnotation(row) : undefined;\n    },\n\n    updateAnnotation(\n      id: string,\n      data: Partial<Omit<Annotation, \"id\" | \"sessionId\" | \"createdAt\">>\n    ): Annotation | undefined {\n      const existing = this.getAnnotation(id);\n      if (!existing) return undefined;\n\n      stmts.updateAnnotation.run({\n        id,\n        comment: data.comment ?? null,\n        status: data.status ?? null,\n        updatedAt: new Date().toISOString(),\n        resolvedAt: data.resolvedAt ?? null,\n        resolvedBy: data.resolvedBy ?? null,\n        thread: data.thread ? JSON.stringify(data.thread) : null,\n        intent: data.intent ?? null,\n        severity: data.severity ?? null,\n      });\n\n      const updated = this.getAnnotation(id);\n      if (updated && existing.sessionId) {\n        const event = eventBus.emit(\"annotation.updated\", existing.sessionId, updated);\n        persistEvent(event);\n      }\n      return updated;\n    },\n\n    updateAnnotationStatus(\n      id: string,\n      status: AnnotationStatus,\n      resolvedBy?: \"human\" | \"agent\"\n    ): Annotation | undefined {\n      const isResolved = status === \"resolved\" || status === \"dismissed\";\n      return this.updateAnnotation(id, {\n        status,\n        resolvedAt: isResolved ? new Date().toISOString() : undefined,\n        resolvedBy: isResolved ? (resolvedBy || \"agent\") : undefined,\n      });\n    },\n\n    addThreadMessage(\n      annotationId: string,\n      role: \"human\" | \"agent\",\n      content: string\n    ): Annotation | undefined {\n      const existing = this.getAnnotation(annotationId);\n      if (!existing) return undefined;\n\n      const message: ThreadMessage = {\n        id: generateId(),\n        role,\n        content,\n        timestamp: Date.now(),\n      };\n\n      const thread = [...(existing.thread || []), message];\n      const updated = this.updateAnnotation(annotationId, { thread });\n\n      if (updated && existing.sessionId) {\n        const event = eventBus.emit(\"thread.message\", existing.sessionId, message);\n        persistEvent(event);\n      }\n\n      return updated;\n    },\n\n    getPendingAnnotations(sessionId: string): Annotation[] {\n      const rows = stmts.getPendingAnnotations.all(sessionId) as Record<string, unknown>[];\n      return rows.map(rowToAnnotation);\n    },\n\n    getSessionAnnotations(sessionId: string): Annotation[] {\n      const rows = stmts.getAnnotationsBySession.all(sessionId) as Record<string, unknown>[];\n      return rows.map(rowToAnnotation);\n    },\n\n    deleteAnnotation(id: string): Annotation | undefined {\n      const existing = this.getAnnotation(id);\n      if (!existing) return undefined;\n\n      stmts.deleteAnnotation.run(id);\n\n      if (existing.sessionId) {\n        const event = eventBus.emit(\"annotation.deleted\", existing.sessionId, existing);\n        persistEvent(event);\n      }\n\n      return existing;\n    },\n\n    // Events\n    getEventsSince(sessionId: string, sequence: number): AFSEvent[] {\n      const rows = stmts.getEventsSince.all(sessionId, sequence) as Record<string, unknown>[];\n      return rows.map((row) => ({\n        type: row.type as AFSEventType,\n        timestamp: row.timestamp as string,\n        sessionId: row.session_id as string,\n        sequence: row.sequence as number,\n        payload: JSON.parse(row.payload as string),\n      }));\n    },\n\n    // Lifecycle\n    close(): void {\n      db.close();\n    },\n  };\n}\n\n// -----------------------------------------------------------------------------\n// Tenant Store Interface\n// -----------------------------------------------------------------------------\n\nexport interface TenantStore {\n  // Organizations\n  createOrganization(name: string): Organization;\n  getOrganization(id: string): Organization | undefined;\n\n  // Users\n  createUser(email: string, orgId: string, role?: UserRole): User;\n  getUser(id: string): User | undefined;\n  getUserByEmail(email: string): User | undefined;\n  getUsersByOrg(orgId: string): User[];\n\n  // API Keys\n  createApiKey(userId: string, name: string, expiresAt?: string): { apiKey: ApiKey; rawKey: string };\n  getApiKeyByHash(hash: string): ApiKey | undefined;\n  listApiKeys(userId: string): ApiKey[];\n  deleteApiKey(id: string): boolean;\n  updateApiKeyLastUsed(id: string): void;\n\n  // User-scoped sessions\n  createSessionForUser(userId: string, url: string, projectId?: string): Session;\n  listSessionsForUser(userId: string): Session[];\n  getSessionForUser(userId: string, sessionId: string): Session | undefined;\n  getSessionWithAnnotationsForUser(userId: string, sessionId: string): SessionWithAnnotations | undefined;\n\n  // User-scoped annotations\n  getPendingAnnotationsForUser(userId: string, sessionId: string): Annotation[];\n  getAllPendingForUser(userId: string): Annotation[];\n\n  // Lifecycle\n  close(): void;\n}\n\n// -----------------------------------------------------------------------------\n// Tenant Store Implementation\n// -----------------------------------------------------------------------------\n\nexport function createTenantStore(dbPath?: string): TenantStore {\n  const db = new Database(dbPath ?? getDbPath());\n  db.pragma(\"journal_mode = WAL\");\n  initDatabase(db);\n\n  // Restore event sequence from last event\n  const lastEvent = db.prepare(\"SELECT MAX(sequence) as seq FROM events\").get() as { seq: number | null };\n  if (lastEvent?.seq) {\n    eventBus.setSequence(lastEvent.seq);\n  }\n\n  // Prepared statements for tenant operations\n  const tenantStmts = {\n    // Organizations\n    insertOrg: db.prepare(`\n      INSERT INTO organizations (id, name, created_at)\n      VALUES (@id, @name, @createdAt)\n    `),\n    getOrg: db.prepare(\"SELECT * FROM organizations WHERE id = ?\"),\n\n    // Users\n    insertUser: db.prepare(`\n      INSERT INTO users (id, email, org_id, role, created_at)\n      VALUES (@id, @email, @orgId, @role, @createdAt)\n    `),\n    getUser: db.prepare(\"SELECT * FROM users WHERE id = ?\"),\n    getUserByEmail: db.prepare(\"SELECT * FROM users WHERE email = ?\"),\n    getUsersByOrg: db.prepare(\"SELECT * FROM users WHERE org_id = ?\"),\n\n    // API Keys\n    insertApiKey: db.prepare(`\n      INSERT INTO api_keys (id, key_prefix, key_hash, user_id, name, created_at, expires_at)\n      VALUES (@id, @keyPrefix, @keyHash, @userId, @name, @createdAt, @expiresAt)\n    `),\n    getApiKeyByHash: db.prepare(\"SELECT * FROM api_keys WHERE key_hash = ?\"),\n    listApiKeys: db.prepare(\"SELECT * FROM api_keys WHERE user_id = ? ORDER BY created_at DESC\"),\n    deleteApiKey: db.prepare(\"DELETE FROM api_keys WHERE id = ?\"),\n    updateApiKeyLastUsed: db.prepare(\"UPDATE api_keys SET last_used_at = ? WHERE id = ?\"),\n\n    // User-scoped sessions\n    insertSessionForUser: db.prepare(`\n      INSERT INTO sessions (id, url, status, created_at, project_id, metadata, user_id)\n      VALUES (@id, @url, @status, @createdAt, @projectId, @metadata, @userId)\n    `),\n    listSessionsForUser: db.prepare(\"SELECT * FROM sessions WHERE user_id = ? ORDER BY created_at DESC\"),\n    getSessionForUser: db.prepare(\"SELECT * FROM sessions WHERE id = ? AND user_id = ?\"),\n    getAnnotationsBySession: db.prepare(\"SELECT * FROM annotations WHERE session_id = ? ORDER BY timestamp\"),\n    getPendingAnnotationsForSession: db.prepare(\"SELECT * FROM annotations WHERE session_id = ? AND status = 'pending' ORDER BY timestamp\"),\n\n    // Get all pending for a user (across all their sessions)\n    getAllPendingForUser: db.prepare(`\n      SELECT a.* FROM annotations a\n      JOIN sessions s ON a.session_id = s.id\n      WHERE s.user_id = ? AND a.status = 'pending'\n      ORDER BY a.timestamp\n    `),\n\n    // Events\n    insertEvent: db.prepare(`\n      INSERT INTO events (type, timestamp, session_id, sequence, payload, user_id)\n      VALUES (@type, @timestamp, @sessionId, @sequence, @payload, @userId)\n    `),\n\n    // Prune old events\n    pruneOldEvents: db.prepare(`\n      DELETE FROM events WHERE timestamp < ?\n    `),\n  };\n\n  // Prune events older than retention period on startup\n  const retentionDays = parseInt(process.env.AGENTATION_EVENT_RETENTION_DAYS || \"7\", 10);\n  const cutoff = new Date(Date.now() - retentionDays * 24 * 60 * 60 * 1000).toISOString();\n  tenantStmts.pruneOldEvents.run(cutoff);\n\n  function persistEventForUser(event: AFSEvent, userId: string): void {\n    tenantStmts.insertEvent.run({\n      type: event.type,\n      timestamp: event.timestamp,\n      sessionId: event.sessionId,\n      sequence: event.sequence,\n      payload: JSON.stringify(event.payload),\n      userId,\n    });\n  }\n\n  return {\n    // Organizations\n    createOrganization(name: string): Organization {\n      const org: Organization = {\n        id: `org_${generateId()}`,\n        name,\n        createdAt: new Date().toISOString(),\n      };\n\n      tenantStmts.insertOrg.run({\n        id: org.id,\n        name: org.name,\n        createdAt: org.createdAt,\n      });\n\n      return org;\n    },\n\n    getOrganization(id: string): Organization | undefined {\n      const row = tenantStmts.getOrg.get(id) as Record<string, unknown> | undefined;\n      return row ? rowToOrganization(row) : undefined;\n    },\n\n    // Users\n    createUser(email: string, orgId: string, role: UserRole = \"member\"): User {\n      const user: User = {\n        id: `user_${generateId()}`,\n        email,\n        orgId,\n        role,\n        createdAt: new Date().toISOString(),\n      };\n\n      tenantStmts.insertUser.run({\n        id: user.id,\n        email: user.email,\n        orgId: user.orgId,\n        role: user.role,\n        createdAt: user.createdAt,\n      });\n\n      return user;\n    },\n\n    getUser(id: string): User | undefined {\n      const row = tenantStmts.getUser.get(id) as Record<string, unknown> | undefined;\n      return row ? rowToUser(row) : undefined;\n    },\n\n    getUserByEmail(email: string): User | undefined {\n      const row = tenantStmts.getUserByEmail.get(email) as Record<string, unknown> | undefined;\n      return row ? rowToUser(row) : undefined;\n    },\n\n    getUsersByOrg(orgId: string): User[] {\n      const rows = tenantStmts.getUsersByOrg.all(orgId) as Record<string, unknown>[];\n      return rows.map(rowToUser);\n    },\n\n    // API Keys\n    createApiKey(userId: string, name: string, expiresAt?: string): { apiKey: ApiKey; rawKey: string } {\n      const id = `key_${generateId()}`;\n      // Generate a secure random key\n      const rawKey = `sk_live_${randomBytes(32).toString(\"base64url\")}`;\n      const keyPrefix = rawKey.substring(0, 12); // \"sk_live_xxxx\"\n\n      // Hash the key for storage\n      const keyHash = createHash(\"sha256\").update(rawKey).digest(\"hex\");\n\n      const apiKey: ApiKey = {\n        id,\n        keyPrefix,\n        keyHash,\n        userId,\n        name,\n        createdAt: new Date().toISOString(),\n        expiresAt,\n      };\n\n      tenantStmts.insertApiKey.run({\n        id: apiKey.id,\n        keyPrefix: apiKey.keyPrefix,\n        keyHash: apiKey.keyHash,\n        userId: apiKey.userId,\n        name: apiKey.name,\n        createdAt: apiKey.createdAt,\n        expiresAt: apiKey.expiresAt ?? null,\n      });\n\n      return { apiKey, rawKey };\n    },\n\n    getApiKeyByHash(hash: string): ApiKey | undefined {\n      const row = tenantStmts.getApiKeyByHash.get(hash) as Record<string, unknown> | undefined;\n      return row ? rowToApiKey(row) : undefined;\n    },\n\n    listApiKeys(userId: string): ApiKey[] {\n      const rows = tenantStmts.listApiKeys.all(userId) as Record<string, unknown>[];\n      return rows.map(rowToApiKey);\n    },\n\n    deleteApiKey(id: string): boolean {\n      const result = tenantStmts.deleteApiKey.run(id);\n      return result.changes > 0;\n    },\n\n    updateApiKeyLastUsed(id: string): void {\n      tenantStmts.updateApiKeyLastUsed.run(new Date().toISOString(), id);\n    },\n\n    // User-scoped sessions\n    createSessionForUser(userId: string, url: string, projectId?: string): Session {\n      const session: Session = {\n        id: generateId(),\n        url,\n        status: \"active\",\n        createdAt: new Date().toISOString(),\n        projectId,\n      };\n\n      tenantStmts.insertSessionForUser.run({\n        id: session.id,\n        url: session.url,\n        status: session.status,\n        createdAt: session.createdAt,\n        projectId: session.projectId ?? null,\n        metadata: null,\n        userId,\n      });\n\n      const event = eventBus.emit(\"session.created\", session.id, session);\n      persistEventForUser(event, userId);\n\n      return session;\n    },\n\n    listSessionsForUser(userId: string): Session[] {\n      const rows = tenantStmts.listSessionsForUser.all(userId) as Record<string, unknown>[];\n      return rows.map(rowToSession);\n    },\n\n    getSessionForUser(userId: string, sessionId: string): Session | undefined {\n      const row = tenantStmts.getSessionForUser.get(sessionId, userId) as Record<string, unknown> | undefined;\n      return row ? rowToSession(row) : undefined;\n    },\n\n    getSessionWithAnnotationsForUser(userId: string, sessionId: string): SessionWithAnnotations | undefined {\n      const sessionRow = tenantStmts.getSessionForUser.get(sessionId, userId) as Record<string, unknown> | undefined;\n      if (!sessionRow) return undefined;\n\n      const annotationRows = tenantStmts.getAnnotationsBySession.all(sessionId) as Record<string, unknown>[];\n\n      return {\n        ...rowToSession(sessionRow),\n        annotations: annotationRows.map(rowToAnnotation),\n      };\n    },\n\n    // User-scoped annotations\n    getPendingAnnotationsForUser(userId: string, sessionId: string): Annotation[] {\n      // First verify the session belongs to the user\n      const session = this.getSessionForUser(userId, sessionId);\n      if (!session) return [];\n\n      const rows = tenantStmts.getPendingAnnotationsForSession.all(sessionId) as Record<string, unknown>[];\n      return rows.map(rowToAnnotation);\n    },\n\n    getAllPendingForUser(userId: string): Annotation[] {\n      const rows = tenantStmts.getAllPendingForUser.all(userId) as Record<string, unknown>[];\n      return rows.map(rowToAnnotation);\n    },\n\n    // Lifecycle\n    close(): void {\n      db.close();\n    },\n  };\n}\n","/**\n * HTTP server for the Agentation API.\n * Uses native Node.js http module - no frameworks.\n */\n\nimport { createServer, type IncomingMessage, type ServerResponse } from \"http\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport {\n  CallToolRequestSchema,\n  ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { TOOLS, handleTool, error as toolError } from \"./mcp.js\";\nimport {\n  createSession,\n  getSession,\n  getSessionWithAnnotations,\n  addAnnotation,\n  updateAnnotation,\n  getAnnotation,\n  deleteAnnotation,\n  listSessions,\n  getPendingAnnotations,\n  addThreadMessage,\n  getEventsSince,\n} from \"./store.js\";\nimport { eventBus } from \"./events.js\";\nimport type { Annotation, AFSEvent, ActionRequest } from \"../types.js\";\n\n/**\n * Log to stderr so diagnostic output never corrupts the MCP stdio channel.\n * When `server` runs without --mcp-only, both the HTTP server and MCP stdio\n * server share the same process. stdout is reserved for JSON-RPC messages,\n * so all logging must go to stderr.\n */\nfunction log(message: string): void {\n  process.stderr.write(message + \"\\n\");\n}\n\n// Cloud API configuration\nlet cloudApiKey: string | undefined;\nconst CLOUD_API_URL = \"https://agentation-mcp-cloud.vercel.app/api\";\n\n/**\n * Set the API key for cloud storage mode.\n * When set, the HTTP server proxies requests to the cloud API.\n */\nexport function setCloudApiKey(key: string | undefined): void {\n  cloudApiKey = key;\n}\n\n/**\n * Check if we're in cloud mode (API key is set).\n */\nfunction isCloudMode(): boolean {\n  return !!cloudApiKey;\n}\n\n// Track active SSE connections for cleanup\nconst sseConnections = new Set<ServerResponse>();\n// Track agent SSE connections separately (for accurate delivery status)\n// These are connections from MCP tools (e.g. watch_annotations), not browser toolbars\nconst agentConnections = new Set<ServerResponse>();\n\n// -----------------------------------------------------------------------------\n// MCP HTTP Transport\n// -----------------------------------------------------------------------------\n\n// Store transports by session ID for stateful sessions\nconst mcpTransports = new Map<string, StreamableHTTPServerTransport>();\n\n/**\n * Initialize a new MCP server with HTTP transport for a session.\n */\nfunction createMcpSession(): { server: Server; transport: StreamableHTTPServerTransport } {\n  const transport = new StreamableHTTPServerTransport({\n    sessionIdGenerator: () => crypto.randomUUID(),\n  });\n\n  const server = new Server(\n    { name: \"agentation\", version: \"0.0.1\" },\n    { capabilities: { tools: {} } }\n  );\n\n  server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: TOOLS }));\n  server.setRequestHandler(CallToolRequestSchema, async (req) => {\n    try {\n      return await handleTool(req.params.name, req.params.arguments);\n    } catch (err) {\n      const message = err instanceof Error ? err.message : \"Unknown error\";\n      return toolError(message);\n    }\n  });\n\n  server.connect(transport);\n  return { server, transport };\n}\n\n// -----------------------------------------------------------------------------\n// Webhook Support\n// -----------------------------------------------------------------------------\n\n/**\n * Get configured webhook URLs from environment variables.\n *\n * Supports:\n * - AGENTATION_WEBHOOK_URL: Single webhook URL\n * - AGENTATION_WEBHOOKS: Comma-separated list of webhook URLs\n */\nfunction getWebhookUrls(): string[] {\n  const urls: string[] = [];\n\n  // Single webhook URL\n  const singleUrl = process.env.AGENTATION_WEBHOOK_URL;\n  if (singleUrl) {\n    urls.push(singleUrl.trim());\n  }\n\n  // Multiple webhook URLs (comma-separated)\n  const multipleUrls = process.env.AGENTATION_WEBHOOKS;\n  if (multipleUrls) {\n    const parsed = multipleUrls\n      .split(\",\")\n      .map((url) => url.trim())\n      .filter((url) => url.length > 0);\n    urls.push(...parsed);\n  }\n\n  return urls;\n}\n\n/**\n * Send webhook notification for an action request.\n * Fire-and-forget: doesn't wait for response, logs errors but doesn't throw.\n */\nfunction sendWebhooks(actionRequest: ActionRequest): void {\n  const webhookUrls = getWebhookUrls();\n\n  if (webhookUrls.length === 0) {\n    return;\n  }\n\n  const payload = JSON.stringify(actionRequest);\n\n  for (const url of webhookUrls) {\n    // Fire and forget - use .then().catch() instead of await\n    fetch(url, {\n      method: \"POST\",\n      headers: {\n        \"Content-Type\": \"application/json\",\n        \"User-Agent\": \"Agentation-Webhook/1.0\",\n      },\n      body: payload,\n    })\n      .then((res) => {\n        log(\n          `[Webhook] POST ${url} -> ${res.status} ${res.statusText}`\n        );\n      })\n      .catch((err) => {\n        console.error(`[Webhook] POST ${url} failed:`, (err as Error).message);\n      });\n  }\n\n  log(\n    `[Webhook] Fired ${webhookUrls.length} webhook(s) for session ${actionRequest.sessionId}`\n  );\n}\n\n// -----------------------------------------------------------------------------\n// Request Helpers\n// -----------------------------------------------------------------------------\n\n/**\n * Parse JSON body from request.\n */\nasync function parseBody<T>(req: IncomingMessage): Promise<T> {\n  return new Promise((resolve, reject) => {\n    let body = \"\";\n    req.on(\"data\", (chunk) => (body += chunk));\n    req.on(\"end\", () => {\n      try {\n        resolve(body ? JSON.parse(body) : {});\n      } catch {\n        reject(new Error(\"Invalid JSON\"));\n      }\n    });\n    req.on(\"error\", reject);\n  });\n}\n\n/**\n * Send JSON response.\n */\nfunction sendJson(res: ServerResponse, status: number, data: unknown): void {\n  res.writeHead(status, {\n    \"Content-Type\": \"application/json\",\n    \"Access-Control-Allow-Origin\": \"*\",\n    \"Access-Control-Allow-Methods\": \"GET, POST, PATCH, DELETE, OPTIONS\",\n    \"Access-Control-Allow-Headers\": \"Content-Type\",\n  });\n  res.end(JSON.stringify(data));\n}\n\n/**\n * Send error response.\n */\nfunction sendError(res: ServerResponse, status: number, message: string): void {\n  sendJson(res, status, { error: message });\n}\n\n/**\n * Handle CORS preflight.\n */\nfunction handleCors(res: ServerResponse): void {\n  res.writeHead(204, {\n    \"Access-Control-Allow-Origin\": \"*\",\n    \"Access-Control-Allow-Methods\": \"GET, POST, PATCH, DELETE, OPTIONS\",\n    \"Access-Control-Allow-Headers\": \"Content-Type, Accept, Mcp-Session-Id\",\n    \"Access-Control-Expose-Headers\": \"Mcp-Session-Id\",\n    \"Access-Control-Max-Age\": \"86400\",\n  });\n  res.end();\n}\n\n// -----------------------------------------------------------------------------\n// Cloud Proxy\n// -----------------------------------------------------------------------------\n\n/**\n * Proxy a request to the cloud API.\n */\nasync function proxyToCloud(\n  req: IncomingMessage,\n  res: ServerResponse,\n  pathname: string\n): Promise<void> {\n  const method = req.method || \"GET\";\n  const cloudUrl = `${CLOUD_API_URL}${pathname}`;\n\n  const headers: Record<string, string> = {\n    \"x-api-key\": cloudApiKey!,\n  };\n\n  // Forward content-type for requests with body\n  if (req.headers[\"content-type\"]) {\n    headers[\"Content-Type\"] = req.headers[\"content-type\"];\n  }\n\n  let body: string | undefined;\n  if (method !== \"GET\" && method !== \"HEAD\") {\n    body = await new Promise<string>((resolve, reject) => {\n      let data = \"\";\n      req.on(\"data\", (chunk) => (data += chunk));\n      req.on(\"end\", () => resolve(data));\n      req.on(\"error\", reject);\n    });\n  }\n\n  try {\n    const cloudRes = await fetch(cloudUrl, {\n      method,\n      headers,\n      body,\n    });\n\n    // Handle SSE responses\n    if (cloudRes.headers.get(\"content-type\")?.includes(\"text/event-stream\")) {\n      res.writeHead(cloudRes.status, {\n        \"Content-Type\": \"text/event-stream\",\n        \"Cache-Control\": \"no-cache\",\n        Connection: \"keep-alive\",\n        \"Access-Control-Allow-Origin\": \"*\",\n      });\n\n      const reader = cloudRes.body?.getReader();\n      if (reader) {\n        const pump = async () => {\n          while (true) {\n            const { done, value } = await reader.read();\n            if (done) break;\n            res.write(value);\n          }\n          res.end();\n        };\n        pump().catch(() => res.end());\n\n        req.on(\"close\", () => {\n          reader.cancel();\n        });\n      }\n      return;\n    }\n\n    // Handle regular JSON responses\n    const data = await cloudRes.text();\n    res.writeHead(cloudRes.status, {\n      \"Content-Type\": cloudRes.headers.get(\"content-type\") || \"application/json\",\n      \"Access-Control-Allow-Origin\": \"*\",\n      \"Access-Control-Allow-Methods\": \"GET, POST, PATCH, DELETE, OPTIONS\",\n      \"Access-Control-Allow-Headers\": \"Content-Type\",\n    });\n    res.end(data);\n  } catch (err) {\n    console.error(\"[Cloud Proxy] Error:\", err);\n    sendError(res, 502, `Cloud proxy error: ${(err as Error).message}`);\n  }\n}\n\n// -----------------------------------------------------------------------------\n// Route Handlers\n// -----------------------------------------------------------------------------\n\ntype RouteHandler = (\n  req: IncomingMessage,\n  res: ServerResponse,\n  params: Record<string, string>\n) => Promise<void>;\n\n/**\n * POST /sessions - Create a new session.\n */\nconst createSessionHandler: RouteHandler = async (req, res) => {\n  try {\n    const body = await parseBody<{ url: string; projectId?: string }>(req);\n\n    if (!body.url) {\n      return sendError(res, 400, \"url is required\");\n    }\n\n    const session = createSession(body.url, body.projectId);\n    sendJson(res, 201, session);\n  } catch (err) {\n    sendError(res, 400, (err as Error).message);\n  }\n};\n\n/**\n * GET /sessions - List all sessions.\n */\nconst listSessionsHandler: RouteHandler = async (_req, res) => {\n  const sessions = listSessions();\n  sendJson(res, 200, sessions);\n};\n\n/**\n * GET /sessions/:id - Get a session with annotations.\n */\nconst getSessionHandler: RouteHandler = async (_req, res, params) => {\n  const session = getSessionWithAnnotations(params.id);\n\n  if (!session) {\n    return sendError(res, 404, \"Session not found\");\n  }\n\n  sendJson(res, 200, session);\n};\n\n/**\n * POST /sessions/:id/annotations - Add annotation to session.\n */\nconst addAnnotationHandler: RouteHandler = async (req, res, params) => {\n  try {\n    const body = await parseBody<Omit<Annotation, \"id\" | \"sessionId\" | \"status\" | \"createdAt\">>(req);\n\n    if (!body.comment || !body.element || !body.elementPath) {\n      return sendError(res, 400, \"comment, element, and elementPath are required\");\n    }\n\n    const annotation = addAnnotation(params.id, body);\n\n    if (!annotation) {\n      return sendError(res, 404, \"Session not found\");\n    }\n\n    sendJson(res, 201, annotation);\n  } catch (err) {\n    sendError(res, 400, (err as Error).message);\n  }\n};\n\n/**\n * PATCH /annotations/:id - Update an annotation.\n */\nconst updateAnnotationHandler: RouteHandler = async (req, res, params) => {\n  try {\n    const body = await parseBody<Partial<Annotation>>(req);\n\n    // Check if annotation exists\n    const existing = getAnnotation(params.id);\n    if (!existing) {\n      return sendError(res, 404, \"Annotation not found\");\n    }\n\n    const annotation = updateAnnotation(params.id, body);\n    sendJson(res, 200, annotation);\n  } catch (err) {\n    sendError(res, 400, (err as Error).message);\n  }\n};\n\n/**\n * GET /annotations/:id - Get an annotation.\n */\nconst getAnnotationHandler: RouteHandler = async (_req, res, params) => {\n  const annotation = getAnnotation(params.id);\n\n  if (!annotation) {\n    return sendError(res, 404, \"Annotation not found\");\n  }\n\n  sendJson(res, 200, annotation);\n};\n\n/**\n * DELETE /annotations/:id - Delete an annotation.\n */\nconst deleteAnnotationHandler: RouteHandler = async (_req, res, params) => {\n  const annotation = deleteAnnotation(params.id);\n\n  if (!annotation) {\n    return sendError(res, 404, \"Annotation not found\");\n  }\n\n  sendJson(res, 200, { deleted: true, annotationId: params.id });\n};\n\n/**\n * GET /sessions/:id/pending - Get pending annotations for a session.\n */\nconst getPendingHandler: RouteHandler = async (_req, res, params) => {\n  const pending = getPendingAnnotations(params.id);\n  sendJson(res, 200, { count: pending.length, annotations: pending });\n};\n\n/**\n * GET /pending - Get all pending annotations across all sessions.\n */\nconst getAllPendingHandler: RouteHandler = async (_req, res) => {\n  const sessions = listSessions();\n  const allPending = sessions.flatMap((session) => getPendingAnnotations(session.id));\n  sendJson(res, 200, { count: allPending.length, annotations: allPending });\n};\n\n/**\n * POST /sessions/:id/action - Request agent action on annotations.\n *\n * Emits an action.requested event via SSE with the current annotations\n * and formatted output. The agent can listen for this event to know\n * when the user wants action taken.\n *\n * Also sends webhooks to configured URLs (via AGENTATION_WEBHOOK_URL or\n * AGENTATION_WEBHOOKS environment variables).\n */\nconst requestActionHandler: RouteHandler = async (req, res, params) => {\n  try {\n    const sessionId = params.id;\n    const body = await parseBody<{ output: string }>(req);\n\n    // Verify session exists\n    const session = getSessionWithAnnotations(sessionId);\n    if (!session) {\n      return sendError(res, 404, \"Session not found\");\n    }\n\n    if (!body.output) {\n      return sendError(res, 400, \"output is required\");\n    }\n\n    // Build action request payload\n    const actionRequest: ActionRequest = {\n      sessionId,\n      annotations: session.annotations,\n      output: body.output,\n      timestamp: new Date().toISOString(),\n    };\n\n    // Emit event (will be sent to all SSE subscribers)\n    eventBus.emit(\"action.requested\", sessionId, actionRequest);\n\n    // Send webhooks (fire and forget, non-blocking)\n    const webhookUrls = getWebhookUrls();\n    sendWebhooks(actionRequest);\n\n    // Return delivery info so client knows if anyone received it\n    // Only count agent connections (with ?agent=true), not browser toolbar connections\n    const agentListeners = agentConnections.size;\n    const webhooks = webhookUrls.length;\n\n    sendJson(res, 200, {\n      success: true,\n      annotationCount: session.annotations.length,\n      delivered: {\n        sseListeners: agentListeners,\n        webhooks: webhooks,\n        total: agentListeners + webhooks,\n      },\n    });\n  } catch (err) {\n    sendError(res, 400, (err as Error).message);\n  }\n};\n\n/**\n * POST /annotations/:id/thread - Add a thread message.\n */\nconst addThreadHandler: RouteHandler = async (req, res, params) => {\n  try {\n    const body = await parseBody<{ role: \"human\" | \"agent\"; content: string }>(req);\n\n    if (!body.role || !body.content) {\n      return sendError(res, 400, \"role and content are required\");\n    }\n\n    const annotation = addThreadMessage(params.id, body.role, body.content);\n\n    if (!annotation) {\n      return sendError(res, 404, \"Annotation not found\");\n    }\n\n    sendJson(res, 201, annotation);\n  } catch (err) {\n    sendError(res, 400, (err as Error).message);\n  }\n};\n\n/**\n * GET /sessions/:id/events - SSE stream of events for a session.\n *\n * Supports reconnection via Last-Event-ID header.\n * Events are streamed in real-time as they occur.\n */\nconst sseHandler: RouteHandler = async (req, res, params) => {\n  const sessionId = params.id;\n  const url = new URL(req.url || \"/\", \"http://localhost\");\n  const isAgent = url.searchParams.get(\"agent\") === \"true\";\n\n  // Verify session exists\n  const session = getSessionWithAnnotations(sessionId);\n  if (!session) {\n    return sendError(res, 404, \"Session not found\");\n  }\n\n  // Set up SSE headers\n  res.writeHead(200, {\n    \"Content-Type\": \"text/event-stream\",\n    \"Cache-Control\": \"no-cache\",\n    Connection: \"keep-alive\",\n    \"Access-Control-Allow-Origin\": \"*\",\n  });\n\n  // Track this connection\n  sseConnections.add(res);\n  if (isAgent) {\n    agentConnections.add(res);\n  }\n\n  // Send initial comment to establish connection\n  res.write(\": connected\\n\\n\");\n\n  // Check for Last-Event-ID for replay\n  const lastEventId = req.headers[\"last-event-id\"];\n  if (lastEventId) {\n    const lastSequence = parseInt(lastEventId as string, 10);\n    if (!isNaN(lastSequence)) {\n      // Replay missed events\n      const missedEvents = getEventsSince(sessionId, lastSequence);\n      for (const event of missedEvents) {\n        sendSSEEvent(res, event);\n      }\n    }\n  }\n\n  // Subscribe to new events\n  const unsubscribe = eventBus.subscribeToSession(sessionId, (event: AFSEvent) => {\n    sendSSEEvent(res, event);\n  });\n\n  // Keep connection alive with periodic comments\n  const keepAlive = setInterval(() => {\n    res.write(\": ping\\n\\n\");\n  }, 30000);\n\n  // Clean up on disconnect\n  req.on(\"close\", () => {\n    clearInterval(keepAlive);\n    unsubscribe();\n    sseConnections.delete(res);\n    agentConnections.delete(res);\n  });\n};\n\n/**\n * Send an SSE event to a response stream.\n */\nfunction sendSSEEvent(res: ServerResponse, event: AFSEvent): void {\n  res.write(`event: ${event.type}\\n`);\n  res.write(`id: ${event.sequence}\\n`);\n  res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n}\n\n/**\n * GET /events - Global SSE stream.\n *\n * Optionally filter by domain: GET /events?domain=example.com\n * Without domain, streams ALL events across all sessions.\n * Useful for agents that need to track feedback across page navigations.\n */\nconst globalSseHandler: RouteHandler = async (req, res) => {\n  const url = new URL(req.url || \"/\", \"http://localhost\");\n  const domain = url.searchParams.get(\"domain\");\n  const isAgent = url.searchParams.get(\"agent\") === \"true\";\n\n  // Set up SSE headers\n  res.writeHead(200, {\n    \"Content-Type\": \"text/event-stream\",\n    \"Cache-Control\": \"no-cache\",\n    Connection: \"keep-alive\",\n    \"Access-Control-Allow-Origin\": \"*\",\n  });\n\n  // Track this connection\n  sseConnections.add(res);\n  if (isAgent) {\n    agentConnections.add(res);\n  }\n\n  // Send initial comment to establish connection\n  res.write(`: connected${domain ? ` to domain ${domain}` : \"\"}\\n\\n`);\n\n  // Send all pending annotations on connect (initial sync for agents)\n  if (isAgent) {\n    let syncCount = 0;\n    const sessions = listSessions();\n    for (const session of sessions) {\n      try {\n        // If domain is specified, filter by it; otherwise include all sessions\n        if (domain) {\n          const sessionHost = new URL(session.url).host;\n          if (sessionHost !== domain) continue;\n        }\n        const pending = getPendingAnnotations(session.id);\n        for (const annotation of pending) {\n          // Send as annotation.created events so agents see existing annotations\n          // Use sequence 0 for initial sync events (they're historical, not new)\n          sendSSEEvent(res, {\n            type: \"annotation.created\",\n            sessionId: session.id,\n            timestamp: annotation.createdAt || new Date().toISOString(),\n            sequence: 0,\n            payload: annotation,\n          });\n          syncCount++;\n        }\n      } catch {\n        // Invalid URL, skip\n      }\n    }\n    // Send a sync.complete event so agents know initial sync is done\n    res.write(`event: sync.complete\\ndata: ${JSON.stringify({ domain: domain ?? \"all\", count: syncCount, timestamp: new Date().toISOString() })}\\n\\n`);\n  }\n\n  // Subscribe to all events, optionally filter by domain\n  const unsubscribe = eventBus.subscribe((event: AFSEvent) => {\n    if (!domain) {\n      // No domain filter -- stream all events\n      sendSSEEvent(res, event);\n      return;\n    }\n    const session = getSession(event.sessionId);\n    if (session) {\n      try {\n        const sessionHost = new URL(session.url).host;\n        if (sessionHost === domain) {\n          sendSSEEvent(res, event);\n        }\n      } catch {\n        // Invalid URL, skip\n      }\n    }\n  });\n\n  // Keep connection alive with periodic comments\n  const keepAlive = setInterval(() => {\n    res.write(\": ping\\n\\n\");\n  }, 30000);\n\n  // Clean up on disconnect\n  req.on(\"close\", () => {\n    clearInterval(keepAlive);\n    unsubscribe();\n    sseConnections.delete(res);\n    agentConnections.delete(res);\n  });\n};\n\n/**\n * Handle MCP protocol requests at /mcp endpoint.\n * Supports POST (requests), GET (SSE stream), and DELETE (session cleanup).\n */\nasync function handleMcp(req: IncomingMessage, res: ServerResponse): Promise<void> {\n  const method = req.method || \"GET\";\n  const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n\n  // Add CORS headers to all responses\n  res.setHeader(\"Access-Control-Allow-Origin\", \"*\");\n  res.setHeader(\"Access-Control-Allow-Methods\", \"GET, POST, DELETE, OPTIONS\");\n  res.setHeader(\"Access-Control-Allow-Headers\", \"Content-Type, Accept, Mcp-Session-Id\");\n  res.setHeader(\"Access-Control-Expose-Headers\", \"Mcp-Session-Id\");\n\n  // POST: Handle JSON-RPC requests\n  if (method === \"POST\") {\n    let transport: StreamableHTTPServerTransport;\n\n    if (sessionId) {\n      // Session ID provided - must exist in our map\n      if (!mcpTransports.has(sessionId)) {\n        res.writeHead(404, { \"Content-Type\": \"application/json\" });\n        res.end(JSON.stringify({\n          jsonrpc: \"2.0\",\n          error: { code: -32000, message: \"Session not found. Please re-initialize.\" },\n          id: null\n        }));\n        return;\n      }\n      transport = mcpTransports.get(sessionId)!;\n    } else {\n      // No session ID - this should be an initialize request, create new session\n      const { transport: newTransport } = createMcpSession();\n      transport = newTransport;\n    }\n\n    try {\n      // Read the request body\n      const body = await new Promise<string>((resolve, reject) => {\n        let data = \"\";\n        req.on(\"data\", (chunk) => (data += chunk));\n        req.on(\"end\", () => resolve(data));\n        req.on(\"error\", reject);\n      });\n\n      const parsedBody = body ? JSON.parse(body) : undefined;\n\n      // Handle the request through the transport (it writes directly to res)\n      await transport.handleRequest(req, res, parsedBody);\n\n      // Store the transport with its session ID after the request is handled (for new sessions)\n      const newSessionId = transport.sessionId;\n      if (newSessionId && !mcpTransports.has(newSessionId)) {\n        mcpTransports.set(newSessionId, transport);\n        log(`[MCP HTTP] New session created: ${newSessionId}`);\n      }\n    } catch (err) {\n      console.error(\"[MCP HTTP] Error handling request:\", err);\n      if (!res.headersSent) {\n        res.writeHead(500, { \"Content-Type\": \"application/json\" });\n        res.end(JSON.stringify({ error: \"Internal server error\" }));\n      }\n    }\n    return;\n  }\n\n  // GET: SSE stream for notifications\n  if (method === \"GET\") {\n    if (!sessionId || !mcpTransports.has(sessionId)) {\n      res.writeHead(400, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify({ error: \"Missing or invalid Mcp-Session-Id\" }));\n      return;\n    }\n\n    const transport = mcpTransports.get(sessionId)!;\n\n    try {\n      // Handle the SSE request (transport writes directly to res)\n      await transport.handleRequest(req, res);\n    } catch (err) {\n      console.error(\"[MCP HTTP] Error handling SSE:\", err);\n      if (!res.headersSent) {\n        res.writeHead(500, { \"Content-Type\": \"application/json\" });\n        res.end(JSON.stringify({ error: \"Internal server error\" }));\n      }\n    }\n    return;\n  }\n\n  // DELETE: Session cleanup\n  if (method === \"DELETE\") {\n    if (sessionId && mcpTransports.has(sessionId)) {\n      const transport = mcpTransports.get(sessionId)!;\n      await transport.close();\n      mcpTransports.delete(sessionId);\n      res.writeHead(204);\n      res.end();\n    } else {\n      res.writeHead(404, { \"Content-Type\": \"application/json\" });\n      res.end(JSON.stringify({ error: \"Session not found\" }));\n    }\n    return;\n  }\n\n  // Method not allowed\n  res.writeHead(405, { \"Content-Type\": \"application/json\" });\n  res.end(JSON.stringify({ error: \"Method not allowed\" }));\n}\n\n// -----------------------------------------------------------------------------\n// Router\n// -----------------------------------------------------------------------------\n\ntype Route = {\n  method: string;\n  pattern: RegExp;\n  handler: RouteHandler;\n  paramNames: string[];\n};\n\nconst routes: Route[] = [\n  {\n    method: \"GET\",\n    pattern: /^\\/events$/,\n    handler: globalSseHandler,\n    paramNames: [],\n  },\n  {\n    method: \"GET\",\n    pattern: /^\\/pending$/,\n    handler: getAllPendingHandler,\n    paramNames: [],\n  },\n  {\n    method: \"GET\",\n    pattern: /^\\/sessions$/,\n    handler: listSessionsHandler,\n    paramNames: [],\n  },\n  {\n    method: \"POST\",\n    pattern: /^\\/sessions$/,\n    handler: createSessionHandler,\n    paramNames: [],\n  },\n  {\n    method: \"GET\",\n    pattern: /^\\/sessions\\/([^/]+)$/,\n    handler: getSessionHandler,\n    paramNames: [\"id\"],\n  },\n  {\n    method: \"GET\",\n    pattern: /^\\/sessions\\/([^/]+)\\/events$/,\n    handler: sseHandler,\n    paramNames: [\"id\"],\n  },\n  {\n    method: \"GET\",\n    pattern: /^\\/sessions\\/([^/]+)\\/pending$/,\n    handler: getPendingHandler,\n    paramNames: [\"id\"],\n  },\n  {\n    method: \"POST\",\n    pattern: /^\\/sessions\\/([^/]+)\\/action$/,\n    handler: requestActionHandler,\n    paramNames: [\"id\"],\n  },\n  {\n    method: \"POST\",\n    pattern: /^\\/sessions\\/([^/]+)\\/annotations$/,\n    handler: addAnnotationHandler,\n    paramNames: [\"id\"],\n  },\n  {\n    method: \"PATCH\",\n    pattern: /^\\/annotations\\/([^/]+)$/,\n    handler: updateAnnotationHandler,\n    paramNames: [\"id\"],\n  },\n  {\n    method: \"GET\",\n    pattern: /^\\/annotations\\/([^/]+)$/,\n    handler: getAnnotationHandler,\n    paramNames: [\"id\"],\n  },\n  {\n    method: \"DELETE\",\n    pattern: /^\\/annotations\\/([^/]+)$/,\n    handler: deleteAnnotationHandler,\n    paramNames: [\"id\"],\n  },\n  {\n    method: \"POST\",\n    pattern: /^\\/annotations\\/([^/]+)\\/thread$/,\n    handler: addThreadHandler,\n    paramNames: [\"id\"],\n  },\n];\n\n/**\n * Match a request to a route.\n */\nfunction matchRoute(\n  method: string,\n  pathname: string\n): { handler: RouteHandler; params: Record<string, string> } | null {\n  for (const route of routes) {\n    if (route.method !== method) continue;\n\n    const match = pathname.match(route.pattern);\n    if (match) {\n      const params: Record<string, string> = {};\n      route.paramNames.forEach((name, i) => {\n        params[name] = match[i + 1];\n      });\n      return { handler: route.handler, params };\n    }\n  }\n  return null;\n}\n\n// -----------------------------------------------------------------------------\n// Server\n// -----------------------------------------------------------------------------\n\n/**\n * Create and start the HTTP server.\n * @param port - Port to listen on\n * @param apiKey - Optional API key for cloud storage mode\n */\nexport function startHttpServer(port: number, apiKey?: string): void {\n  // Set cloud mode if API key provided\n  if (apiKey) {\n    setCloudApiKey(apiKey);\n  }\n\n  const server = createServer(async (req, res) => {\n    const url = new URL(req.url || \"/\", `http://localhost:${port}`);\n    const pathname = url.pathname;\n    const method = req.method || \"GET\";\n\n    // Log all requests for debugging\n    if (method !== \"OPTIONS\" && pathname !== \"/health\") {\n      log(`[HTTP] ${method} ${pathname}`);\n    }\n\n    // Handle CORS preflight\n    if (method === \"OPTIONS\") {\n      return handleCors(res);\n    }\n\n    // Health check (always local)\n    if (pathname === \"/health\" && method === \"GET\") {\n      return sendJson(res, 200, { status: \"ok\", mode: isCloudMode() ? \"cloud\" : \"local\" });\n    }\n\n    // Status endpoint (always local)\n    if (pathname === \"/status\" && method === \"GET\") {\n      const webhookUrls = getWebhookUrls();\n      return sendJson(res, 200, {\n        mode: isCloudMode() ? \"cloud\" : \"local\",\n        webhooksConfigured: webhookUrls.length > 0,\n        webhookCount: webhookUrls.length,\n        activeListeners: sseConnections.size,\n        agentListeners: agentConnections.size,\n      });\n    }\n\n    // MCP protocol endpoint (always local - allows Claude Code to connect)\n    if (pathname === \"/mcp\") {\n      return handleMcp(req, res);\n    }\n\n    // Cloud mode: proxy all other requests to cloud API\n    if (isCloudMode()) {\n      return proxyToCloud(req, res, pathname + url.search);\n    }\n\n    // Local mode: use local store\n    const match = matchRoute(method, pathname);\n    if (!match) {\n      return sendError(res, 404, \"Not found\");\n    }\n\n    try {\n      await match.handler(req, res, match.params);\n    } catch (err) {\n      console.error(\"Request error:\", err);\n      sendError(res, 500, \"Internal server error\");\n    }\n  });\n\n  server.on(\"error\", (err: NodeJS.ErrnoException) => {\n    if (err.code === \"EADDRINUSE\") {\n      log(`[HTTP] Port ${port} already in use — skipping HTTP server (MCP stdio still active)`);\n    } else {\n      log(`[HTTP] Server error: ${err.message}`);\n    }\n  });\n\n  server.listen(port, () => {\n    if (isCloudMode()) {\n      log(`[HTTP] Agentation server listening on http://localhost:${port} (cloud mode)`);\n    } else {\n      log(`[HTTP] Agentation server listening on http://localhost:${port}`);\n    }\n  });\n}\n","/**\n * MCP server for Agentation.\n * Exposes tools for AI agents to interact with annotations.\n *\n * This server fetches data from the HTTP API (single source of truth)\n * rather than maintaining its own store.\n */\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n  CallToolRequestSchema,\n  ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport type { ActionRequest } from \"../types.js\";\n\n// -----------------------------------------------------------------------------\n// Configuration\n// -----------------------------------------------------------------------------\n\nlet httpBaseUrl = \"http://localhost:4747\";\nlet apiKey: string | undefined;\n\n/**\n * Set the HTTP server URL that this MCP server will fetch from.\n */\nexport function setHttpBaseUrl(url: string): void {\n  httpBaseUrl = url;\n}\n\n/**\n * Set the API key for authenticating with the cloud backend.\n */\nexport function setApiKey(key: string): void {\n  apiKey = key;\n}\n\n// -----------------------------------------------------------------------------\n// HTTP Client\n// -----------------------------------------------------------------------------\n\nasync function httpGet<T>(path: string): Promise<T> {\n  const headers: Record<string, string> = {};\n  if (apiKey) {\n    headers[\"x-api-key\"] = apiKey;\n  }\n  const res = await fetch(`${httpBaseUrl}${path}`, { headers });\n  if (!res.ok) {\n    const body = await res.text();\n    throw new Error(`HTTP ${res.status}: ${body}`);\n  }\n  return res.json() as Promise<T>;\n}\n\nasync function httpPatch<T>(path: string, body: unknown): Promise<T> {\n  const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n  if (apiKey) {\n    headers[\"x-api-key\"] = apiKey;\n  }\n  const res = await fetch(`${httpBaseUrl}${path}`, {\n    method: \"PATCH\",\n    headers,\n    body: JSON.stringify(body),\n  });\n  if (!res.ok) {\n    const text = await res.text();\n    throw new Error(`HTTP ${res.status}: ${text}`);\n  }\n  return res.json() as Promise<T>;\n}\n\nasync function httpPost<T>(path: string, body: unknown): Promise<T> {\n  const headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n  if (apiKey) {\n    headers[\"x-api-key\"] = apiKey;\n  }\n  const res = await fetch(`${httpBaseUrl}${path}`, {\n    method: \"POST\",\n    headers,\n    body: JSON.stringify(body),\n  });\n  if (!res.ok) {\n    const text = await res.text();\n    throw new Error(`HTTP ${res.status}: ${text}`);\n  }\n  return res.json() as Promise<T>;\n}\n\n// -----------------------------------------------------------------------------\n// Tool Schemas\n// -----------------------------------------------------------------------------\n\nconst GetPendingSchema = z.object({\n  sessionId: z.string().describe(\"The session ID to get pending annotations for\"),\n});\n\nconst AcknowledgeSchema = z.object({\n  annotationId: z.string().describe(\"The annotation ID to acknowledge\"),\n});\n\nconst ResolveSchema = z.object({\n  annotationId: z.string().describe(\"The annotation ID to resolve\"),\n  summary: z.string().optional().describe(\"Optional summary of how it was resolved\"),\n});\n\nconst DismissSchema = z.object({\n  annotationId: z.string().describe(\"The annotation ID to dismiss\"),\n  reason: z.string().describe(\"Reason for dismissing this annotation\"),\n});\n\nconst ReplySchema = z.object({\n  annotationId: z.string().describe(\"The annotation ID to reply to\"),\n  message: z.string().describe(\"The reply message\"),\n});\n\nconst GetSessionSchema = z.object({\n  sessionId: z.string().describe(\"The session ID to get\"),\n});\n\nconst WatchAnnotationsSchema = z.object({\n  sessionId: z.string().optional().describe(\"Optional session ID to filter. If not provided, watches ALL sessions.\"),\n  batchWindowSeconds: z.number().optional().default(10).describe(\"Seconds to wait after first annotation before returning batch (default: 10, max: 60)\"),\n  timeoutSeconds: z.number().optional().default(120).describe(\"Max seconds to wait for first annotation (default: 120, max: 300)\"),\n});\n\n// -----------------------------------------------------------------------------\n// Tool Definitions\n// -----------------------------------------------------------------------------\n\nexport const TOOLS = [\n  {\n    name: \"agentation_list_sessions\",\n    description: \"List all active annotation sessions\",\n    inputSchema: {\n      type: \"object\" as const,\n      properties: {},\n      required: [],\n    },\n  },\n  {\n    name: \"agentation_get_session\",\n    description: \"Get a session with all its annotations\",\n    inputSchema: {\n      type: \"object\" as const,\n      properties: {\n        sessionId: {\n          type: \"string\",\n          description: \"The session ID to get\",\n        },\n      },\n      required: [\"sessionId\"],\n    },\n  },\n  {\n    name: \"agentation_get_pending\",\n    description:\n      \"Get all pending (unacknowledged) annotations for a session. Use this to see what feedback the human has given that needs attention.\",\n    inputSchema: {\n      type: \"object\" as const,\n      properties: {\n        sessionId: {\n          type: \"string\",\n          description: \"The session ID to get pending annotations for\",\n        },\n      },\n      required: [\"sessionId\"],\n    },\n  },\n  {\n    name: \"agentation_get_all_pending\",\n    description:\n      \"Get all pending annotations across ALL sessions. Use this to see all unaddressed feedback from the human across all pages they've visited.\",\n    inputSchema: {\n      type: \"object\" as const,\n      properties: {},\n      required: [],\n    },\n  },\n  {\n    name: \"agentation_acknowledge\",\n    description:\n      \"Mark an annotation as acknowledged. Use this to let the human know you've seen their feedback and will address it.\",\n    inputSchema: {\n      type: \"object\" as const,\n      properties: {\n        annotationId: {\n          type: \"string\",\n          description: \"The annotation ID to acknowledge\",\n        },\n      },\n      required: [\"annotationId\"],\n    },\n  },\n  {\n    name: \"agentation_resolve\",\n    description:\n      \"Mark an annotation as resolved. Use this after you've addressed the feedback. Optionally include a summary of what you did.\",\n    inputSchema: {\n      type: \"object\" as const,\n      properties: {\n        annotationId: {\n          type: \"string\",\n          description: \"The annotation ID to resolve\",\n        },\n        summary: {\n          type: \"string\",\n          description: \"Optional summary of how it was resolved\",\n        },\n      },\n      required: [\"annotationId\"],\n    },\n  },\n  {\n    name: \"agentation_dismiss\",\n    description:\n      \"Dismiss an annotation. Use this when you've decided not to address the feedback, with a reason why.\",\n    inputSchema: {\n      type: \"object\" as const,\n      properties: {\n        annotationId: {\n          type: \"string\",\n          description: \"The annotation ID to dismiss\",\n        },\n        reason: {\n          type: \"string\",\n          description: \"Reason for dismissing this annotation\",\n        },\n      },\n      required: [\"annotationId\", \"reason\"],\n    },\n  },\n  {\n    name: \"agentation_reply\",\n    description:\n      \"Add a reply to an annotation's thread. Use this to ask clarifying questions or provide updates to the human.\",\n    inputSchema: {\n      type: \"object\" as const,\n      properties: {\n        annotationId: {\n          type: \"string\",\n          description: \"The annotation ID to reply to\",\n        },\n        message: {\n          type: \"string\",\n          description: \"The reply message\",\n        },\n      },\n      required: [\"annotationId\", \"message\"],\n    },\n  },\n  {\n    name: \"agentation_watch_annotations\",\n    description:\n      \"Block until new annotations appear, then collect a batch and return them. \" +\n      \"Triggers automatically when annotations are created — the user just annotates in the browser \" +\n      \"and the agent picks them up. After detecting the first new annotation, waits for a batch window \" +\n      \"to collect more before returning. Use in a loop for hands-free processing. \" +\n      \"After addressing each annotation, call agentation_resolve with the annotation ID and a summary \" +\n      \"of what you did. Only resolve annotations the user accepted — if the user rejects your change, \" +\n      \"leave the annotation open.\",\n    inputSchema: {\n      type: \"object\" as const,\n      properties: {\n        sessionId: {\n          type: \"string\",\n          description: \"Optional session ID to filter. If not provided, watches ALL sessions.\",\n        },\n        batchWindowSeconds: {\n          type: \"number\",\n          description: \"Seconds to wait after first annotation before returning batch (default: 10, max: 60)\",\n        },\n        timeoutSeconds: {\n          type: \"number\",\n          description: \"Max seconds to wait for first annotation (default: 120, max: 300)\",\n        },\n      },\n      required: [],\n    },\n  },\n];\n\n// -----------------------------------------------------------------------------\n// Types\n// -----------------------------------------------------------------------------\n\ntype Session = {\n  id: string;\n  url: string;\n  status: string;\n  createdAt: string;\n};\n\ntype Annotation = {\n  id: string;\n  sessionId: string;\n  comment: string;\n  element: string;\n  elementPath: string;\n  url?: string;\n  intent?: string;\n  severity?: string;\n  timestamp?: number;\n  nearbyText?: string;\n  reactComponents?: string;\n  status: string;\n};\n\ntype SessionWithAnnotations = Session & {\n  annotations: Annotation[];\n};\n\ntype PendingResponse = {\n  count: number;\n  annotations: Annotation[];\n};\n\n// -----------------------------------------------------------------------------\n// Tool Handlers\n// -----------------------------------------------------------------------------\n\ntype ToolResult = {\n  content: Array<{ type: \"text\"; text: string }>;\n  isError?: boolean;\n};\n\nexport function success(data: unknown): ToolResult {\n  return {\n    content: [{ type: \"text\", text: JSON.stringify(data, null, 2) }],\n  };\n}\n\nexport function error(message: string): ToolResult {\n  return {\n    content: [{ type: \"text\", text: message }],\n    isError: true,\n  };\n}\n\n/**\n * Result from watchForAnnotations\n */\ntype WatchAnnotationsResult =\n  | { type: \"annotations\"; annotations: Annotation[]; sessions: string[] }\n  | { type: \"timeout\" }\n  | { type: \"error\"; message: string };\n\n/**\n * Watch for new annotation.created events via SSE from the HTTP server.\n * When the first annotation is detected, waits for a batch window to collect\n * additional annotations directly from SSE event payloads.\n *\n * Initial sync events (sequence 0) are ignored to prevent false triggers\n * from pre-existing pending annotations when the SSE connection opens.\n *\n * Watches for new annotations via SSE and collects them into a batch.\n */\nfunction watchForAnnotations(\n  sessionId: string | undefined,\n  batchWindowMs: number,\n  timeoutMs: number\n): Promise<WatchAnnotationsResult> {\n  return new Promise((resolve) => {\n    let aborted = false;\n    const controller = new AbortController();\n    let batchTimeout: ReturnType<typeof setTimeout> | null = null;\n    const detectedSessions = new Set<string>();\n    const collectedAnnotations: Annotation[] = [];\n\n    const cleanup = () => {\n      aborted = true;\n      controller.abort();\n      if (batchTimeout) clearTimeout(batchTimeout);\n    };\n\n    // Set overall timeout\n    const timeoutId = setTimeout(() => {\n      cleanup();\n      resolve({ type: \"timeout\" });\n    }, timeoutMs);\n\n    // Connect to SSE endpoint with agent=true to be counted as an agent listener\n    const sseUrl = sessionId\n      ? `${httpBaseUrl}/sessions/${sessionId}/events?agent=true`\n      : `${httpBaseUrl}/events?agent=true`;\n\n    const sseHeaders: Record<string, string> = { Accept: \"text/event-stream\" };\n    if (apiKey) {\n      sseHeaders[\"x-api-key\"] = apiKey;\n    }\n\n    fetch(sseUrl, {\n      signal: controller.signal,\n      headers: sseHeaders,\n    })\n      .then(async (res) => {\n        if (!res.ok) {\n          clearTimeout(timeoutId);\n          cleanup();\n          resolve({ type: \"error\", message: `HTTP server returned ${res.status}: ${res.statusText}` });\n          return;\n        }\n        if (!res.body) {\n          clearTimeout(timeoutId);\n          cleanup();\n          resolve({ type: \"error\", message: \"No response body from SSE endpoint\" });\n          return;\n        }\n\n        const reader = res.body.getReader();\n        const decoder = new TextDecoder();\n        let buffer = \"\";\n\n        while (!aborted) {\n          const { done, value } = await reader.read();\n          if (done) {\n            if (!aborted) {\n              clearTimeout(timeoutId);\n              cleanup();\n              if (collectedAnnotations.length > 0) {\n                resolve({\n                  type: \"annotations\",\n                  annotations: collectedAnnotations,\n                  sessions: Array.from(detectedSessions),\n                });\n              } else {\n                resolve({ type: \"error\", message: \"SSE connection closed unexpectedly. The agentation server may have restarted.\" });\n              }\n            }\n            return;\n          }\n\n          buffer += decoder.decode(value, { stream: true });\n          const lines = buffer.split(\"\\n\");\n          buffer = lines.pop() || \"\";\n\n          for (const line of lines) {\n            if (line.startsWith(\"data: \")) {\n              try {\n                const event = JSON.parse(line.slice(6));\n                if (event.type === \"annotation.created\") {\n                  // Skip initial sync events (sequence 0) — historical replay, not new\n                  if (event.sequence === 0) continue;\n\n                  // If filtering by session, check it matches\n                  if (sessionId && event.sessionId !== sessionId) continue;\n\n                  detectedSessions.add(event.sessionId);\n                  collectedAnnotations.push(event.payload as Annotation);\n\n                  // First annotation detected — start batch window\n                  if (!batchTimeout) {\n                    batchTimeout = setTimeout(() => {\n                      clearTimeout(timeoutId);\n                      cleanup();\n                      resolve({\n                        type: \"annotations\",\n                        annotations: collectedAnnotations,\n                        sessions: Array.from(detectedSessions),\n                      });\n                    }, batchWindowMs);\n                  }\n                }\n              } catch {\n                // Ignore parse errors for individual events\n              }\n            }\n          }\n        }\n      })\n      .catch((err) => {\n        // Connection error or aborted\n        if (!aborted) {\n          clearTimeout(timeoutId);\n          const message = err instanceof Error ? err.message : \"Unknown connection error\";\n          // Check for common connection errors\n          if (message.includes(\"ECONNREFUSED\") || message.includes(\"fetch failed\")) {\n            resolve({ type: \"error\", message: `Cannot connect to HTTP server at ${httpBaseUrl}. Is the agentation server running?` });\n          } else if (message.includes(\"abort\")) {\n            // Aborted by timeout - already handled\n            resolve({ type: \"timeout\" });\n          } else {\n            resolve({ type: \"error\", message: `Connection error: ${message}` });\n          }\n        }\n      });\n  });\n}\n\nexport async function handleTool(name: string, args: unknown): Promise<ToolResult> {\n  switch (name) {\n    case \"agentation_list_sessions\": {\n      const sessions = await httpGet<Session[]>(\"/sessions\");\n      return success({\n        sessions: sessions.map((s) => ({\n          id: s.id,\n          url: s.url,\n          status: s.status,\n          createdAt: s.createdAt,\n        })),\n      });\n    }\n\n    case \"agentation_get_session\": {\n      const { sessionId } = GetSessionSchema.parse(args);\n      try {\n        const session = await httpGet<SessionWithAnnotations>(`/sessions/${sessionId}`);\n        return success(session);\n      } catch (err) {\n        if ((err as Error).message.includes(\"404\")) {\n          return error(`Session not found: ${sessionId}`);\n        }\n        throw err;\n      }\n    }\n\n    case \"agentation_get_pending\": {\n      const { sessionId } = GetPendingSchema.parse(args);\n      const response = await httpGet<PendingResponse>(`/sessions/${sessionId}/pending`);\n      return success({\n        count: response.count,\n        annotations: response.annotations.map((a) => ({\n          id: a.id,\n          comment: a.comment,\n          element: a.element,\n          elementPath: a.elementPath,\n          url: a.url,\n          intent: a.intent,\n          severity: a.severity,\n          timestamp: a.timestamp,\n          nearbyText: a.nearbyText,\n          reactComponents: a.reactComponents,\n        })),\n      });\n    }\n\n    case \"agentation_get_all_pending\": {\n      const response = await httpGet<PendingResponse>(\"/pending\");\n      return success({\n        count: response.count,\n        annotations: response.annotations.map((a) => ({\n          id: a.id,\n          comment: a.comment,\n          element: a.element,\n          elementPath: a.elementPath,\n          url: a.url,\n          intent: a.intent,\n          severity: a.severity,\n          timestamp: a.timestamp,\n          nearbyText: a.nearbyText,\n          reactComponents: a.reactComponents,\n        })),\n      });\n    }\n\n    case \"agentation_acknowledge\": {\n      const { annotationId } = AcknowledgeSchema.parse(args);\n      try {\n        await httpPatch(`/annotations/${annotationId}`, { status: \"acknowledged\" });\n        return success({ acknowledged: true, annotationId });\n      } catch (err) {\n        if ((err as Error).message.includes(\"404\")) {\n          return error(`Annotation not found: ${annotationId}`);\n        }\n        throw err;\n      }\n    }\n\n    case \"agentation_resolve\": {\n      const { annotationId, summary } = ResolveSchema.parse(args);\n      try {\n        await httpPatch(`/annotations/${annotationId}`, {\n          status: \"resolved\",\n          resolvedBy: \"agent\",\n        });\n        if (summary) {\n          await httpPost(`/annotations/${annotationId}/thread`, {\n            role: \"agent\",\n            content: `Resolved: ${summary}`,\n          });\n        }\n        return success({ resolved: true, annotationId, summary });\n      } catch (err) {\n        if ((err as Error).message.includes(\"404\")) {\n          return error(`Annotation not found: ${annotationId}`);\n        }\n        throw err;\n      }\n    }\n\n    case \"agentation_dismiss\": {\n      const { annotationId, reason } = DismissSchema.parse(args);\n      try {\n        await httpPatch(`/annotations/${annotationId}`, {\n          status: \"dismissed\",\n          resolvedBy: \"agent\",\n        });\n        await httpPost(`/annotations/${annotationId}/thread`, {\n          role: \"agent\",\n          content: `Dismissed: ${reason}`,\n        });\n        return success({ dismissed: true, annotationId, reason });\n      } catch (err) {\n        if ((err as Error).message.includes(\"404\")) {\n          return error(`Annotation not found: ${annotationId}`);\n        }\n        throw err;\n      }\n    }\n\n    case \"agentation_reply\": {\n      const { annotationId, message } = ReplySchema.parse(args);\n      try {\n        await httpPost(`/annotations/${annotationId}/thread`, {\n          role: \"agent\",\n          content: message,\n        });\n        return success({ replied: true, annotationId, message });\n      } catch (err) {\n        if ((err as Error).message.includes(\"404\")) {\n          return error(`Annotation not found: ${annotationId}`);\n        }\n        throw err;\n      }\n    }\n\n    case \"agentation_watch_annotations\": {\n      const parsed = WatchAnnotationsSchema.parse(args);\n      const sessionId = parsed.sessionId;\n      const batchWindowSeconds = Math.min(60, Math.max(1, parsed.batchWindowSeconds ?? 10));\n      const timeoutSeconds = Math.min(300, Math.max(1, parsed.timeoutSeconds ?? 120));\n\n      // Drain: return any pending annotations immediately before blocking on SSE.\n      // This catches annotations that arrived while the caller was busy processing\n      // the previous batch (when watch_annotations wasn't running).\n      try {\n        const pendingPath = sessionId ? `/sessions/${sessionId}/pending` : \"/pending\";\n        const pending = await httpGet<PendingResponse>(pendingPath);\n        if (pending.count > 0) {\n          const sessions = [...new Set(pending.annotations.map((a) => a.sessionId))];\n          return success({\n            timeout: false,\n            count: pending.count,\n            sessions,\n            annotations: pending.annotations.map((a) => ({\n              id: a.id,\n              comment: a.comment,\n              element: a.element,\n              elementPath: a.elementPath,\n              url: a.url,\n              intent: a.intent,\n              severity: a.severity,\n              timestamp: a.timestamp,\n              nearbyText: a.nearbyText,\n              reactComponents: a.reactComponents,\n            })),\n          });\n        }\n      } catch (err) {\n        console.error(\"[MCP] Pending drain failed, falling through to SSE watch:\", err);\n      }\n\n      const result = await watchForAnnotations(\n        sessionId,\n        batchWindowSeconds * 1000,\n        timeoutSeconds * 1000\n      );\n\n      switch (result.type) {\n        case \"annotations\":\n          return success({\n            timeout: false,\n            count: result.annotations.length,\n            sessions: result.sessions,\n            annotations: result.annotations.map((a) => ({\n              id: a.id,\n              comment: a.comment,\n              element: a.element,\n              elementPath: a.elementPath,\n              url: a.url,\n              intent: a.intent,\n              severity: a.severity,\n              timestamp: a.timestamp,\n              nearbyText: a.nearbyText,\n              reactComponents: a.reactComponents,\n            })),\n          });\n        case \"timeout\":\n          return success({\n            timeout: true,\n            message: `No new annotations within ${timeoutSeconds} seconds`,\n          });\n        case \"error\":\n          return error(result.message);\n      }\n    }\n\n    default:\n      return error(`Unknown tool: ${name}`);\n  }\n}\n\n// -----------------------------------------------------------------------------\n// Server\n// -----------------------------------------------------------------------------\n\n/**\n * Create and start the MCP server on stdio.\n * @param baseUrl - Optional HTTP server URL to fetch from (default: http://localhost:4747)\n */\nexport async function startMcpServer(baseUrl?: string): Promise<void> {\n  if (baseUrl) {\n    setHttpBaseUrl(baseUrl);\n  }\n\n  const server = new Server(\n    {\n      name: \"agentation\",\n      version: \"0.0.1\",\n    },\n    {\n      capabilities: {\n        tools: {},\n      },\n    }\n  );\n\n  // List available tools\n  server.setRequestHandler(ListToolsRequestSchema, async () => {\n    return { tools: TOOLS };\n  });\n\n  // Handle tool calls\n  server.setRequestHandler(CallToolRequestSchema, async (request) => {\n    const { name, arguments: args } = request.params;\n    try {\n      return await handleTool(name, args);\n    } catch (err) {\n      const message = err instanceof Error ? err.message : \"Unknown error\";\n      return error(message);\n    }\n  });\n\n  // Connect via stdio\n  const transport = new StdioServerTransport();\n  await server.connect(transport);\n\n  // Log startup message with connection details\n  const isRemote = httpBaseUrl.startsWith(\"https://\") || (!httpBaseUrl.includes(\"localhost\") && !httpBaseUrl.includes(\"127.0.0.1\"));\n  if (isRemote && apiKey) {\n    console.error(`[MCP] Agentation MCP server started on stdio (Remote: ${httpBaseUrl}, API key: configured)`);\n  } else if (isRemote) {\n    console.error(`[MCP] Agentation MCP server started on stdio (Remote: ${httpBaseUrl}, API key: not configured)`);\n  } else {\n    console.error(`[MCP] Agentation MCP server started on stdio (HTTP: ${httpBaseUrl})`);\n  }\n}\n","/**\n * Store module - provides persistence for sessions and annotations.\n *\n * By default uses SQLite (~/.agentation/store.db).\n * Falls back to in-memory storage if SQLite fails to initialize.\n *\n * Usage:\n *   import { store } from './store.js';\n *   const session = store.createSession('http://localhost:3000');\n */\n\nimport type {\n  AFSStore,\n  AFSEvent,\n  Session,\n  SessionStatus,\n  SessionWithAnnotations,\n  Annotation,\n  AnnotationStatus,\n  ThreadMessage,\n} from \"../types.js\";\nimport { eventBus } from \"./events.js\";\n\n// -----------------------------------------------------------------------------\n// Store Singleton\n// -----------------------------------------------------------------------------\n\nlet _store: AFSStore | null = null;\n\n/**\n * Get the store instance. Lazily initializes on first access.\n */\nexport function getStore(): AFSStore {\n  if (!_store) {\n    _store = initializeStore();\n  }\n  return _store;\n}\n\n/**\n * Initialize the store. Tries SQLite first, falls back to in-memory.\n */\nfunction initializeStore(): AFSStore {\n  // Check if we should use in-memory only\n  if (process.env.AGENTATION_STORE === \"memory\") {\n    process.stderr.write(\"[Store] Using in-memory store (AGENTATION_STORE=memory)\\n\");\n    return createMemoryStore();\n  }\n\n  try {\n    // Dynamic import to avoid issues if better-sqlite3 isn't available\n    // eslint-disable-next-line @typescript-eslint/no-require-imports\n    const { createSQLiteStore } = require(\"./sqlite.js\");\n    const store = createSQLiteStore();\n    process.stderr.write(\"[Store] Using SQLite store (~/.agentation/store.db)\\n\");\n    return store;\n  } catch (err) {\n    console.warn(\"[Store] SQLite unavailable, falling back to in-memory:\", (err as Error).message);\n    return createMemoryStore();\n  }\n}\n\n// -----------------------------------------------------------------------------\n// In-Memory Store (fallback)\n// -----------------------------------------------------------------------------\n\nfunction createMemoryStore(): AFSStore {\n  const sessions = new Map<string, Session>();\n  const annotations = new Map<string, Annotation>();\n  const events: AFSEvent[] = [];\n\n  function generateId(): string {\n    return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;\n  }\n\n  return {\n    createSession(url: string, projectId?: string): Session {\n      const session: Session = {\n        id: generateId(),\n        url,\n        status: \"active\",\n        createdAt: new Date().toISOString(),\n        projectId,\n      };\n      sessions.set(session.id, session);\n\n      const event = eventBus.emit(\"session.created\", session.id, session);\n      events.push(event);\n\n      return session;\n    },\n\n    getSession(id: string): Session | undefined {\n      return sessions.get(id);\n    },\n\n    getSessionWithAnnotations(id: string): SessionWithAnnotations | undefined {\n      const session = sessions.get(id);\n      if (!session) return undefined;\n\n      const sessionAnnotations = Array.from(annotations.values()).filter(\n        (a) => a.sessionId === id\n      );\n\n      return {\n        ...session,\n        annotations: sessionAnnotations,\n      };\n    },\n\n    updateSessionStatus(id: string, status: SessionStatus): Session | undefined {\n      const session = sessions.get(id);\n      if (!session) return undefined;\n\n      session.status = status;\n      session.updatedAt = new Date().toISOString();\n\n      const eventType = status === \"closed\" ? \"session.closed\" : \"session.updated\";\n      const event = eventBus.emit(eventType, id, session);\n      events.push(event);\n\n      return session;\n    },\n\n    listSessions(): Session[] {\n      return Array.from(sessions.values());\n    },\n\n    addAnnotation(\n      sessionId: string,\n      data: Omit<Annotation, \"id\" | \"sessionId\" | \"status\" | \"createdAt\">\n    ): Annotation | undefined {\n      const session = sessions.get(sessionId);\n      if (!session) return undefined;\n\n      const annotation: Annotation = {\n        ...data,\n        id: generateId(),\n        sessionId,\n        status: \"pending\",\n        createdAt: new Date().toISOString(),\n      };\n\n      annotations.set(annotation.id, annotation);\n\n      const event = eventBus.emit(\"annotation.created\", sessionId, annotation);\n      events.push(event);\n\n      return annotation;\n    },\n\n    getAnnotation(id: string): Annotation | undefined {\n      return annotations.get(id);\n    },\n\n    updateAnnotation(\n      id: string,\n      data: Partial<Omit<Annotation, \"id\" | \"sessionId\" | \"createdAt\">>\n    ): Annotation | undefined {\n      const annotation = annotations.get(id);\n      if (!annotation) return undefined;\n\n      Object.assign(annotation, data, { updatedAt: new Date().toISOString() });\n\n      if (annotation.sessionId) {\n        const event = eventBus.emit(\"annotation.updated\", annotation.sessionId, annotation);\n        events.push(event);\n      }\n\n      return annotation;\n    },\n\n    updateAnnotationStatus(\n      id: string,\n      status: AnnotationStatus,\n      resolvedBy?: \"human\" | \"agent\"\n    ): Annotation | undefined {\n      const annotation = annotations.get(id);\n      if (!annotation) return undefined;\n\n      annotation.status = status;\n      annotation.updatedAt = new Date().toISOString();\n\n      if (status === \"resolved\" || status === \"dismissed\") {\n        annotation.resolvedAt = new Date().toISOString();\n        annotation.resolvedBy = resolvedBy || \"agent\";\n      }\n\n      if (annotation.sessionId) {\n        const event = eventBus.emit(\"annotation.updated\", annotation.sessionId, annotation);\n        events.push(event);\n      }\n\n      return annotation;\n    },\n\n    addThreadMessage(\n      annotationId: string,\n      role: \"human\" | \"agent\",\n      content: string\n    ): Annotation | undefined {\n      const annotation = annotations.get(annotationId);\n      if (!annotation) return undefined;\n\n      const message: ThreadMessage = {\n        id: generateId(),\n        role,\n        content,\n        timestamp: Date.now(),\n      };\n\n      if (!annotation.thread) {\n        annotation.thread = [];\n      }\n      annotation.thread.push(message);\n      annotation.updatedAt = new Date().toISOString();\n\n      if (annotation.sessionId) {\n        const event = eventBus.emit(\"thread.message\", annotation.sessionId, message);\n        events.push(event);\n      }\n\n      return annotation;\n    },\n\n    getPendingAnnotations(sessionId: string): Annotation[] {\n      return Array.from(annotations.values()).filter(\n        (a) => a.sessionId === sessionId && a.status === \"pending\"\n      );\n    },\n\n    getSessionAnnotations(sessionId: string): Annotation[] {\n      return Array.from(annotations.values()).filter(\n        (a) => a.sessionId === sessionId\n      );\n    },\n\n    deleteAnnotation(id: string): Annotation | undefined {\n      const annotation = annotations.get(id);\n      if (!annotation) return undefined;\n\n      annotations.delete(id);\n\n      if (annotation.sessionId) {\n        const event = eventBus.emit(\"annotation.deleted\", annotation.sessionId, annotation);\n        events.push(event);\n      }\n\n      return annotation;\n    },\n\n    getEventsSince(sessionId: string, sequence: number): AFSEvent[] {\n      return events.filter(\n        (e) => e.sessionId === sessionId && e.sequence > sequence\n      );\n    },\n\n    close(): void {\n      sessions.clear();\n      annotations.clear();\n      events.length = 0;\n    },\n  };\n}\n\n// -----------------------------------------------------------------------------\n// Convenience Exports (delegate to singleton)\n// -----------------------------------------------------------------------------\n\nexport const store = {\n  get instance() {\n    return getStore();\n  },\n};\n\n// Direct function exports for backwards compatibility\nexport function createSession(url: string, projectId?: string): Session {\n  return getStore().createSession(url, projectId);\n}\n\nexport function getSession(id: string): Session | undefined {\n  return getStore().getSession(id);\n}\n\nexport function getSessionWithAnnotations(id: string): SessionWithAnnotations | undefined {\n  return getStore().getSessionWithAnnotations(id);\n}\n\nexport function updateSessionStatus(id: string, status: SessionStatus): Session | undefined {\n  return getStore().updateSessionStatus(id, status);\n}\n\nexport function listSessions(): Session[] {\n  return getStore().listSessions();\n}\n\nexport function addAnnotation(\n  sessionId: string,\n  data: Omit<Annotation, \"id\" | \"sessionId\" | \"status\" | \"createdAt\">\n): Annotation | undefined {\n  return getStore().addAnnotation(sessionId, data);\n}\n\nexport function getAnnotation(id: string): Annotation | undefined {\n  return getStore().getAnnotation(id);\n}\n\nexport function updateAnnotation(\n  id: string,\n  data: Partial<Omit<Annotation, \"id\" | \"sessionId\" | \"createdAt\">>\n): Annotation | undefined {\n  return getStore().updateAnnotation(id, data);\n}\n\nexport function updateAnnotationStatus(\n  id: string,\n  status: AnnotationStatus,\n  resolvedBy?: \"human\" | \"agent\"\n): Annotation | undefined {\n  return getStore().updateAnnotationStatus(id, status, resolvedBy);\n}\n\nexport function addThreadMessage(\n  annotationId: string,\n  role: \"human\" | \"agent\",\n  content: string\n): Annotation | undefined {\n  return getStore().addThreadMessage(annotationId, role, content);\n}\n\nexport function getPendingAnnotations(sessionId: string): Annotation[] {\n  return getStore().getPendingAnnotations(sessionId);\n}\n\nexport function getSessionAnnotations(sessionId: string): Annotation[] {\n  return getStore().getSessionAnnotations(sessionId);\n}\n\nexport function deleteAnnotation(id: string): Annotation | undefined {\n  return getStore().deleteAnnotation(id);\n}\n\nexport function getEventsSince(sessionId: string, sequence: number): AFSEvent[] {\n  return getStore().getEventsSince(sessionId, sequence);\n}\n\n/**\n * Clear all data and reset the store.\n */\nexport function clearAll(): void {\n  getStore().close();\n  _store = null;\n}\n","/**\n * Agentation MCP Server\n *\n * This package provides an MCP server for AI coding agents to interact\n * with web page annotations from the Agentation toolbar.\n */\n\n// Re-export server functions\nexport { startHttpServer, startMcpServer } from \"./server/index.js\";\n\n// Re-export store functions\nexport {\n  getStore,\n  store,\n  createSession,\n  getSession,\n  getSessionWithAnnotations,\n  updateSessionStatus,\n  listSessions,\n  addAnnotation,\n  getAnnotation,\n  updateAnnotation,\n  updateAnnotationStatus,\n  addThreadMessage,\n  getPendingAnnotations,\n  getSessionAnnotations,\n  deleteAnnotation,\n  getEventsSince,\n  clearAll,\n} from \"./server/store.js\";\n\n// Re-export event bus\nexport { eventBus, userEventBus } from \"./server/events.js\";\n\n// Re-export tenant store\nexport {\n  getTenantStore,\n  resetTenantStore,\n  hashApiKey,\n  isValidApiKeyFormat,\n  createUserContext,\n  createOrganization,\n  getOrganization,\n  createUser,\n  getUser,\n  getUserByEmail,\n  getUsersByOrg,\n  createApiKey,\n  getApiKeyByHash,\n  listApiKeys,\n  deleteApiKey,\n  updateApiKeyLastUsed,\n  createSessionForUser,\n  listSessionsForUser,\n  getSessionForUser,\n  getSessionWithAnnotationsForUser,\n  getPendingAnnotationsForUser,\n  getAllPendingForUser,\n} from \"./server/tenant-store.js\";\nexport type { TenantStore } from \"./server/tenant-store.js\";\n\n// Re-export types\nexport type {\n  Annotation,\n  AnnotationIntent,\n  AnnotationSeverity,\n  AnnotationStatus,\n  Session,\n  SessionStatus,\n  SessionWithAnnotations,\n  ThreadMessage,\n  AFSEventType,\n  ActionRequest,\n  AFSEvent,\n  AFSStore,\n  // Multi-tenant types\n  Organization,\n  User,\n  UserRole,\n  ApiKey,\n  UserContext,\n} from \"./types.js\";\n","/**\n * Tenant Store - Multi-tenant wrapper for the base store.\n *\n * Provides user-scoped access to sessions and annotations,\n * plus management of organizations, users, and API keys.\n *\n * Usage:\n *   import { getTenantStore, hashApiKey } from './tenant-store.js';\n *   const store = getTenantStore();\n *   const user = store.getUser(userId);\n */\n\nimport { createHash } from \"crypto\";\nimport type {\n  Organization,\n  User,\n  UserRole,\n  ApiKey,\n  UserContext,\n  Session,\n  SessionWithAnnotations,\n  Annotation,\n} from \"../types.js\";\n\n// Re-export TenantStore type\nexport type { TenantStore } from \"./sqlite.js\";\n\n// -----------------------------------------------------------------------------\n// Store Singleton\n// -----------------------------------------------------------------------------\n\nlet _tenantStore: import(\"./sqlite.js\").TenantStore | null = null;\n\n/**\n * Get the tenant store instance. Lazily initializes on first access.\n */\nexport function getTenantStore(): import(\"./sqlite.js\").TenantStore {\n  if (!_tenantStore) {\n    _tenantStore = initializeTenantStore();\n  }\n  return _tenantStore;\n}\n\n/**\n * Initialize the tenant store.\n */\nfunction initializeTenantStore(): import(\"./sqlite.js\").TenantStore {\n  try {\n    // Dynamic import to avoid issues if better-sqlite3 isn't available\n    // eslint-disable-next-line @typescript-eslint/no-require-imports\n    const { createTenantStore } = require(\"./sqlite.js\");\n    const store = createTenantStore();\n    process.stderr.write(\"[TenantStore] Initialized tenant store\\n\");\n    return store;\n  } catch (err) {\n    console.error(\"[TenantStore] Failed to initialize:\", (err as Error).message);\n    throw err;\n  }\n}\n\n/**\n * Reset the tenant store singleton (for testing).\n */\nexport function resetTenantStore(): void {\n  if (_tenantStore) {\n    _tenantStore.close();\n    _tenantStore = null;\n  }\n}\n\n// -----------------------------------------------------------------------------\n// API Key Utilities\n// -----------------------------------------------------------------------------\n\n/**\n * Hash an API key for lookup.\n * Used by auth middleware to find the key in the database.\n */\nexport function hashApiKey(rawKey: string): string {\n  return createHash(\"sha256\").update(rawKey).digest(\"hex\");\n}\n\n/**\n * Validate API key format.\n */\nexport function isValidApiKeyFormat(key: string): boolean {\n  return key.startsWith(\"sk_live_\") && key.length > 20;\n}\n\n// -----------------------------------------------------------------------------\n// User Context Utilities\n// -----------------------------------------------------------------------------\n\n/**\n * Create a UserContext from a User and Organization.\n */\nexport function createUserContext(user: User): UserContext {\n  return {\n    userId: user.id,\n    orgId: user.orgId,\n    email: user.email,\n    role: user.role,\n  };\n}\n\n// -----------------------------------------------------------------------------\n// Convenience Exports (delegate to singleton)\n// -----------------------------------------------------------------------------\n\n// Organizations\nexport function createOrganization(name: string): Organization {\n  return getTenantStore().createOrganization(name);\n}\n\nexport function getOrganization(id: string): Organization | undefined {\n  return getTenantStore().getOrganization(id);\n}\n\n// Users\nexport function createUser(email: string, orgId: string, role?: UserRole): User {\n  return getTenantStore().createUser(email, orgId, role);\n}\n\nexport function getUser(id: string): User | undefined {\n  return getTenantStore().getUser(id);\n}\n\nexport function getUserByEmail(email: string): User | undefined {\n  return getTenantStore().getUserByEmail(email);\n}\n\nexport function getUsersByOrg(orgId: string): User[] {\n  return getTenantStore().getUsersByOrg(orgId);\n}\n\n// API Keys\nexport function createApiKey(\n  userId: string,\n  name: string,\n  expiresAt?: string\n): { apiKey: ApiKey; rawKey: string } {\n  return getTenantStore().createApiKey(userId, name, expiresAt);\n}\n\nexport function getApiKeyByHash(hash: string): ApiKey | undefined {\n  return getTenantStore().getApiKeyByHash(hash);\n}\n\nexport function listApiKeys(userId: string): ApiKey[] {\n  return getTenantStore().listApiKeys(userId);\n}\n\nexport function deleteApiKey(id: string): boolean {\n  return getTenantStore().deleteApiKey(id);\n}\n\nexport function updateApiKeyLastUsed(id: string): void {\n  return getTenantStore().updateApiKeyLastUsed(id);\n}\n\n// User-scoped sessions\nexport function createSessionForUser(\n  userId: string,\n  url: string,\n  projectId?: string\n): Session {\n  return getTenantStore().createSessionForUser(userId, url, projectId);\n}\n\nexport function listSessionsForUser(userId: string): Session[] {\n  return getTenantStore().listSessionsForUser(userId);\n}\n\nexport function getSessionForUser(\n  userId: string,\n  sessionId: string\n): Session | undefined {\n  return getTenantStore().getSessionForUser(userId, sessionId);\n}\n\nexport function getSessionWithAnnotationsForUser(\n  userId: string,\n  sessionId: string\n): SessionWithAnnotations | undefined {\n  return getTenantStore().getSessionWithAnnotationsForUser(userId, sessionId);\n}\n\n// User-scoped annotations\nexport function getPendingAnnotationsForUser(\n  userId: string,\n  sessionId: string\n): Annotation[] {\n  return getTenantStore().getPendingAnnotationsForUser(userId, sessionId);\n}\n\nexport function getAllPendingForUser(userId: string): Annotation[] {\n  return getTenantStore().getAllPendingForUser(userId);\n}\n"],"mappings":"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","names":["userSessions","apiKey","Server","CallToolRequestSchema","ListToolsRequestSchema","createSQLiteStore","store","generateId","Server","ListToolsRequestSchema","CallToolRequestSchema","apiKey","createHash","createTenantStore","store"]}