Skip to main content
Emdash integrates with Linear, Jira, and GitHub Issues, allowing you to attach issue tracker tickets to tasks and pass them directly to coding agents. Agents receive the full issue context (title, description, labels, etc.) to implement features or fix bugs.
Integrations are optional. You can use Emdash without connecting any issue tracker.

Overview

The issue tracking workflow:
  1. Connect your issue tracker in Settings
  2. Browse issues directly in Emdash
  3. Attach an issue to a task
  4. Agent receives the full issue context
  5. Link PR to the issue when creating a pull request

Supported platforms

PlatformStatusAuthenticationService
Linear✅ SupportedAPI keyLinearService.ts
Jira✅ SupportedSite URL + API tokenJiraService.ts
GitHub Issues✅ Supportedgh CLIGitHubService.ts

Linear integration

Connecting Linear

1

Generate an API key

  1. Go to Linear Settings → API
  2. Click Create a personal API key
  3. Name it “Emdash” and copy the key
2

Add to Emdash

  1. Open Settings → Integrations → Linear
  2. Paste your API key
  3. Click Connect
Emdash validates the key by fetching your viewer info and workspace name.
3

Verify connection

The connection status will show:
  • Connected with your workspace name
  • ⚠️ Error if authentication failed

Using Linear issues

In any task, click Attach Issue and select Linear to browse:
  • Open issues from your workspace
  • Issues filtered by state.type not in ["completed", "cancelled"]
  • Up to 50 most recently updated issues

Implementation details

From LinearService.ts:91-129:
async initialFetch(limit = 50): Promise<any[]> {
  const token = await this.getStoredToken();
  if (!token) {
    throw new Error('Linear token not set. Connect Linear in settings first.');
  }

  const query = `
    query ListIssues($limit: Int!) {
      issues(
        first: $limit,
        orderBy: updatedAt,
        filter: { state: { type: { nin: ["completed", "cancelled"] } } }
      ) {
        nodes {
          id
          identifier
          title
          description
          url
          state { name type color }
          team { name key }
          project { name }
          assignee { displayName name }
          updatedAt
        }
      }
    }
  `;

  const response = await this.graphql<{ issues: { nodes: any[] } }>(token, query, {
    limit: sanitizedLimit,
  });

  return response?.issues?.nodes ?? [];
}
Linear tokens are stored securely in your OS keychain via Keytar (service name: emdash-linear).

Jira integration

Connecting Jira

1

Generate an API token

  1. Go to Atlassian API Tokens
  2. Click Create API token
  3. Name it “Emdash” and copy the token
2

Find your site URL

Your Jira site URL is the domain you use to access Jira:
  • Example: https://your-company.atlassian.net
3

Add to Emdash

  1. Open Settings → Integrations → Jira
  2. Enter:
    • Site URL: https://your-company.atlassian.net
    • Email: Your Atlassian account email
    • API Token: The token from step 1
  3. Click Connect
Emdash validates by calling /rest/api/3/myself.

Using Jira issues

Emdash fetches issues using fallback JQL queries to handle limited permissions:
  1. assignee = currentUser() ORDER BY updated DESC
  2. reporter = currentUser() ORDER BY updated DESC
  3. ORDER BY updated DESC (all issues you can see)
If all queries fail, falls back to issue picker for recently viewed issues.

ADF description handling

Jira uses Atlassian Document Format (ADF) for rich text. Emdash flattens it to plain text:
// From JiraService.ts:335-351
private static flattenAdf(node: any): string {
  if (!node) return '';
  if (typeof node === 'string') return node;
  if (node.type === 'text') return node.text || '';
  if (Array.isArray(node.content)) {
    const parts = node.content.map((c: any) => JiraService.flattenAdf(c));
    if (['doc', 'bulletList', 'orderedList'].includes(node.type)) {
      return parts.join('\n');
    }
    if (['paragraph', 'heading', 'listItem'].includes(node.type)) {
      return parts.join('');
    }
    return parts.join('');
  }
  return '';
}
Jira credentials are stored in:
  • API token: OS keychain (Keytar, service name: emdash-jira)
  • Site URL + email: <userData>/jira.json

