Skip to content

Link task to GitHub Pull Request (Task Detail + MCP update_task) #4

@tasks-flow

Description

@tasks-flow

Task ↔ Pull Request Linking (Task Detail + MCP update_task)

Summary

Add first-class PR linking for tasks from already linked GitHub repositories, available in:

  1. Task detail panel UI.
  2. MCP via existing update_task tool permission (no new MCP scope).

This will reuse existing task:update authorization and existing external_links storage (externalType = github_pr), with validation against linked repositories and real GitHub PR existence.

Implementation Plan

1. Add shared API contract for PR linking request

Files:

  • /Users/arnaudjezequel/Documents/dev/flowtask/packages/shared/src/types/task.ts

Changes:

  1. Add a new schema/type for linking a PR to a task, e.g. LinkTaskGitHubPrSchema with:
    • owner: string
    • repo: string
    • prNumber: positive int (coerced)
  2. Export the corresponding TypeScript type.
  3. Keep existing UpdateTaskSchema unchanged (PR linking remains a dedicated endpoint in REST).

2. Centralize GitHub PR link logic in API service

Files:

  • /Users/arnaudjezequel/Documents/dev/flowtask/apps/api/src/services/task-github-link-service.ts (new)

Changes:

  1. Create a small service/helper that:
    • Resolves active GitHub integration for a project.
    • Verifies the target repo is in integration config.repositories.
    • Resolves installation ID for that repo.
    • Fetches PR from GitHub (getPullRequest) to validate and get canonical URL.
    • Checks duplicates before insert:
      • same task + same PR (ALREADY_LINKED)
      • same integration + same PR linked elsewhere (PR_ALREADY_LINKED)
    • Inserts external_links row with:
      • externalType: 'github_pr'
      • externalId: prNumber.toString()
      • externalUrl: pullRequest.html_url
      • lastSyncedAt: now
  2. Return structured domain errors (code + status) for route/MCP error mapping consistency.

3. Add REST endpoint for task detail panel

Files:

  • /Users/arnaudjezequel/Documents/dev/flowtask/apps/api/src/routes/tasks.ts

Changes:

  1. Add POST /api/tasks/:taskId/github-pr endpoint using new shared schema.
  2. Authorization: same as update task (task:update) via existing checkTaskAccess.
  3. Call the new service helper.
  4. On success:
    • Publish task:updated SSE with refreshed task payload.
    • Return 201 with linked PR info (URL + number).
  5. Error codes:
    • NO_INTEGRATION
    • REPO_NOT_LINKED
    • NO_INSTALLATION
    • ALREADY_LINKED
    • PR_ALREADY_LINKED
    • GITHUB_ERROR

4. Extend MCP update_task input to support PR linking

Files:

  • /Users/arnaudjezequel/Documents/dev/flowtask/packages/domain/src/agent/types.ts
  • /Users/arnaudjequel/Documents/dev/flowtask/apps/api/src/routes/mcp.ts
  • /Users/arnaudjequel/Documents/dev/flowtask/apps/api/src/routes/mcp-sse.ts

Changes:

  1. Extend AGENT_TOOLS definition for update_task with optional fields:
    • githubPrOwner: string
    • githubPrRepo: string
    • githubPrNumber: integer
  2. In both MCP execution paths (mcp.ts and mcp-sse.ts):
    • Keep existing update_task scope check (no new tool).
    • Validate PR args are all present together if any is present.
    • Reuse the same API helper/service for linking logic.
    • Support both:
      • link-only call
      • combined update + link call
    • Return the refreshed task (including updated externalLinks).

5. Update task detail panel UI

Files:

  • /Users/arnaudjezequel/Documents/dev/flowtask/apps/web/src/components/tasks/GitHubLinkSection.tsx

Changes:

  1. Add a “Link PR” flow in the GitHub section:
    • Select linked repo.
    • Input PR number.
    • Submit to POST /api/tasks/:taskId/github-pr.
  2. Keep current “Create issue” flow unchanged.
  3. Refresh task query after success.
  4. Show inline error text from API.
  5. Keep multiple PR links allowed and rendered as today.

Public API / Interface Changes

  1. New REST endpoint:
    • POST /api/tasks/:taskId/github-pr
  2. New shared schema/type in @flowtask/shared for PR-link request payload.
  3. MCP update_task tool input adds optional params:
    • githubPrOwner
    • githubPrRepo
    • githubPrNumber
  4. No new MCP tool, no new OAuth tool scope, no permission model changes.

Test Cases And Scenarios

API / Auth

  1. User with task:update can link PR from a linked repo.
  2. User without access gets 403.
  3. Linking with repo not linked to project returns REPO_NOT_LINKED.
  4. Linking unknown PR number returns GITHUB_ERROR/not found mapping.
  5. Linking same PR twice on same task returns ALREADY_LINKED.
  6. Linking PR already linked to another task in same integration returns PR_ALREADY_LINKED.

MCP

  1. update_task with only PR args links successfully and returns task with new github_pr external link.
  2. update_task with regular fields + PR args updates and links in one call.
  3. Missing one PR arg (owner/repo/number) fails with validation error.
  4. Token lacking update_task scope cannot perform PR linking.

UI

  1. Task detail panel shows Link PR controls when GitHub repos are linked.
  2. Successful link appears immediately in PR links list.
  3. API errors are surfaced in panel.
  4. Multiple PR links can be added and displayed.

Validation Commands

  1. bun run --filter @flowtask/shared build
  2. bun run --filter @flowtask/domain build
  3. bun run --filter @flowtask/api typecheck
  4. bun run --filter @flowtask/web typecheck
  5. bun run --filter @flowtask/api build
  6. bun run --filter @flowtask/web build

Assumptions And Defaults

  1. UI input mode: repository selector + PR number entry.
  2. A task may have multiple linked PRs.
  3. MCP uses existing update_task tool (extended args), not a new tool.
  4. This scope includes linking only (no unlink/remove PR in this change).
  5. Existing external ID convention remains (externalId = PR number as string).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions