agentation-vue-mcp 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +27 -0
- package/README.md +171 -0
- package/dist/cli.js +2952 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.mts +341 -0
- package/dist/index.d.ts +341 -0
- package/dist/index.js +2817 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2761 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +60 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"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 SessionWithAnnotationsV2,\n Annotation,\n AnnotationV2,\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 annotations_v2 (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL,\n schema_version INTEGER NOT NULL DEFAULT 1,\n timestamp TEXT NOT NULL,\n url TEXT NOT NULL,\n element_selector TEXT NOT NULL,\n element_text TEXT,\n comment TEXT NOT NULL,\n source TEXT NOT NULL,\n metadata TEXT,\n created_at TEXT NOT NULL,\n updated_at 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_annotations_v2_session ON annotations_v2(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\nfunction rowToAnnotationV2(row: Record<string, unknown>): AnnotationV2 {\n return {\n id: row.id as string,\n schemaVersion: row.schema_version as 1,\n timestamp: row.timestamp as string,\n url: row.url as string,\n elementSelector: row.element_selector as string,\n elementText: row.element_text as string | undefined,\n comment: row.comment as string,\n source: JSON.parse(row.source as string),\n metadata: row.metadata ? JSON.parse(row.metadata as string) : undefined,\n sessionId: row.session_id as string,\n createdAt: row.created_at as string | undefined,\n updatedAt: row.updated_at 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 // Annotations V2\n insertAnnotationV2: db.prepare(`\n INSERT INTO annotations_v2 (\n id, session_id, schema_version, timestamp, url, element_selector,\n element_text, comment, source, metadata, created_at, updated_at\n ) VALUES (\n @id, @sessionId, @schemaVersion, @timestamp, @url, @elementSelector,\n @elementText, @comment, @source, @metadata, @createdAt, @updatedAt\n )\n `),\n getAnnotationV2: db.prepare(\"SELECT * FROM annotations_v2 WHERE id = ?\"),\n getAnnotationsV2BySession: db.prepare(\n \"SELECT * FROM annotations_v2 WHERE session_id = ? ORDER BY created_at\"\n ),\n updateAnnotationV2: db.prepare(`\n UPDATE annotations_v2 SET\n element_text = COALESCE(@elementText, element_text),\n comment = COALESCE(@comment, comment),\n source = COALESCE(@source, source),\n metadata = COALESCE(@metadata, metadata),\n updated_at = @updatedAt\n WHERE id = @id\n `),\n deleteAnnotationV2: db.prepare(\"DELETE FROM annotations_v2 WHERE id = ?\"),\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 // -- Annotations V2 (Vue schema) ------------------------------------------\n\n getSessionWithAnnotationsV2(id: string): SessionWithAnnotationsV2 | undefined {\n const sessionRow = stmts.getSession.get(id) as Record<string, unknown> | undefined;\n if (!sessionRow) return undefined;\n\n const annotationRows = stmts.getAnnotationsV2BySession.all(id) as Record<string, unknown>[];\n\n return {\n ...rowToSession(sessionRow),\n annotations: annotationRows.map(rowToAnnotationV2),\n };\n },\n\n addAnnotationV2(sessionId: string, data: AnnotationV2): AnnotationV2 | undefined {\n const session = this.getSession(sessionId);\n if (!session) return undefined;\n\n // Idempotent: return existing if same ID\n const existing = this.getAnnotationV2(data.id);\n if (existing) return existing;\n\n const annotation: AnnotationV2 = {\n ...data,\n sessionId,\n createdAt: new Date().toISOString(),\n };\n\n stmts.insertAnnotationV2.run({\n id: annotation.id,\n sessionId: annotation.sessionId,\n schemaVersion: annotation.schemaVersion,\n timestamp: annotation.timestamp,\n url: annotation.url,\n elementSelector: annotation.elementSelector,\n elementText: annotation.elementText ?? null,\n comment: annotation.comment,\n source: JSON.stringify(annotation.source),\n metadata: annotation.metadata ? JSON.stringify(annotation.metadata) : null,\n createdAt: annotation.createdAt,\n updatedAt: null,\n });\n\n return annotation;\n },\n\n getAnnotationV2(id: string): AnnotationV2 | undefined {\n const row = stmts.getAnnotationV2.get(id) as Record<string, unknown> | undefined;\n return row ? rowToAnnotationV2(row) : undefined;\n },\n\n updateAnnotationV2(\n id: string,\n data: Partial<Omit<AnnotationV2, \"id\" | \"sessionId\" | \"createdAt\">>\n ): AnnotationV2 | undefined {\n const existing = this.getAnnotationV2(id);\n if (!existing) return undefined;\n\n stmts.updateAnnotationV2.run({\n id,\n elementText: data.elementText ?? null,\n comment: data.comment ?? null,\n source: data.source ? JSON.stringify(data.source) : null,\n metadata: data.metadata ? JSON.stringify(data.metadata) : null,\n updatedAt: new Date().toISOString(),\n });\n\n return this.getAnnotationV2(id);\n },\n\n getSessionAnnotationsV2(sessionId: string): AnnotationV2[] {\n const rows = stmts.getAnnotationsV2BySession.all(sessionId) as Record<string, unknown>[];\n return rows.map(rowToAnnotationV2);\n },\n\n deleteAnnotationV2(id: string): AnnotationV2 | undefined {\n const existing = this.getAnnotationV2(id);\n if (!existing) return undefined;\n stmts.deleteAnnotationV2.run(id);\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 getSessionWithAnnotationsV2,\n addAnnotation,\n addAnnotationV2,\n updateAnnotation,\n updateAnnotationV2,\n getAnnotation,\n getAnnotationV2,\n deleteAnnotation,\n deleteAnnotationV2,\n listSessions,\n getPendingAnnotations,\n addThreadMessage,\n getEventsSince,\n} from \"./store.js\";\nimport { eventBus } from \"./events.js\";\nimport type { Annotation, AnnotationV2, 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// V2 Route Handlers (Vue schema)\n// -----------------------------------------------------------------------------\n\n/**\n * GET /v2/sessions/:id - Get session with V2 annotations.\n */\nconst getSessionV2Handler: RouteHandler = async (_req, res, params) => {\n const session = getSessionWithAnnotationsV2(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 /v2/sessions/:id/annotations - Add V2 annotation to session.\n */\nconst addAnnotationV2Handler: RouteHandler = async (req, res, params) => {\n try {\n const body = await parseBody<AnnotationV2>(req);\n\n if (!body.id || !body.comment || !body.elementSelector || !body.source) {\n return sendError(res, 400, \"id, comment, elementSelector, and source are required\");\n }\n\n // Idempotent: if annotation with same ID exists for this session, return it\n const existing = getAnnotationV2(body.id);\n if (existing) {\n if (existing.sessionId !== params.id) {\n return sendError(res, 409, \"Annotation ID already exists in a different session\");\n }\n return sendJson(res, 200, existing);\n }\n\n const annotation = addAnnotationV2(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 /v2/annotations/:id - Update a V2 annotation.\n */\nconst updateAnnotationV2Handler: RouteHandler = async (req, res, params) => {\n try {\n const body = await parseBody<Partial<AnnotationV2>>(req);\n\n const existing = getAnnotationV2(params.id);\n if (!existing) {\n return sendError(res, 404, \"Annotation not found\");\n }\n\n const annotation = updateAnnotationV2(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 /v2/annotations/:id - Get a V2 annotation.\n */\nconst getAnnotationV2Handler: RouteHandler = async (_req, res, params) => {\n const annotation = getAnnotationV2(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 /v2/annotations/:id - Delete a V2 annotation.\n */\nconst deleteAnnotationV2Handler: RouteHandler = async (_req, res, params) => {\n const annotation = deleteAnnotationV2(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 // V2 routes (Vue schema) — must be before legacy routes for clean matching\n {\n method: \"GET\",\n pattern: /^\\/v2\\/sessions$/,\n handler: listSessionsHandler,\n paramNames: [],\n },\n {\n method: \"POST\",\n pattern: /^\\/v2\\/sessions$/,\n handler: createSessionHandler,\n paramNames: [],\n },\n {\n method: \"GET\",\n pattern: /^\\/v2\\/sessions\\/([^/]+)$/,\n handler: getSessionV2Handler,\n paramNames: [\"id\"],\n },\n {\n method: \"POST\",\n pattern: /^\\/v2\\/sessions\\/([^/]+)\\/annotations$/,\n handler: addAnnotationV2Handler,\n paramNames: [\"id\"],\n },\n {\n method: \"PATCH\",\n pattern: /^\\/v2\\/annotations\\/([^/]+)$/,\n handler: updateAnnotationV2Handler,\n paramNames: [\"id\"],\n },\n {\n method: \"GET\",\n pattern: /^\\/v2\\/annotations\\/([^/]+)$/,\n handler: getAnnotationV2Handler,\n paramNames: [\"id\"],\n },\n {\n method: \"DELETE\",\n pattern: /^\\/v2\\/annotations\\/([^/]+)$/,\n handler: deleteAnnotationV2Handler,\n paramNames: [\"id\"],\n },\n // Legacy routes (React schema)\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 * // TODO(phase6): Add MCP tools for V2 annotations (getSessionV2, getPendingV2, etc.)\n * // Currently, MCP tools only see legacy React annotations.\n * // V2 Vue annotations are accessible via the /v2/ HTTP API but not yet\n * // surfaced through the MCP tool layer.\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 SessionWithAnnotationsV2,\n Annotation,\n AnnotationV2,\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 annotationsV2 = new Map<string, AnnotationV2>();\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 getSessionWithAnnotationsV2(id: string): SessionWithAnnotationsV2 | undefined {\n const session = sessions.get(id);\n if (!session) return undefined;\n\n return {\n ...session,\n annotations: Array.from(annotationsV2.values()).filter(\n (a) => a.sessionId === id\n ),\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 // -- Annotations V2 (Vue schema) ------------------------------------------\n\n addAnnotationV2(sessionId: string, data: AnnotationV2): AnnotationV2 | undefined {\n const session = sessions.get(sessionId);\n if (!session) return undefined;\n\n // Idempotent: return existing if same ID\n const existing = annotationsV2.get(data.id);\n if (existing) return existing;\n\n const annotation: AnnotationV2 = {\n ...data,\n sessionId,\n createdAt: new Date().toISOString(),\n };\n\n annotationsV2.set(annotation.id, annotation);\n return annotation;\n },\n\n getAnnotationV2(id: string): AnnotationV2 | undefined {\n return annotationsV2.get(id);\n },\n\n updateAnnotationV2(\n id: string,\n data: Partial<Omit<AnnotationV2, \"id\" | \"sessionId\" | \"createdAt\">>\n ): AnnotationV2 | undefined {\n const annotation = annotationsV2.get(id);\n if (!annotation) return undefined;\n\n Object.assign(annotation, data, { updatedAt: new Date().toISOString() });\n return annotation;\n },\n\n getSessionAnnotationsV2(sessionId: string): AnnotationV2[] {\n return Array.from(annotationsV2.values()).filter(\n (a) => a.sessionId === sessionId\n );\n },\n\n deleteAnnotationV2(id: string): AnnotationV2 | undefined {\n const annotation = annotationsV2.get(id);\n if (!annotation) return undefined;\n annotationsV2.delete(id);\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 annotationsV2.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\n// -- V2 convenience exports --------------------------------------------------\n\nexport function getSessionWithAnnotationsV2(id: string): SessionWithAnnotationsV2 | undefined {\n return getStore().getSessionWithAnnotationsV2(id);\n}\n\nexport function addAnnotationV2(sessionId: string, data: AnnotationV2): AnnotationV2 | undefined {\n return getStore().addAnnotationV2(sessionId, data);\n}\n\nexport function getAnnotationV2(id: string): AnnotationV2 | undefined {\n return getStore().getAnnotationV2(id);\n}\n\nexport function updateAnnotationV2(\n id: string,\n data: Partial<Omit<AnnotationV2, \"id\" | \"sessionId\" | \"createdAt\">>\n): AnnotationV2 | undefined {\n return getStore().updateAnnotationV2(id, data);\n}\n\nexport function getSessionAnnotationsV2(sessionId: string): AnnotationV2[] {\n return getStore().getSessionAnnotationsV2(sessionId);\n}\n\nexport function deleteAnnotationV2(id: string): AnnotationV2 | undefined {\n return getStore().deleteAnnotationV2(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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agentation-vue-mcp",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "MCP server for Agentation - visual feedback for AI coding agents",
|
|
5
|
+
"license": "PolyForm-Shield-1.0.0",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/liuc-c/agentation-vue.git",
|
|
9
|
+
"directory": "mcp"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/liuc-c/agentation-vue/tree/main/mcp#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/liuc-c/agentation-vue/issues"
|
|
14
|
+
},
|
|
15
|
+
"main": "./dist/index.js",
|
|
16
|
+
"module": "./dist/index.mjs",
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"bin": {
|
|
19
|
+
"agentation-vue-mcp": "./dist/cli.js"
|
|
20
|
+
},
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": {
|
|
25
|
+
"types": "./dist/index.d.mts",
|
|
26
|
+
"default": "./dist/index.mjs"
|
|
27
|
+
},
|
|
28
|
+
"require": {
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"default": "./dist/index.js"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist"
|
|
39
|
+
],
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
42
|
+
"better-sqlite3": "^12.6.2",
|
|
43
|
+
"zod": "^3.23.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
47
|
+
"@types/node": "^20.0.0",
|
|
48
|
+
"tsup": "^8.0.0",
|
|
49
|
+
"typescript": "^5.0.0"
|
|
50
|
+
},
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=18.0.0"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsup",
|
|
56
|
+
"watch": "tsup --watch",
|
|
57
|
+
"dev": "pnpm build && pnpm watch",
|
|
58
|
+
"start": "pnpm build && node dist/cli.js server"
|
|
59
|
+
}
|
|
60
|
+
}
|