Skip to content

Add a @jira connector (mention → chip → live context at copy time) #17

Description

@ojowwalker77

Summary

Add a @jira connector so a Jira issue (or JQL search result) can be @-mentioned in the editor, resolved to a chip, and expanded into live context at copy time — the same pattern as the existing @github, @linear, @notion, and @sentry connectors.

Background

Connectors are the scalable unit behind an app chip. The editor and search panel only know how to ask a connector for search results and rendered context; each connector owns its own API details, and they're resolved concurrently at copy time by SelfContainedRenderer. @linear is the closest existing analogue (issue tracker, token auth, reference-typed selection).

Reference connector: LinearAppConnector in Sources/ComposerApp/Support/AppConnectors.swift.

Implementation steps

  1. Auth — Jira Cloud uses Basic auth with an Atlassian API token + account email + site URL (https://<site>.atlassian.net). The current ConnectorAuth.apiToken(label:hint:createURL:) captures a single secret, so decide one of:

    • encode email:token (and capture the site separately), or
    • extend ConnectorAuth with a case that carries the extra fields.

    Pick the lighter option that keeps Settings simple and document it in the PR. createURL should deep-link to https://id.atlassian.com/manage-profile/security/api-tokens. The secret is stored in ConnectorSecretStore.

  2. Connector struct — add private struct JiraAppConnector: ComposerAppConnector to AppConnectors.swift: let id = "@jira", the auth above, search(_:context:), and render(selection:).

    • search() → query the Jira REST API v3 (e.g. /rest/api/3/search with JQL, or issue-key lookup) and return AppSearchResults.
    • render(selection:) → fetch the issue summary, description, status, assignee, and key comments, and format them as a self-contained context section.
  3. Register — add JiraAppConnector() to AppConnectorRegistry.all.

  4. Selection type — add a case jira(JiraReference) to AppSelection in AppReference.swift and handle it in AppToken.string(appID:selection:) / AppToken.parse(_:) so the chip round-trips through the note's plain text.

  5. Mention catalog — add a MentionItem (id @jira, label, subtitle, SF Symbol) to MentionCatalog.all and map "@jira": .service in MentionCatalog.appCategory in MentionToken.swift.

  6. Service (optional but cleaner) — put the Jira REST calls in a JiraService.swift under Sources/ComposerApp/Services/, reading the secret from ConnectorSecretStore.

  7. Settings token field — confirm the connectors section of SettingsView renders the auth field(s); match the wiring of the existing token-backed connectors.

Acceptance criteria

  • @jira appears in the mention picker under the service category.
  • With credentials set, typing in the app-search panel returns Jira issues (by JQL and/or issue key); committing one inserts a resolved chip.
  • At copy time the chip expands into readable issue context (summary, description, status, comments) via SelfContainedRenderer.
  • With no credentials, the connector shows a clear "needs auth" state rather than failing silently.
  • ./script/build_and_run.sh --verify passes.

References

  • LinearAppConnector in AppConnectors.swift is the closest template (issue tracker, token auth, reference-typed selection).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions