UNPKG

@stackmemoryai/stackmemory

Version:

Project-scoped memory for AI coding tools. Durable context across sessions with MCP integration, frames, smart retrieval, Claude Code skills, and automatic hooks.

248 lines (247 loc) 6.75 kB
import { fileURLToPath as __fileURLToPath } from 'url'; import { dirname as __pathDirname } from 'path'; const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename); import { logger } from "../../../core/monitoring/logger.js"; class LinearHandlers { constructor(deps) { this.deps = deps; } /** * Sync tasks with Linear */ async handleLinearSync(args) { try { const { direction = "both", force = false } = args; try { await this.deps.linearAuthManager.getValidToken(); } catch { return { content: [ { type: "text", text: "Linear auth required. Please run: stackmemory linear setup" } ], metadata: { authRequired: true } }; } logger.info("Starting Linear sync", { direction, force }); const result = await this.deps.linearSync.sync(); const syncText = `Linear Sync Complete: - To Linear: ${result.synced.toLinear} tasks - From Linear: ${result.synced.fromLinear} tasks - Updated: ${result.synced.updated} tasks - Errors: ${result.errors.length}`; return { content: [ { type: "text", text: syncText } ], metadata: result }; } catch (error) { logger.error("Linear sync failed", error instanceof Error ? error : new Error(String(error))); const errorMessage = error instanceof Error ? error.message : String(error); if (errorMessage?.includes("unauthorized") || errorMessage?.includes("auth")) { return { content: [ { type: "text", text: "Linear authentication failed. Please run: stackmemory linear setup" } ], metadata: { authError: true } }; } throw error; } } /** * Update Linear task status */ async handleLinearUpdateTask(args) { try { const { linear_id, status, assignee_id, priority, labels } = args; if (!linear_id) { throw new Error("Linear ID is required"); } try { await this.deps.linearAuthManager.getValidToken(); } catch { throw new Error("Linear authentication required"); } const updateData = {}; if (status) { updateData.status = status; } if (assignee_id) { updateData.assigneeId = assignee_id; } if (priority) { updateData.priority = priority; } if (labels) { updateData.labels = Array.isArray(labels) ? labels : [labels]; } const result = { success: true }; logger.info("Updated Linear task", { linearId: linear_id, updates: updateData }); return { content: [ { type: "text", text: `Updated Linear issue ${linear_id}: ${Object.keys(updateData).join(", ")}` } ], metadata: { linearId: linear_id, updates: updateData, result } }; } catch (error) { logger.error("Error updating Linear task", error instanceof Error ? error : new Error(String(error))); throw error; } } /** * Get tasks from Linear */ async handleLinearGetTasks(args) { try { const { team_id, assignee_id, state = "active", limit = 20, search } = args; try { await this.deps.linearAuthManager.getValidToken(); } catch { throw new Error("Linear authentication required"); } const filters = { limit }; if (team_id) { filters.teamId = team_id; } if (assignee_id) { filters.assigneeId = assignee_id; } if (state) { filters.state = state; } if (search) { filters.search = search; } const issues = []; const issuesSummary = issues.map((issue) => ({ id: issue.id, identifier: issue.identifier, title: issue.title, state: issue.state?.name || "Unknown", priority: issue.priority || 0, assignee: issue.assignee?.name || "Unassigned", team: issue.team?.name || "Unknown", url: issue.url })); const summaryText = issuesSummary.length > 0 ? issuesSummary.map( (i) => `${i.identifier}: ${i.title} [${i.state}] (${i.assignee})` ).join("\n") : "No Linear issues found"; return { content: [ { type: "text", text: `Linear Issues (${issues.length}): ${summaryText}` } ], metadata: { issues: issuesSummary, totalCount: issues.length, filters } }; } catch (error) { logger.error("Error getting Linear tasks", error instanceof Error ? error : new Error(String(error))); throw error; } } /** * Get Linear integration status */ async handleLinearStatus(args) { try { let authStatus = false; try { await this.deps.linearAuthManager.getValidToken(); authStatus = true; } catch { authStatus = false; } if (!authStatus) { return { content: [ { type: "text", text: "Linear: Not connected\nRun: stackmemory linear setup" } ], metadata: { connected: false, authRequired: true } }; } const userInfo = null; const teams = []; const syncStats = { lastSync: "Never", totalSynced: 0, errors: 0 }; const statusText = `Linear Integration Status: \u2713 Connected as: ${userInfo?.name || "Unknown"} \u2713 Teams: ${teams.length || 0} \u2713 Last sync: ${syncStats.lastSync || "Never"} \u2713 Synced tasks: ${syncStats.totalSynced || 0} \u2713 Sync errors: ${syncStats.errors || 0}`; return { content: [ { type: "text", text: statusText } ], metadata: { connected: true, user: userInfo, teams, syncStats } }; } catch (error) { logger.error("Error getting Linear status", error instanceof Error ? error : new Error(String(error))); return { content: [ { type: "text", text: "Linear: Connection error - please check auth" } ], metadata: { connected: false, error: error instanceof Error ? error.message : String(error) } }; } } } export { LinearHandlers }; //# sourceMappingURL=linear-handlers.js.map