GitHub Issues integration

Connecting GitHub Issues

GitHub Issues authentication piggybacks on GitHub CLI:
1

Install GitHub CLI

# macOS
brew install gh

# Windows
winget install GitHub.cli

# Linux
sudo apt install gh  # Debian/Ubuntu
sudo yum install gh  # RHEL/CentOS
2

Authenticate with GitHub

gh auth login
Follow the prompts to authenticate via browser or token.
3

Verify in Emdash

Open Settings → GitHub. If authenticated, you’ll see:
  • Connected with your GitHub username
  • Your avatar and profile
GitHub Issues integration requires gh CLI. It does not work with GitHub OAuth tokens stored in Emdash alone.

Using GitHub Issues

Issues are project-specific. When you attach an issue to a task:
  1. Emdash runs gh issue list in the project directory
  2. Fetches open issues (state: open)
  3. Shows up to 50 most recently updated issues
From GitHubService.ts:491-521:
async listIssues(projectPath: string, limit: number = 50): Promise<any[]> {
  const fields = ['number', 'title', 'url', 'state', 'updatedAt', 'assignees', 'labels'];
  const { stdout } = await this.execGH(
    `gh issue list --state open --limit ${safeLimit} --json ${fields.join(',')}`,
    { cwd: projectPath }
  );
  const list = JSON.parse(stdout || '[]');
  if (!Array.isArray(list)) return [];
  return list;
}
GitHub Issues requires the project to be a GitHub repository. For non-GitHub projects, use Linear or Jira instead.

Credential storage summary

PlatformStorageService NameLocation
LinearKeytaremdash-linearapi-token account
Jira (token)Keytaremdash-jiraapi-token account
Jira (config)JSON file<userData>/jira.json
GitHubKeytar + gh CLIemdash-githubgithub-token account
Keychain locations:
  • macOS: Keychain Access.app
  • Linux: libsecret (GNOME Keyring, KWallet)
  • Windows: Windows Credential Manager

Disconnecting integrations

To disconnect an integration:
  1. Go to Settings → Integrations
  2. Select the platform (Linear/Jira/GitHub)
  3. Click Disconnect
Emdash will:
  • Remove credentials from the OS keychain
  • Clear any cached data
  • Stop fetching issues from that platform
Disconnecting an integration does not remove issues already attached to tasks. The issue metadata remains in the Emdash database.

Troubleshooting

Symptom: “Unable to retrieve Linear account information”Solutions:
  1. Verify the API key is correct (regenerate if needed)
  2. Check the key has the required scopes (read:issues, write:issues)
  3. Ensure your Linear workspace is active
Symptom: “Jira API error 401”Solutions:
  1. Verify your Atlassian email is correct
  2. Regenerate your API token
  3. Ensure your Jira site URL is correct (https:// required)
  4. Check you have access to the Jira project
Symptom: “GitHub CLI not installed”Solutions:
  1. Install gh CLI: brew install gh (macOS)
  2. Authenticate: gh auth login
  3. Restart Emdash to detect the CLI
  4. Check PATH includes gh location
Symptom: Issue list is empty despite having open issuesSolutions:
  • Linear: Check filter excludes completed/cancelled issues
  • Jira: Verify you have permission to view issues (try JQL in Jira web)
  • GitHub: Ensure the project is a GitHub repo with issues enabled

Best practices

Use dedicated API keys

Create separate API keys for Emdash (not your personal keys) for easier revocation.

Link PRs to issues

When creating PRs, Emdash can automatically reference the linked issue in the description.

Keep issue context minimal

Large issue descriptions can overwhelm agents. Summarize key requirements in the task description.

Rotate credentials regularly

Regenerate API keys periodically for security.

Build docs developers (and LLMs) love