### Development Setup and Commands Source: https://github.com/casals/obsidian-linear-integration-plugin/blob/master/README.md Provides essential commands for setting up the development environment for the Obsidian Linear Integration Plugin. Includes cloning the repository, installing dependencies, and running development or build tasks. ```bash # Clone the repository git clone https://github.com/your-username/obsidian-linear-plugin.git cd obsidian-linear-plugin # Install dependencies npm install # Start development npm run dev # Build for production npm run build # Run TypeScript checks npm run typecheck # Lint code npm run lint # Clean build artifacts npm run clean ``` -------------------------------- ### Inline Tag Syntax Documentation Source: https://github.com/casals/obsidian-linear-integration-plugin/blob/master/README.md Provides a reference for the enhanced inline tag syntax used within Obsidian notes for interacting with Linear. This table details various tag types, their syntax, examples, and whether they support auto-complete functionality. ```markdown | Tag Type | Syntax | Example | Auto-complete | |----------|--------|---------|---------------| | Team | `@team/team-name` | `@team/Engineering` | ✅ | | Assignee | `@assignee/username` | `@assignee/john.doe` | ✅ | | Status | `@status/status-name` | `@status/In Progress` | ✅ | | Priority | `@priority/number` | `@priority/1` | ✅ | | Project | `@project/project-name` | `@project/Q4 Roadmap` | ✅ | | Labels | `@label/label-name` | `@label/bug @label/urgent` | ✅ | **Note**: All tags support spaces in names (e.g., `@assignee/John Doe`, `@status/In Review`) ``` -------------------------------- ### Manage Linear Issues via API Client (TypeScript) Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt Provides examples of creating, retrieving, updating, and searching Linear issues using the `LinearClient`. It covers creating issues with basic and extended fields, fetching issues by ID or with filters, and performing batch updates. It also demonstrates adding comments to issues. ```typescript import { LinearClient } from './src/api/linear-client'; const client = new LinearClient('lin_api_your_key_here'); // Create a new issue with basic fields const newIssue = await client.createIssue( 'Bug: Login validation not working', // title 'The login form does not validate email addresses properly.', // description 'team-uuid', // teamId 'user-uuid', // assigneeId (optional) 'state-uuid', // stateId (optional) 1, // priority (1=Urgent, 2=High, 3=Medium, 4=Low) ['bug', 'frontend'] // labelNames (auto-creates if not exist) ); console.log('Created:', newIssue.identifier); // e.g., 'ENG-123' // Create issue with extended options const issue = await client.createIssueWithLabels( 'Feature: Dark mode', 'Implement dark mode toggle in settings', 'team-uuid', { assigneeId: 'user-uuid', stateId: 'state-uuid', priority: 2, labelIds: ['label-uuid-1', 'label-uuid-2'], projectId: 'project-uuid', dueDate: '2024-12-31' } ); // Get issues (with optional filters) const issues = await client.getIssues('team-uuid', '2024-01-01T00:00:00Z'); // Get a specific issue by ID const issue = await client.getIssueById('issue-uuid'); // Returns full issue with comments: { id, identifier, title, description, state, assignee, team, priority, estimate, labels, comments, ... } // Search issues by text const results = await client.searchIssues('login bug', 'team-uuid'); // Update an issue const updated = await client.updateIssue('issue-uuid', { title: 'Updated title', stateId: 'new-state-uuid', assigneeId: 'new-user-uuid' }); // Batch update multiple issues await client.batchUpdateIssues([ { issueId: 'issue-1', updates: { stateId: 'done-state-uuid' } }, { issueId: 'issue-2', updates: { stateId: 'done-state-uuid' } } ]); // Add a comment to an issue await client.addCommentToIssue('issue-uuid', 'This has been fixed in PR #42'); ``` -------------------------------- ### Create Linear Issue from Note Example Source: https://github.com/casals/obsidian-linear-integration-plugin/blob/master/README.md Demonstrates how to format a markdown note with inline tags to create a Linear issue. These tags specify details like team, assignee, priority, status, and labels, which the plugin interprets to pre-fill issue fields. ```markdown # Bug: Login validation not working @team/Engineering @assignee/sarah.jones @priority/1 @status/In Progress @label/critical @label/frontend The login form doesn't validate email addresses properly when users enter malformed addresses. Steps to reproduce: 1. Navigate to login page 2. Enter invalid email format 3. Submit form Expected: Validation error shown Actual: Form submits successfully ``` -------------------------------- ### Initialize and Test Linear API Client (TypeScript) Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt Demonstrates how to initialize the `LinearClient` with an API key and test the connection to the Linear GraphQL API. It also shows how to retrieve teams, users, workflow states, labels, and projects. ```typescript import { LinearClient } from './src/api/linear-client'; // Initialize the client with your API key const client = new LinearClient('lin_api_your_key_here'); // Test the connection const isConnected = await client.testConnection(); console.log('Connected:', isConnected); // Get all teams const teams = await client.getTeams(); // Returns: [{ id: 'team-uuid', name: 'Engineering', key: 'ENG' }, ...] // Get all users in the organization const users = await client.getUsers(); // Returns: [{ id: 'user-uuid', name: 'John Doe', email: 'john@company.com' }, ...] // Get workflow states for a specific team const states = await client.getTeamStates('team-uuid'); // Returns: [{ id: 'state-uuid', name: 'In Progress', type: 'started', color: '#3b82f6' }, ...] // Get all labels (optionally filtered by team) const labels = await client.getLabels('team-uuid'); // Returns: [{ id: 'label-uuid', name: 'bug', color: '#ff5722', parent: null, isGroup: false }, ...] // Get projects const projects = await client.getProjects('team-uuid'); // Returns: [{ id: 'project-uuid', name: 'Q4 Roadmap', description: 'Q4 initiatives' }, ...] ``` -------------------------------- ### Frontmatter Integration for Synced Notes Source: https://github.com/casals/obsidian-linear-integration-plugin/blob/master/README.md Demonstrates the automatic management of frontmatter for notes synced with Linear. This includes mapping Linear issue properties to YAML frontmatter fields. ```yaml --- linear_id: "issue-uuid" linear_identifier: "ENG-123" linear_status: "In Progress" linear_assignee: "John Doe" linear_team: "Engineering" linear_url: "https://linear.app/issue/ENG-123" linear_created: "2024-01-15T10:30:00Z" linear_updated: "2024-01-16T14:22:00Z" linear_last_synced: "2024-01-16T14:25:00Z" linear_priority: 1 linear_estimate: 5 linear_labels: ["bug", "frontend", "critical"] --- ``` -------------------------------- ### Generate Kanban and Agenda Views from Linear Issues Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt Creates Kanban boards and agenda views in Markdown format from Linear issues. These views can be automatically generated and saved as notes within Obsidian. ```typescript import { KanbanGenerator, AgendaGenerator } from './src/features/local-config-system'; // Generate a kanban board const kanbanGen = new KanbanGenerator(app.vault, linearClient, settings); const kanbanContent = await kanbanGen.generateKanbanBoard('team-uuid'); // Returns markdown grouped by status: /* # Linear Kanban Board *Generated: 1/16/2024, 10:30:00 AM* ## Todo (3) - [ ] 🔴 **[ENG-123](https://linear.app/...)** Fix login validation - Assignee: @John Doe - Team: Engineering - Estimate: 5pts ## In Progress (2) ... */ // Create kanban note file const kanbanFile = await kanbanGen.createKanbanNote('team-uuid'); // Creates: 'Linear Issues/Linear Kanban 2024-01-16.md' // Generate an agenda view const agendaGen = new AgendaGenerator(app.vault, linearClient, settings); const agendaContent = await agendaGen.generateAgenda('user-uuid', 7); // Returns markdown grouped by date with due issues // Create agenda note file const agendaFile = await agendaGen.createAgendaNote('user-uuid', 7); // Creates: 'Linear Issues/Linear Agenda 2024-01-16.md' ``` -------------------------------- ### Batch Operations with BatchOperationManager (TypeScript) Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt Manages bulk operations on multiple notes and Linear issues. It supports batch creation of issues from notes, synchronization of notes within a folder, and updating the status of multiple issues. Requires instances of Obsidian's App, Vault, LinearClient, and SyncManager. ```typescript import { BatchOperationManager } from './src/features/local-config-system'; const batchManager = new BatchOperationManager(app, app.vault, linearClient, syncManager); // Batch create issues from multiple notes const selectedFiles = [file1, file2, file3]; const results = await batchManager.batchCreateIssues(selectedFiles); console.log(`Created: ${results.successes}, Failed: ${results.failures.length}`); // Returns: { successes: 2, failures: ['file3.md: No team specified'] } // Batch sync all notes in a folder const syncResult = await batchManager.batchSyncNotes(folder); // Returns: { created: 5, updated: 3, errors: [...], conflicts: [...] } // Batch update status for multiple issues await batchManager.batchUpdateStatus( ['issue-uuid-1', 'issue-uuid-2', 'issue-uuid-3'], 'done-state-uuid' ); ``` -------------------------------- ### LocalConfigManager: Per-Folder Configuration for Linear Integration Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt The LocalConfigManager allows for managing local `.linear.json` configuration files, enabling folder-specific settings that override global plugin settings. It can retrieve configurations for specific notes by walking up the directory tree, save configurations for a note's directory, and retrieve all configurations within the vault. It also provides a method to clear the configuration cache. ```typescript import { LocalConfigManager } from './src/features/local-config-system'; const configManager = new LocalConfigManager(app.vault); // Get config for a specific note (walks up directory tree) const config = await configManager.getConfigForNote(file); // Returns: { workspace, team, project, labels, assignee, priority, autoSync, template } // Save config for a note's directory await configManager.saveConfigForNote(file, { workspace: 'my-company', team: 'engineering', project: 'q4-roadmap', defaultAssignee: 'john.doe@company.com', defaultPriority: 3, autoSync: true, labels: ['frontend', 'backend', 'bug-fix'] }); // Get all configs in the vault const allConfigs = await configManager.getAllConfigs(); // Returns: [{ path: 'projects/.linear.json', config: {...} }, ...] // Clear the config cache (call when config files are modified externally) configManager.clearCache(); // Example .linear.json file: /* { "workspace": "my-company", "team": "engineering", "project": "q4-roadmap", "defaultAssignee": "john.doe@company.com", "defaultPriority": 3, "autoSync": true, "labels": ["frontend", "backend"], "template": "# {{title}}\n\n**Status:** {{status}}\n...", "syncRules": { "bidirectional": true, "conflictResolution": "manual", "includeComments": true }, "display": { "showTooltips": true, "enableQuickEdit": true, "statusIcons": { "Backlog": "📋", "Todo": "📝", "In Progress": "🔄", "Done": "✅" } } } */ ``` -------------------------------- ### Custom Note Templates with Variables Source: https://github.com/casals/obsidian-linear-integration-plugin/blob/master/README.md Illustrates how to customize note generation using template variables provided by the Obsidian Linear Integration Plugin. These variables are dynamically replaced with Linear issue data. ```markdown # {{title}} **Status:** {{status}} | **Priority:** {{priority}} **Assignee:** {{assignee}} | **Team:** {{team}} **Created:** {{created}} | **Updated:** {{updated}} ## Description {{description}} ## Acceptance Criteria - [ ] ## Notes --- *Linear: [{{identifier}}]({{url}}) | Last synced: {{lastSync}}* ``` -------------------------------- ### Linear Autocomplete System (TypeScript) Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt Provides smart, context-aware autocomplete suggestions for inline tags within Obsidian notes. It supports various Linear entities like teams, assignees, statuses, priorities, labels, and projects, offering color-coded labels and cached data for efficiency. Integrates with Obsidian's EditorSuggest. ```typescript // The autocomplete system integrates with Obsidian's EditorSuggest // Trigger patterns: // @team/ -> Shows available teams // @assignee/ -> Shows team members // @status/ -> Shows workflow states // @priority/ -> Shows priority levels (1-4) // @label/ -> Shows labels with colors // @project/ -> Shows projects // Example usage in a note: /* # New Feature Request @team/Engineering @assignee/john.doe @priority/2 @status/Todo @label/feature @label/enhancement @project/Q4 Roadmap Implement dark mode toggle in application settings. */ // The autocomplete shows: // - Color-coded label dots matching Linear's label colors // - Hierarchical labels (group/child format) // - Default values from local config marked with "(default)" // - Fuzzy matching for faster selection // Settings that control autocomplete: // settings.autocompleteEnabled: boolean // settings.autoFillFromExpressions: boolean (pre-fill modal from tags) ``` -------------------------------- ### Local Configuration for Obsidian Linear Plugin Source: https://github.com/casals/obsidian-linear-integration-plugin/blob/master/README.md Defines local configuration settings for the Obsidian Linear Integration Plugin using a JSON file. This includes workspace details, default values, sync rules, and display preferences. ```json { "workspace": "my-company", "team": "engineering", "project": "q4-roadmap", "defaultAssignee": "john.doe@company.com", "defaultPriority": 3, "autoSync": true, "labels": [ "frontend", "backend", "bug-fix" ], "template": "# {{title}}\n\n**Status:** {{status}} | **Priority:** {{priority}}\n**Assignee:** {{assignee}} | **Team:** {{team}}\n\n## Context\n{{description}}\n\n## Acceptance Criteria\n- [ ] \n\n## Notes\n\n\n---\n*Linear: [{{identifier}}]({{url}}) | Last synced: {{lastSync}}*", "syncRules": { "bidirectional": true, "conflictResolution": "manual", "includeComments": true }, "display": { "showTooltips": true, "enableQuickEdit": true, "statusIcons": { "Backlog": "📋", "Todo": "📝", "In Progress": "🔄", "In Review": "👀", "Done": "✅", "Canceled": "❌" } } } ``` -------------------------------- ### SyncManager: Bidirectional Sync Between Obsidian and Linear Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt The SyncManager handles bidirectional synchronization between Obsidian notes and Linear issues. It creates and updates notes with proper frontmatter, manages note creation for issues, and extracts Linear data from notes. Dependencies include the Obsidian app, LinearClient, settings, and the plugin instance. ```typescript import { SyncManager } from './src/sync/sync-manager'; import { LinearClient } from './src/api/linear-client'; // Initialize sync manager (typically done in plugin.onload) const syncManager = new SyncManager(app, linearClient, settings, plugin); // Sync all issues from Linear to Obsidian const result = await syncManager.syncAll(); console.log(`Created: ${result.created}, Updated: ${result.updated}`); console.log('Errors:', result.errors); console.log('Conflicts:', result.conflicts); // Find or create a note for a specific issue const file = await syncManager.findOrCreateNoteForIssue(linearIssue); // Update a note with Linear issue data const isNew = await syncManager.updateNoteWithIssue(file, linearIssue); // Get frontmatter from a note const frontmatter = await syncManager.getFrontmatter(file); // Returns: { linear_id, linear_identifier, linear_status, linear_assignee, linear_team, linear_url, ... } // Get the Linear issue ID from a note const issueId = await syncManager.getLinearIdFromNote(file); // Generated note frontmatter structure: /* --- linear_id: "issue-uuid" linear_identifier: "ENG-123" linear_status: "In Progress" linear_assignee: "John Doe" linear_team: "Engineering" linear_url: "https://linear.app/issue/ENG-123" linear_created: "2024-01-15T10:30:00Z" linear_updated: "2024-01-16T14:22:00Z" linear_last_synced: "2024-01-16T14:25:00Z" linear_priority: 1 linear_estimate: 5 linear_labels: - bug - frontend --- */ ``` -------------------------------- ### Plugin Settings Interface and Defaults (TypeScript) Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt Defines the interface for plugin settings, including API keys, default team IDs, sync configurations, and UI preferences. It also provides default values for status mappings, which associate Linear statuses with emojis for visual representation in Obsidian. ```typescript // Available Obsidian commands: // - "Create Linear issue from note" (Ctrl/Cmd + P -> "Linear: Create Issue") // - "Sync Linear issues" // - "Open Linear issue in browser" // - "Quick edit Linear issue" // - "Generate Kanban board" // - "Generate agenda" // - "Mirror Linear comments" // - "Batch create issues from selection" // - "Insert issue reference" // Plugin settings interface: interface LinearPluginSettings { apiKey: string; // Linear API key (lin_api_...) teamId: string; // Default team ID syncFolder: string; // Folder for synced notes (default: "Linear Issues") autoSync: boolean; // Sync on startup autoSyncInterval: number; // Minutes between auto-syncs (0 to disable) autocompleteEnabled: boolean; quickEditEnabled: boolean; tooltipsEnabled: boolean; autoFillFromExpressions: boolean; conflictResolution: 'manual' | 'linear-wins' | 'obsidian-wins' | 'timestamp'; statusMapping: Record; // Status -> emoji mapping noteTemplate: string; // Template for new notes inlineCommentMirroring: boolean; debugMode: boolean; } // Default status mapping: const statusMapping = { 'Todo': '📋', 'In Progress': '🔄', 'Done': '✅', 'Canceled': '❌' }; ``` -------------------------------- ### Parse Markdown Tags and Content Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt Parses inline tags, note configuration, titles, and converts content for Linear compatibility. It also supports generating and embedding issue references and replacing tags. ```typescript const tags = MarkdownParser.parseInlineTags(content); // Returns: [ // { type: 'assignee', value: 'john.doe', position: { start: 52, end: 70 } }, // { type: 'priority', value: '1', position: { start: 71, end: 83 } }, // { type: 'label', value: 'bug', position: { start: 100, end: 104 } }, // ... // ] // Parse full note config from frontmatter and inline tags const config = MarkdownParser.parseNoteConfig(app, file, content); // Returns: { team, assignee, priority, project, labels: ['bug', 'frontend'], ... } // Extract title from content const title = MarkdownParser.extractTitle(content); // Returns: 'Bug: Login validation not working' // Convert to Linear-compatible description (removes tags, converts Obsidian syntax) const description = MarkdownParser.convertToLinearDescription(content); // Removes frontmatter, inline tags, converts wikilinks, callouts, highlights // Generate an issue reference link const reference = MarkdownParser.generateIssueReference('issue-uuid', 'ENG-123'); // Returns: '[ENG-123](https://linear.app/issue/issue-uuid)' // Embed issue reference in note content const updatedContent = MarkdownParser.embedIssueReference(content, reference, 'bottom'); // Adds: '\n---\n**Linear Issue:** [ENG-123](...)\n---\n' // Replace inline tags with new values const replaced = MarkdownParser.replaceInlineTags(content, { '@status/In Progress': '@status/Done' }); ``` -------------------------------- ### Comment Mirroring with CommentMirror (TypeScript) Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt Synchronizes comments from Linear issues to corresponding Obsidian notes. It adds or updates a 'Comments' section within the note, displaying each comment with its author and timestamp. Requires Obsidian's Vault and a LinearClient instance. ```typescript import { CommentMirror } from './src/features/local-config-system'; const commentMirror = new CommentMirror(app.vault, linearClient); // Mirror comments from Linear to a note await commentMirror.mirrorCommentsToNote(file, 'issue-uuid'); // This adds or updates a Comments section in the note: /* ## Comments ### John Doe - 1/15/2024, 2:30:00 PM This has been investigated. The root cause is in the validation regex. --- ### Jane Smith - 1/16/2024, 9:15:00 AM Fixed in PR #42. Ready for review. --- */ ``` -------------------------------- ### MarkdownParser: Parsing Inline Tags and Converting Syntax Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt The MarkdownParser is responsible for parsing inline tags from markdown notes and converting Obsidian-specific syntax into a format compatible with Linear. This allows for seamless integration of markdown content into Linear issues. ```typescript import { MarkdownParser } from './src/parsers/markdown-parser'; // Parse inline tags from note content const content = ` ``` -------------------------------- ### Resolve Sync Conflicts with Linear Issues Source: https://context7.com/casals/obsidian-linear-integration-plugin/llms.txt Handles synchronization conflicts between Linear issues and Obsidian notes. It can detect differences and resolve them based on user settings or manual intervention. ```typescript import { ConflictResolver, ConflictHistory } from './src/features/conflict-resolver'; const resolver = new ConflictResolver(app, settings); // Detect conflicts between Linear issue and note const conflicts = resolver.detectConflicts(linearIssue, noteFrontmatter, noteContent); // Returns: [ // { issueId: 'uuid', field: 'title', linearValue: 'New Title', obsidianValue: 'Old Title', timestamp: '...' }, // { issueId: 'uuid', field: 'status', linearValue: 'Done', obsidianValue: 'In Progress', timestamp: '...' }, // ... // ] // Resolve conflicts based on settings const resolutions = await resolver.resolveConflicts(conflicts); // Based on settings.conflictResolution: 'manual' | 'linear-wins' | 'obsidian-wins' | 'timestamp' // Returns: { 'uuid-title': 'linear', 'uuid-status': 'obsidian', ... } // Manual resolution opens a modal for user to choose per-field // Track conflict history const history = new ConflictHistory(); history.addConflict(conflict); // Get recent conflicts (last 7 days by default) const recentConflicts = history.getRecentConflicts(7); // Get conflicts for a specific issue const issueConflicts = history.getConflictsByIssue('issue-uuid'); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.