import { DevinIcon, LinearIcon, SlackIcon } from '@/components/icons'
import { getScopesForService } from '@/lib/oauth/utils'
import type { BlockConfig, BlockMeta } from '@/blocks/types'
import { AuthMode, IntegrationType } from '@/blocks/types'
import { normalizeFileInput } from '@/blocks/utils'
import type { LinearResponse } from '@/tools/linear/types'
import { getTrigger } from '@/triggers'

export const LinearBlock: BlockConfig<LinearResponse> = {
  type: 'linear',
  name: 'Linear (Legacy)',
  description: 'Interact with Linear issues, projects, and more',
  hideFromToolbar: true,
  authMode: AuthMode.OAuth,
  triggerAllowed: true,
  longDescription:
    'Integrate Linear into the workflow. Can manage issues, comments, projects, labels, workflow states, cycles, attachments, and more. Can also trigger workflows based on Linear webhook events.',
  docsLink: 'https://docs.sim.ai/integrations/linear',
  category: 'tools',
  integrationType: IntegrationType.Productivity,
  icon: LinearIcon,
  bgColor: '#5E6AD2',
  subBlocks: [
    {
      id: 'operation',
      title: 'Operation',
      type: 'dropdown',
      options: [
        // Issue Operations
        { label: 'Read Issues', id: 'linear_read_issues' },
        { label: 'Get Issue', id: 'linear_get_issue' },
        { label: 'Create Issue', id: 'linear_create_issue' },
        { label: 'Update Issue', id: 'linear_update_issue' },
        { label: 'Archive Issue', id: 'linear_archive_issue' },
        { label: 'Unarchive Issue', id: 'linear_unarchive_issue' },
        { label: 'Delete Issue', id: 'linear_delete_issue' },
        { label: 'Search Issues', id: 'linear_search_issues' },
        { label: 'Add Label to Issue', id: 'linear_add_label_to_issue' },
        { label: 'Remove Label from Issue', id: 'linear_remove_label_from_issue' },
        // Comment Operations
        { label: 'Create Comment', id: 'linear_create_comment' },
        { label: 'Update Comment', id: 'linear_update_comment' },
        { label: 'Delete Comment', id: 'linear_delete_comment' },
        { label: 'List Comments', id: 'linear_list_comments' },
        // Project Operations
        { label: 'List Projects', id: 'linear_list_projects' },
        { label: 'Get Project', id: 'linear_get_project' },
        { label: 'Create Project', id: 'linear_create_project' },
        { label: 'Update Project', id: 'linear_update_project' },
        { label: 'Archive Project', id: 'linear_archive_project' },
        // User & Team Operations
        { label: 'List Users', id: 'linear_list_users' },
        { label: 'List Teams', id: 'linear_list_teams' },
        { label: 'Get Viewer', id: 'linear_get_viewer' },
        // Label Operations
        { label: 'List Labels', id: 'linear_list_labels' },
        { label: 'Create Label', id: 'linear_create_label' },
        { label: 'Update Label', id: 'linear_update_label' },
        { label: 'Archive Label', id: 'linear_archive_label' },
        // Workflow State Operations
        { label: 'List Workflow States', id: 'linear_list_workflow_states' },
        { label: 'Create Workflow State', id: 'linear_create_workflow_state' },
        { label: 'Update Workflow State', id: 'linear_update_workflow_state' },
        // Cycle Operations
        { label: 'List Cycles', id: 'linear_list_cycles' },
        { label: 'Get Cycle', id: 'linear_get_cycle' },
        { label: 'Create Cycle', id: 'linear_create_cycle' },
        { label: 'Get Active Cycle', id: 'linear_get_active_cycle' },
        // Attachment Operations
        { label: 'Create Attachment', id: 'linear_create_attachment' },
        { label: 'List Attachments', id: 'linear_list_attachments' },
        { label: 'Update Attachment', id: 'linear_update_attachment' },
        { label: 'Delete Attachment', id: 'linear_delete_attachment' },
        // Issue Relation Operations
        { label: 'Create Issue Relation', id: 'linear_create_issue_relation' },
        { label: 'List Issue Relations', id: 'linear_list_issue_relations' },
        { label: 'Delete Issue Relation', id: 'linear_delete_issue_relation' },
        // Favorite Operations
        { label: 'Create Favorite', id: 'linear_create_favorite' },
        { label: 'List Favorites', id: 'linear_list_favorites' },
        // Project Update Operations
        { label: 'Create Project Update', id: 'linear_create_project_update' },
        { label: 'List Project Updates', id: 'linear_list_project_updates' },
        // Notification Operations
        { label: 'List Notifications', id: 'linear_list_notifications' },
        { label: 'Update Notification', id: 'linear_update_notification' },
        // Customer Operations
        { label: 'Create Customer', id: 'linear_create_customer' },
        { label: 'List Customers', id: 'linear_list_customers' },
        // Customer Request Operations
        { label: 'Create Customer Request', id: 'linear_create_customer_request' },
        { label: 'Update Customer Request', id: 'linear_update_customer_request' },
        { label: 'List Customer Requests', id: 'linear_list_customer_requests' },
        // Customer Management Operations
        { label: 'Get Customer', id: 'linear_get_customer' },
        { label: 'Update Customer', id: 'linear_update_customer' },
        { label: 'Delete Customer', id: 'linear_delete_customer' },
        { label: 'Merge Customers', id: 'linear_merge_customers' },
        // Customer Status Operations
        { label: 'Create Customer Status', id: 'linear_create_customer_status' },
        { label: 'Update Customer Status', id: 'linear_update_customer_status' },
        { label: 'Delete Customer Status', id: 'linear_delete_customer_status' },
        { label: 'List Customer Statuses', id: 'linear_list_customer_statuses' },
        // Customer Tier Operations
        { label: 'Create Customer Tier', id: 'linear_create_customer_tier' },
        { label: 'Update Customer Tier', id: 'linear_update_customer_tier' },
        { label: 'Delete Customer Tier', id: 'linear_delete_customer_tier' },
        { label: 'List Customer Tiers', id: 'linear_list_customer_tiers' },
        // Project Management Operations
        { label: 'Delete Project', id: 'linear_delete_project' },
        // Project Label Operations
        { label: 'Create Project Label', id: 'linear_create_project_label' },
        { label: 'Update Project Label', id: 'linear_update_project_label' },
        { label: 'Delete Project Label', id: 'linear_delete_project_label' },
        { label: 'List Project Labels', id: 'linear_list_project_labels' },
        { label: 'Add Label to Project', id: 'linear_add_label_to_project' },
        { label: 'Remove Label from Project', id: 'linear_remove_label_from_project' },
        // Project Milestone Operations
        { label: 'Create Project Milestone', id: 'linear_create_project_milestone' },
        { label: 'Update Project Milestone', id: 'linear_update_project_milestone' },
        { label: 'Delete Project Milestone', id: 'linear_delete_project_milestone' },
        { label: 'List Project Milestones', id: 'linear_list_project_milestones' },
        // Project Status Operations
        { label: 'Create Project Status', id: 'linear_create_project_status' },
        { label: 'Update Project Status', id: 'linear_update_project_status' },
        { label: 'Delete Project Status', id: 'linear_delete_project_status' },
        { label: 'List Project Statuses', id: 'linear_list_project_statuses' },
      ],
      value: () => 'linear_read_issues',
    },
    {
      id: 'credential',
      title: 'Linear Account',
      type: 'oauth-input',
      canonicalParamId: 'oauthCredential',
      mode: 'basic',
      serviceId: 'linear',
      requiredScopes: getScopesForService('linear'),
      placeholder: 'Select Linear account',
      required: true,
    },
    {
      id: 'manualCredential',
      title: 'Linear Account',
      type: 'short-input',
      canonicalParamId: 'oauthCredential',
      mode: 'advanced',
      placeholder: 'Enter credential ID',
      required: true,
    },
    // Team selector (for most operations)
    {
      id: 'teamId',
      title: 'Team',
      type: 'project-selector',
      canonicalParamId: 'teamId',
      serviceId: 'linear',
      selectorKey: 'linear.teams',
      placeholder: 'Select a team',
      dependsOn: ['credential'],
      mode: 'basic',
      required: {
        field: 'operation',
        value: [
          'linear_create_issue',
          'linear_create_project',
          'linear_list_workflow_states',
          'linear_create_workflow_state',
          'linear_create_cycle',
          'linear_get_active_cycle',
        ],
      },
      condition: {
        field: 'operation',
        value: [
          'linear_read_issues',
          'linear_create_issue',
          'linear_search_issues',
          'linear_list_projects',
          'linear_create_project',
          'linear_list_labels',
          'linear_list_workflow_states',
          'linear_create_workflow_state',
          'linear_list_cycles',
          'linear_create_cycle',
          'linear_get_active_cycle',
          'linear_list_project_labels',
        ],
      },
    },
    // Manual team ID input (advanced mode)
    {
      id: 'manualTeamId',
      title: 'Team ID',
      type: 'short-input',
      canonicalParamId: 'teamId',
      placeholder: 'Enter Linear team ID',
      mode: 'advanced',
      dependsOn: ['credential'],
      required: {
        field: 'operation',
        value: [
          'linear_create_issue',
          'linear_create_project',
          'linear_list_workflow_states',
          'linear_create_workflow_state',
          'linear_create_cycle',
          'linear_get_active_cycle',
        ],
      },
      condition: {
        field: 'operation',
        value: [
          'linear_read_issues',
          'linear_create_issue',
          'linear_search_issues',
          'linear_list_projects',
          'linear_create_project',
          'linear_list_labels',
          'linear_list_workflow_states',
          'linear_create_workflow_state',
          'linear_list_cycles',
          'linear_create_cycle',
          'linear_get_active_cycle',
          'linear_list_project_labels',
        ],
      },
    },
    // Project selector (for issue creation)
    {
      id: 'projectId',
      title: 'Project',
      type: 'project-selector',
      canonicalParamId: 'projectId',
      serviceId: 'linear',
      selectorKey: 'linear.projects',
      placeholder: 'Select a project',
      dependsOn: ['credential', 'teamId'],
      mode: 'basic',
      required: {
        field: 'operation',
        value: [
          'linear_get_project',
          'linear_update_project',
          'linear_archive_project',
          'linear_delete_project',
          'linear_create_project_update',
          'linear_list_project_updates',
        ],
      },
      condition: {
        field: 'operation',
        value: [
          'linear_read_issues',
          'linear_create_issue',
          'linear_get_project',
          'linear_update_project',
          'linear_archive_project',
          'linear_delete_project',
          'linear_create_project_update',
          'linear_list_project_updates',
          'linear_list_project_labels',
        ],
      },
    },
    // Manual project ID input (advanced mode)
    {
      id: 'manualProjectId',
      title: 'Project ID',
      type: 'short-input',
      canonicalParamId: 'projectId',
      placeholder: 'Enter Linear project ID',
      mode: 'advanced',
      dependsOn: ['credential', 'teamId'],
      required: {
        field: 'operation',
        value: [
          'linear_get_project',
          'linear_update_project',
          'linear_archive_project',
          'linear_delete_project',
          'linear_create_project_update',
          'linear_list_project_updates',
        ],
      },
      condition: {
        field: 'operation',
        value: [
          'linear_read_issues',
          'linear_create_issue',
          'linear_get_project',
          'linear_update_project',
          'linear_archive_project',
          'linear_delete_project',
          'linear_create_project_update',
          'linear_list_project_updates',
          'linear_list_project_labels',
        ],
      },
    },
    // Issue ID input (for operations requiring issue ID)
    {
      id: 'issueId',
      title: 'Issue ID',
      type: 'short-input',
      placeholder: 'Enter Linear issue ID',
      required: true,
      condition: {
        field: 'operation',
        value: [
          'linear_get_issue',
          'linear_update_issue',
          'linear_archive_issue',
          'linear_unarchive_issue',
          'linear_delete_issue',
          'linear_add_label_to_issue',
          'linear_remove_label_from_issue',
          'linear_create_comment',
          'linear_list_comments',
          'linear_create_attachment',
          'linear_list_attachments',
          'linear_create_issue_relation',
          'linear_list_issue_relations',
        ],
      },
    },
    // Title (for issue creation/update)
    {
      id: 'title',
      title: 'Title',
      type: 'short-input',
      placeholder: 'Enter issue title',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_issue', 'linear_update_issue'],
      },
      wandConfig: {
        enabled: true,
        prompt: `Generate a concise Linear issue title based on the user's description.
The title should:
- Be clear and descriptive
- Capture the essence of the issue
- Be suitable for project management tracking

Return ONLY the title text - no explanations.`,
        placeholder: 'Describe the issue (e.g., "login not working", "add export feature")...',
      },
    },
    // Description (for issue creation/update, comments, projects)
    {
      id: 'description',
      title: 'Description',
      type: 'long-input',
      placeholder: 'Enter description',
      condition: {
        field: 'operation',
        value: [
          'linear_create_issue',
          'linear_update_issue',
          'linear_create_project',
          'linear_update_project',
        ],
      },
      wandConfig: {
        enabled: true,
        prompt: `Generate a detailed description based on the user's description.
The description should:
- Provide context and details
- Include acceptance criteria or requirements when applicable
- Be professional and clear

Return ONLY the description text - no explanations.`,
        placeholder: 'Describe the details (e.g., "users report errors when logging in")...',
      },
    },
    // Comment body
    {
      id: 'body',
      title: 'Comment',
      type: 'long-input',
      placeholder: 'Enter comment text',
      required: {
        field: 'operation',
        value: ['linear_create_comment', 'linear_create_project_update'],
      },
      condition: {
        field: 'operation',
        value: ['linear_create_comment', 'linear_update_comment', 'linear_create_project_update'],
      },
      wandConfig: {
        enabled: true,
        prompt: `Generate a comment or project update based on the user's description.
The comment should:
- Be professional and informative
- Provide relevant updates or information
- Be suitable for team collaboration

Return ONLY the comment text - no explanations.`,
        placeholder:
          'Describe what you want to communicate (e.g., "progress update", "request for review")...',
      },
    },
    // Comment ID
    {
      id: 'commentId',
      title: 'Comment ID',
      type: 'short-input',
      placeholder: 'Enter comment ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_update_comment', 'linear_delete_comment'],
      },
    },
    // Label ID
    {
      id: 'labelId',
      title: 'Label ID',
      type: 'short-input',
      placeholder: 'Enter label ID',
      required: true,
      condition: {
        field: 'operation',
        value: [
          'linear_add_label_to_issue',
          'linear_remove_label_from_issue',
          'linear_update_label',
          'linear_archive_label',
        ],
      },
    },
    // Label name (for creating labels)
    {
      id: 'name',
      title: 'Name',
      type: 'short-input',
      placeholder: 'Enter name',
      required: {
        field: 'operation',
        value: ['linear_create_label', 'linear_create_project', 'linear_create_workflow_state'],
      },
      condition: {
        field: 'operation',
        value: [
          'linear_create_label',
          'linear_update_label',
          'linear_create_project',
          'linear_update_project',
          'linear_create_workflow_state',
          'linear_update_workflow_state',
          'linear_create_cycle',
        ],
      },
    },
    // Label color
    {
      id: 'color',
      title: 'Color (hex)',
      type: 'short-input',
      placeholder: '#5E6AD2',
      condition: {
        field: 'operation',
        value: [
          'linear_create_label',
          'linear_update_label',
          'linear_create_workflow_state',
          'linear_update_workflow_state',
        ],
      },
    },
    // State ID (for issue updates)
    {
      id: 'stateId',
      title: 'State ID',
      type: 'short-input',
      placeholder: 'Enter workflow state ID',
      condition: {
        field: 'operation',
        value: ['linear_update_issue', 'linear_update_workflow_state'],
      },
    },
    // Assignee ID (for issue operations)
    {
      id: 'assigneeId',
      title: 'Assignee ID',
      type: 'short-input',
      placeholder: 'Enter user ID to assign',
      condition: {
        field: 'operation',
        value: ['linear_create_issue', 'linear_update_issue'],
      },
    },
    // Priority (for issues and projects)
    {
      id: 'priority',
      title: 'Priority',
      type: 'dropdown',
      options: [
        { label: 'No Priority', id: '0' },
        { label: 'Urgent', id: '1' },
        { label: 'High', id: '2' },
        { label: 'Normal', id: '3' },
        { label: 'Low', id: '4' },
      ],
      value: () => '0',
      condition: {
        field: 'operation',
        value: ['linear_create_issue', 'linear_update_issue', 'linear_create_project'],
      },
    },
    // Estimate (for issues)
    {
      id: 'estimate',
      title: 'Estimate',
      type: 'short-input',
      placeholder: 'Enter estimate points',
      condition: {
        field: 'operation',
        value: ['linear_create_issue', 'linear_update_issue'],
      },
    },
    // Search query
    {
      id: 'query',
      title: 'Search Query',
      type: 'long-input',
      placeholder: 'Enter search query',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_search_issues'],
      },
      wandConfig: {
        enabled: true,
        prompt: `Generate a search query for Linear issues based on the user's description.
The query should:
- Be specific and targeted
- Use relevant keywords
- Be suitable for finding issues

Return ONLY the search query - no explanations.`,
        placeholder:
          'Describe what you want to search for (e.g., "open bugs", "my assigned tasks")...',
      },
    },
    // Include archived (for list operations)
    {
      id: 'includeArchived',
      title: 'Include Archived',
      type: 'switch',
      condition: {
        field: 'operation',
        value: ['linear_read_issues', 'linear_search_issues', 'linear_list_projects'],
      },
    },
    // Issue filtering options for read_issues (advanced)
    {
      id: 'labelIds',
      title: 'Label IDs',
      type: 'short-input',
      placeholder: 'Array of label IDs to filter by',
      mode: 'advanced',
      condition: {
        field: 'operation',
        value: 'linear_read_issues',
      },
    },
    {
      id: 'createdAfter',
      title: 'Created After',
      type: 'short-input',
      placeholder: 'Filter issues created after this date (ISO 8601 format)',
      mode: 'advanced',
      condition: {
        field: 'operation',
        value: 'linear_read_issues',
      },
    },
    {
      id: 'updatedAfter',
      title: 'Updated After',
      type: 'short-input',
      placeholder: 'Filter issues updated after this date (ISO 8601 format)',
      mode: 'advanced',
      condition: {
        field: 'operation',
        value: 'linear_read_issues',
      },
    },
    {
      id: 'orderBy',
      title: 'Order By',
      type: 'short-input',
      placeholder: 'Sort order: "createdAt" or "updatedAt" (default: "updatedAt")',
      mode: 'advanced',
      condition: {
        field: 'operation',
        value: 'linear_read_issues',
      },
    },
    // Cycle ID
    {
      id: 'cycleId',
      title: 'Cycle ID',
      type: 'short-input',
      placeholder: 'Enter cycle ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_get_cycle'],
      },
    },
    // Cycle start/end dates
    {
      id: 'startDate',
      title: 'Start Date',
      type: 'short-input',
      placeholder: 'YYYY-MM-DD',
      required: {
        field: 'operation',
        value: ['linear_create_cycle'],
      },
      condition: {
        field: 'operation',
        value: ['linear_create_cycle', 'linear_create_project'],
      },
      wandConfig: {
        enabled: true,
        prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "today" -> Today's date
- "next Monday" -> Calculate the next Monday
- "start of next month" -> First day of next month
- "in 2 weeks" -> Calculate 14 days from now

Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
        placeholder: 'Describe the start date (e.g., "next Monday", "start of next month")...',
        generationType: 'timestamp',
      },
    },
    {
      id: 'endDate',
      title: 'End Date',
      type: 'short-input',
      placeholder: 'YYYY-MM-DD',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_cycle'],
      },
      wandConfig: {
        enabled: true,
        prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "in 2 weeks" -> Calculate 14 days from now
- "end of month" -> Last day of current month
- "next Friday" -> Calculate the next Friday
- "end of quarter" -> Last day of current quarter

Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
        placeholder: 'Describe the end date (e.g., "in 2 weeks", "end of month")...',
        generationType: 'timestamp',
      },
    },
    // Target date (for projects)
    {
      id: 'targetDate',
      title: 'Target Date',
      type: 'short-input',
      placeholder: 'YYYY-MM-DD',
      condition: {
        field: 'operation',
        value: ['linear_create_project', 'linear_update_project'],
      },
      wandConfig: {
        enabled: true,
        prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "end of quarter" -> Last day of current quarter
- "in 3 months" -> Calculate 3 months from now
- "end of year" -> December 31 of current year
- "next month" -> First day of next month

Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
        placeholder: 'Describe the target date (e.g., "end of quarter", "in 3 months")...',
        generationType: 'timestamp',
      },
    },
    // Attachment file
    {
      id: 'attachmentFileUpload',
      title: 'Attachment',
      type: 'file-upload',
      canonicalParamId: 'file',
      placeholder: 'Upload attachment',
      condition: {
        field: 'operation',
        value: ['linear_create_attachment'],
      },
      mode: 'basic',
      multiple: false,
    },
    {
      id: 'file',
      title: 'File Reference',
      type: 'short-input',
      canonicalParamId: 'file',
      placeholder: 'File reference from previous block',
      condition: {
        field: 'operation',
        value: ['linear_create_attachment'],
      },
      mode: 'advanced',
    },
    // Attachment URL
    {
      id: 'url',
      title: 'URL',
      type: 'short-input',
      placeholder: 'Enter URL',
      required: false,
      condition: {
        field: 'operation',
        value: ['linear_create_attachment'],
      },
      mode: 'advanced',
    },
    // Attachment title
    {
      id: 'attachmentTitle',
      title: 'Title',
      type: 'short-input',
      placeholder: 'Enter attachment title',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_attachment', 'linear_update_attachment'],
      },
    },
    // Attachment ID
    {
      id: 'attachmentId',
      title: 'Attachment ID',
      type: 'short-input',
      placeholder: 'Enter attachment ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_update_attachment', 'linear_delete_attachment'],
      },
    },
    // Issue relation type
    {
      id: 'relationType',
      title: 'Relation Type',
      type: 'dropdown',
      options: [
        { label: 'Blocks', id: 'blocks' },
        { label: 'Blocked by', id: 'blocked' },
        { label: 'Duplicate', id: 'duplicate' },
        { label: 'Related', id: 'related' },
      ],
      value: () => 'related',
      condition: {
        field: 'operation',
        value: ['linear_create_issue_relation'],
      },
    },
    // Related issue ID
    {
      id: 'relatedIssueId',
      title: 'Related Issue ID',
      type: 'short-input',
      placeholder: 'Enter related issue ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_issue_relation'],
      },
    },
    // Relation ID
    {
      id: 'relationId',
      title: 'Relation ID',
      type: 'short-input',
      placeholder: 'Enter relation ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_delete_issue_relation'],
      },
    },
    // Favorite type
    {
      id: 'favoriteType',
      title: 'Favorite Type',
      type: 'dropdown',
      options: [
        { label: 'Issue', id: 'issue' },
        { label: 'Project', id: 'project' },
        { label: 'Cycle', id: 'cycle' },
        { label: 'Label', id: 'label' },
      ],
      value: () => 'issue',
      condition: {
        field: 'operation',
        value: ['linear_create_favorite'],
      },
    },
    // Favorite target ID
    {
      id: 'favoriteTargetId',
      title: 'Target ID',
      type: 'short-input',
      placeholder: 'Enter ID to favorite',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_favorite'],
      },
    },
    // Pagination - First (for list operations)
    {
      id: 'first',
      title: 'Limit',
      type: 'short-input',
      placeholder: 'Number of items to return (default: 50)',
      condition: {
        field: 'operation',
        value: [
          'linear_read_issues',
          'linear_search_issues',
          'linear_list_comments',
          'linear_list_projects',
          'linear_list_users',
          'linear_list_teams',
          'linear_list_labels',
          'linear_list_workflow_states',
          'linear_list_cycles',
          'linear_list_attachments',
          'linear_list_issue_relations',
          'linear_list_favorites',
          'linear_list_project_updates',
          'linear_list_notifications',
          'linear_list_customer_statuses',
          'linear_list_customer_tiers',
          'linear_list_customers',
          'linear_list_customer_requests',
          'linear_list_project_labels',
          'linear_list_project_milestones',
          'linear_list_project_statuses',
        ],
      },
    },
    // Pagination - After (for list operations)
    {
      id: 'after',
      title: 'After Cursor',
      type: 'short-input',
      placeholder: 'Cursor for pagination',
      condition: {
        field: 'operation',
        value: [
          'linear_read_issues',
          'linear_search_issues',
          'linear_list_comments',
          'linear_list_projects',
          'linear_list_users',
          'linear_list_teams',
          'linear_list_labels',
          'linear_list_workflow_states',
          'linear_list_cycles',
          'linear_list_attachments',
          'linear_list_issue_relations',
          'linear_list_favorites',
          'linear_list_project_updates',
          'linear_list_notifications',
          'linear_list_customers',
          'linear_list_customer_requests',
          'linear_list_customer_statuses',
          'linear_list_customer_tiers',
          'linear_list_project_labels',
          'linear_list_project_milestones',
          'linear_list_project_statuses',
        ],
      },
    },
    // Project health (for project updates)
    {
      id: 'health',
      title: 'Project Health',
      type: 'dropdown',
      options: [
        { label: 'On Track', id: 'onTrack' },
        { label: 'At Risk', id: 'atRisk' },
        { label: 'Off Track', id: 'offTrack' },
      ],
      value: () => 'onTrack',
      condition: {
        field: 'operation',
        value: ['linear_create_project_update'],
      },
    },
    // Notification ID
    {
      id: 'notificationId',
      title: 'Notification ID',
      type: 'short-input',
      placeholder: 'Enter notification ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_update_notification'],
      },
    },
    // Mark as read
    {
      id: 'markAsRead',
      title: 'Mark as Read',
      type: 'switch',
      condition: {
        field: 'operation',
        value: ['linear_update_notification'],
      },
    },
    // Workflow state type
    {
      id: 'workflowType',
      title: 'Workflow Type',
      type: 'dropdown',
      options: [
        { label: 'Backlog', id: 'backlog' },
        { label: 'Unstarted', id: 'unstarted' },
        { label: 'Started', id: 'started' },
        { label: 'Completed', id: 'completed' },
        { label: 'Canceled', id: 'canceled' },
      ],
      value: () => 'started',
      condition: {
        field: 'operation',
        value: ['linear_create_workflow_state'],
      },
    },
    // Lead ID (for projects)
    {
      id: 'leadId',
      title: 'Lead ID',
      type: 'short-input',
      placeholder: 'Enter user ID for project lead',
      condition: {
        field: 'operation',
        value: ['linear_create_project', 'linear_update_project'],
      },
    },
    // Project state
    {
      id: 'projectState',
      title: 'Project State',
      type: 'short-input',
      placeholder: 'Enter project state',
      condition: {
        field: 'operation',
        value: ['linear_update_project'],
      },
    },
    // Customer name (for creating/updating customer)
    {
      id: 'customerName',
      title: 'Customer Name',
      type: 'short-input',
      placeholder: 'Enter customer name',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_customer', 'linear_update_customer'],
      },
    },
    // Customer domains
    {
      id: 'customerDomains',
      title: 'Domains',
      type: 'long-input',
      placeholder: 'Enter domains (comma-separated)',
      condition: {
        field: 'operation',
        value: ['linear_create_customer', 'linear_update_customer'],
      },
    },
    // Customer external IDs
    {
      id: 'customerExternalIds',
      title: 'External IDs',
      type: 'long-input',
      placeholder: 'Enter external IDs (comma-separated)',
      condition: {
        field: 'operation',
        value: ['linear_create_customer', 'linear_update_customer'],
      },
    },
    // Customer logo URL
    {
      id: 'customerLogoUrl',
      title: 'Logo URL',
      type: 'short-input',
      placeholder: 'Enter logo URL',
      condition: {
        field: 'operation',
        value: ['linear_create_customer', 'linear_update_customer'],
      },
    },
    // Customer owner ID
    {
      id: 'customerOwnerId',
      title: 'Owner User ID',
      type: 'short-input',
      placeholder: 'Enter owner user ID',
      condition: {
        field: 'operation',
        value: ['linear_create_customer', 'linear_update_customer'],
      },
    },
    // Customer revenue
    {
      id: 'customerRevenue',
      title: 'Annual Revenue',
      type: 'short-input',
      placeholder: 'Enter annual revenue (number)',
      condition: {
        field: 'operation',
        value: ['linear_create_customer', 'linear_update_customer'],
      },
    },
    // Customer size
    {
      id: 'customerSize',
      title: 'Organization Size',
      type: 'short-input',
      placeholder: 'Enter organization size (number)',
      condition: {
        field: 'operation',
        value: ['linear_create_customer', 'linear_update_customer'],
      },
    },
    // Customer ID (for customer request operations)
    {
      id: 'customerId',
      title: 'Customer ID',
      type: 'short-input',
      placeholder: 'Enter customer ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_customer_request', 'linear_update_customer_request'],
      },
    },
    // Customer request ID (for updating)
    {
      id: 'customerNeedId',
      title: 'Customer Request ID',
      type: 'short-input',
      placeholder: 'Enter customer request ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_update_customer_request'],
      },
    },
    // Customer request body/description
    {
      id: 'requestBody',
      title: 'Request Description',
      type: 'long-input',
      placeholder: 'Enter customer request description',
      condition: {
        field: 'operation',
        value: ['linear_create_customer_request', 'linear_update_customer_request'],
      },
      wandConfig: {
        enabled: true,
        prompt: `Generate a customer request description based on the user's description.
The description should:
- Clearly explain the customer's need or request
- Include relevant context and details
- Be professional and suitable for product feedback

Return ONLY the description text - no explanations.`,
        placeholder:
          'Describe the customer request (e.g., "need bulk export feature", "integration with Slack")...',
      },
    },
    // Customer request priority/urgency
    {
      id: 'customerRequestPriority',
      title: 'Urgency',
      type: 'dropdown',
      options: [
        { label: 'Not Important (0)', id: '0' },
        { label: 'Important (1)', id: '1' },
      ],
      value: () => '0',
      condition: {
        field: 'operation',
        value: ['linear_create_customer_request', 'linear_update_customer_request'],
      },
    },
    // Link customer request to issue
    {
      id: 'linkedIssueId',
      title: 'Link to Issue',
      type: 'short-input',
      placeholder: 'Enter issue ID to link',
      condition: {
        field: 'operation',
        value: ['linear_create_customer_request', 'linear_update_customer_request'],
      },
    },
    // Customer ID for get/update/delete/merge operations
    {
      id: 'customerIdTarget',
      title: 'Customer ID',
      type: 'short-input',
      placeholder: 'Enter customer ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_get_customer', 'linear_update_customer', 'linear_delete_customer'],
      },
    },
    // Source and target customer IDs for merge
    {
      id: 'sourceCustomerId',
      title: 'Source Customer ID (to merge from)',
      type: 'short-input',
      placeholder: 'Customer ID to merge and delete',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_merge_customers'],
      },
    },
    {
      id: 'targetCustomerId',
      title: 'Target Customer ID (to merge into)',
      type: 'short-input',
      placeholder: 'Customer ID to keep',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_merge_customers'],
      },
    },
    // Customer status/tier fields
    {
      id: 'statusName',
      title: 'Status Name',
      type: 'short-input',
      placeholder: 'Enter status name',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_customer_status'],
      },
    },
    {
      id: 'statusColor',
      title: 'Status Color',
      type: 'short-input',
      placeholder: 'Enter hex color (e.g., #FF0000)',
      required: true,
      condition: {
        field: 'operation',
        value: [
          'linear_create_customer_status',
          'linear_create_customer_tier',
          'linear_create_project_status',
          'linear_create_project_label',
        ],
      },
    },
    {
      id: 'statusId',
      title: 'Status ID',
      type: 'short-input',
      placeholder: 'Enter status ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_update_customer_status', 'linear_delete_customer_status'],
      },
    },
    {
      id: 'tierName',
      title: 'Tier Name',
      type: 'short-input',
      placeholder: 'Enter tier name (e.g., Enterprise, Pro)',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_customer_tier'],
      },
    },
    {
      id: 'tierId',
      title: 'Tier ID',
      type: 'short-input',
      placeholder: 'Enter tier ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_update_customer_tier', 'linear_delete_customer_tier'],
      },
    },
    // Project label fields
    {
      id: 'projectLabelName',
      title: 'Label Name',
      type: 'short-input',
      placeholder: 'Enter project label name',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_project_label', 'linear_update_project_label'],
      },
    },
    {
      id: 'projectLabelDescription',
      title: 'Label Description',
      type: 'long-input',
      placeholder: 'Enter project label description',
      condition: {
        field: 'operation',
        value: ['linear_create_project_label', 'linear_update_project_label'],
      },
    },
    {
      id: 'projectLabelIsGroup',
      title: 'Is Label Group',
      type: 'dropdown',
      options: [
        { label: 'No', id: 'false' },
        { label: 'Yes', id: 'true' },
      ],
      value: () => 'false',
      condition: {
        field: 'operation',
        value: ['linear_create_project_label'],
      },
    },
    {
      id: 'projectLabelParentId',
      title: 'Parent Label ID',
      type: 'short-input',
      placeholder: 'Enter parent label ID (for nested labels)',
      condition: {
        field: 'operation',
        value: ['linear_create_project_label'],
      },
    },
    {
      id: 'projectLabelId',
      title: 'Label ID',
      type: 'short-input',
      placeholder: 'Enter project label ID',
      required: true,
      condition: {
        field: 'operation',
        value: [
          'linear_update_project_label',
          'linear_delete_project_label',
          'linear_add_label_to_project',
          'linear_remove_label_from_project',
        ],
      },
    },
    // Project milestone fields
    {
      id: 'milestoneName',
      title: 'Milestone Name',
      type: 'short-input',
      placeholder: 'Enter milestone name',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_project_milestone'],
      },
    },
    {
      id: 'milestoneDescription',
      title: 'Milestone Description',
      type: 'long-input',
      placeholder: 'Enter milestone description',
      condition: {
        field: 'operation',
        value: ['linear_create_project_milestone', 'linear_update_project_milestone'],
      },
    },
    {
      id: 'milestoneId',
      title: 'Milestone ID',
      type: 'short-input',
      placeholder: 'Enter milestone ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_update_project_milestone', 'linear_delete_project_milestone'],
      },
    },
    {
      id: 'milestoneTargetDate',
      title: 'Target Date',
      type: 'short-input',
      placeholder: 'YYYY-MM-DD',
      condition: {
        field: 'operation',
        value: ['linear_create_project_milestone', 'linear_update_project_milestone'],
      },
      wandConfig: {
        enabled: true,
        prompt: `Generate a date in YYYY-MM-DD format based on the user's description.
Examples:
- "in 2 weeks" -> Calculate 14 days from now
- "end of sprint" -> Calculate based on typical 2-week sprint
- "next milestone" -> Calculate a reasonable next milestone date
- "end of month" -> Last day of current month

Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, no extra text.`,
        placeholder: 'Describe the milestone target date (e.g., "in 2 weeks", "end of month")...',
        generationType: 'timestamp',
      },
    },
    // Project status fields
    {
      id: 'projectStatusName',
      title: 'Status Name',
      type: 'short-input',
      placeholder: 'Enter project status name',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_project_status'],
      },
    },
    {
      id: 'projectStatusType',
      title: 'Status Type',
      type: 'dropdown',
      options: [
        { label: 'Backlog', id: 'backlog' },
        { label: 'Planned', id: 'planned' },
        { label: 'Started', id: 'started' },
        { label: 'Paused', id: 'paused' },
        { label: 'Completed', id: 'completed' },
        { label: 'Canceled', id: 'canceled' },
      ],
      value: () => 'started',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_project_status'],
      },
    },
    {
      id: 'projectStatusPosition',
      title: 'Position',
      type: 'short-input',
      placeholder: 'Enter position (e.g. 0, 1, 2...)',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_create_project_status'],
      },
    },
    {
      id: 'projectStatusId',
      title: 'Status ID',
      type: 'short-input',
      placeholder: 'Enter project status ID',
      required: true,
      condition: {
        field: 'operation',
        value: ['linear_update_project_status', 'linear_delete_project_status'],
      },
    },
    {
      id: 'projectStatusIndefinite',
      title: 'Can Stay Indefinitely',
      type: 'dropdown',
      options: [
        { label: 'No', id: 'false' },
        { label: 'Yes', id: 'true' },
      ],
      value: () => 'false',
      condition: {
        field: 'operation',
        value: ['linear_create_project_status', 'linear_update_project_status'],
      },
    },
    // Project ID for milestone/label operations
    {
      id: 'projectIdForMilestone',
      title: 'Project ID',
      type: 'short-input',
      placeholder: 'Enter project ID',
      required: true,
      condition: {
        field: 'operation',
        value: [
          'linear_create_project_milestone',
          'linear_list_project_milestones',
          'linear_add_label_to_project',
          'linear_remove_label_from_project',
        ],
      },
    },
    // Trigger SubBlocks
    ...getTrigger('linear_issue_created').subBlocks,
    ...getTrigger('linear_issue_updated').subBlocks,
    ...getTrigger('linear_issue_removed').subBlocks,
    ...getTrigger('linear_comment_created').subBlocks,
    ...getTrigger('linear_comment_updated').subBlocks,
    ...getTrigger('linear_project_created').subBlocks,
    ...getTrigger('linear_project_updated').subBlocks,
    ...getTrigger('linear_cycle_created').subBlocks,
    ...getTrigger('linear_cycle_updated').subBlocks,
    ...getTrigger('linear_label_created').subBlocks,
    ...getTrigger('linear_label_updated').subBlocks,
    ...getTrigger('linear_project_update_created').subBlocks,
    ...getTrigger('linear_customer_request_created').subBlocks,
    ...getTrigger('linear_customer_request_updated').subBlocks,
    ...getTrigger('linear_webhook').subBlocks,
  ],
  tools: {
    access: [
      'linear_read_issues',
      'linear_get_issue',
      'linear_create_issue',
      'linear_update_issue',
      'linear_archive_issue',
      'linear_unarchive_issue',
      'linear_delete_issue',
      'linear_search_issues',
      'linear_add_label_to_issue',
      'linear_remove_label_from_issue',
      'linear_create_comment',
      'linear_update_comment',
      'linear_delete_comment',
      'linear_list_comments',
      'linear_list_projects',
      'linear_get_project',
      'linear_create_project',
      'linear_update_project',
      'linear_archive_project',
      'linear_list_users',
      'linear_list_teams',
      'linear_get_viewer',
      'linear_list_labels',
      'linear_create_label',
      'linear_update_label',
      'linear_archive_label',
      'linear_list_workflow_states',
      'linear_create_workflow_state',
      'linear_update_workflow_state',
      'linear_list_cycles',
      'linear_get_cycle',
      'linear_create_cycle',
      'linear_get_active_cycle',
      'linear_create_attachment',
      'linear_list_attachments',
      'linear_update_attachment',
      'linear_delete_attachment',
      'linear_create_issue_relation',
      'linear_list_issue_relations',
      'linear_delete_issue_relation',
      'linear_create_favorite',
      'linear_list_favorites',
      'linear_create_project_update',
      'linear_list_project_updates',
      'linear_list_notifications',
      'linear_update_notification',
      'linear_create_customer',
      'linear_list_customers',
      'linear_create_customer_request',
      'linear_update_customer_request',
      'linear_list_customer_requests',
      'linear_get_customer',
      'linear_update_customer',
      'linear_delete_customer',
      'linear_merge_customers',
      'linear_create_customer_status',
      'linear_update_customer_status',
      'linear_delete_customer_status',
      'linear_list_customer_statuses',
      'linear_create_customer_tier',
      'linear_update_customer_tier',
      'linear_delete_customer_tier',
      'linear_list_customer_tiers',
      'linear_delete_project',
      'linear_create_project_label',
      'linear_update_project_label',
      'linear_delete_project_label',
      'linear_list_project_labels',
      'linear_add_label_to_project',
      'linear_remove_label_from_project',
      'linear_create_project_milestone',
      'linear_update_project_milestone',
      'linear_delete_project_milestone',
      'linear_list_project_milestones',
      'linear_create_project_status',
      'linear_update_project_status',
      'linear_delete_project_status',
      'linear_list_project_statuses',
    ],
    config: {
      tool: (params) => {
        return params.operation || 'linear_read_issues'
      },
      params: (params) => {
        // Use canonical param IDs (raw subBlock IDs are deleted after serialization)
        const effectiveTeamId = params.teamId ? String(params.teamId).trim() : ''
        const effectiveProjectId = params.projectId ? String(params.projectId).trim() : ''

        // Base params that most operations need
        const baseParams: Record<string, any> = {
          oauthCredential: params.oauthCredential,
        }

        // Operation-specific param mapping
        switch (params.operation) {
          case 'linear_read_issues':
            return {
              ...baseParams,
              teamId: effectiveTeamId || undefined,
              projectId: effectiveProjectId || undefined,
              includeArchived: params.includeArchived,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_get_issue':
            if (!params.issueId?.trim()) {
              throw new Error('Issue ID is required.')
            }
            return {
              ...baseParams,
              issueId: params.issueId.trim(),
            }

          case 'linear_create_issue':
            if (!effectiveTeamId) {
              throw new Error('Team ID is required.')
            }
            if (!params.title?.trim()) {
              throw new Error('Title is required.')
            }
            return {
              ...baseParams,
              teamId: effectiveTeamId,
              projectId: effectiveProjectId || undefined,
              title: params.title.trim(),
              description: params.description,
              stateId: params.stateId,
              assigneeId: params.assigneeId,
              priority: params.priority ? Number(params.priority) : undefined,
              estimate: params.estimate ? Number(params.estimate) : undefined,
            }

          case 'linear_update_issue':
            if (!params.issueId?.trim()) {
              throw new Error('Issue ID is required.')
            }
            return {
              ...baseParams,
              issueId: params.issueId.trim(),
              title: params.title,
              description: params.description,
              stateId: params.stateId,
              assigneeId: params.assigneeId,
              priority: params.priority ? Number(params.priority) : undefined,
              estimate: params.estimate ? Number(params.estimate) : undefined,
            }

          case 'linear_archive_issue':
          case 'linear_unarchive_issue':
          case 'linear_delete_issue':
            if (!params.issueId?.trim()) {
              throw new Error('Issue ID is required.')
            }
            return {
              ...baseParams,
              issueId: params.issueId.trim(),
            }

          case 'linear_search_issues':
            if (!params.query?.trim()) {
              throw new Error('Search query is required.')
            }
            return {
              ...baseParams,
              query: params.query.trim(),
              teamId: effectiveTeamId,
              includeArchived: params.includeArchived,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_add_label_to_issue':
          case 'linear_remove_label_from_issue':
            if (!params.issueId?.trim() || !params.labelId?.trim()) {
              throw new Error('Issue ID and Label ID are required.')
            }
            return {
              ...baseParams,
              issueId: params.issueId.trim(),
              labelId: params.labelId.trim(),
            }

          case 'linear_create_comment':
            if (!params.issueId?.trim() || !params.body?.trim()) {
              throw new Error('Issue ID and comment body are required.')
            }
            return {
              ...baseParams,
              issueId: params.issueId.trim(),
              body: params.body.trim(),
            }

          case 'linear_update_comment':
            if (!params.commentId?.trim()) {
              throw new Error('Comment ID is required.')
            }
            return {
              ...baseParams,
              commentId: params.commentId.trim(),
              body: params.body?.trim() || undefined,
            }

          case 'linear_delete_comment':
            if (!params.commentId?.trim()) {
              throw new Error('Comment ID is required.')
            }
            return {
              ...baseParams,
              commentId: params.commentId.trim(),
            }

          case 'linear_list_comments':
            if (!params.issueId?.trim()) {
              throw new Error('Issue ID is required.')
            }
            return {
              ...baseParams,
              issueId: params.issueId.trim(),
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_list_projects':
            return {
              ...baseParams,
              teamId: effectiveTeamId,
              includeArchived: params.includeArchived,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_get_project':
            if (!effectiveProjectId) {
              throw new Error('Project ID is required.')
            }
            return {
              ...baseParams,
              projectId: effectiveProjectId,
            }

          case 'linear_create_project':
            if (!effectiveTeamId || !params.name?.trim()) {
              throw new Error('Team ID and project name are required.')
            }
            return {
              ...baseParams,
              teamId: effectiveTeamId,
              name: params.name.trim(),
              description: params.description,
              leadId: params.leadId,
              startDate: params.startDate,
              targetDate: params.targetDate,
              priority: params.priority ? Number(params.priority) : undefined,
            }

          case 'linear_update_project':
            if (!effectiveProjectId) {
              throw new Error('Project ID is required.')
            }
            return {
              ...baseParams,
              projectId: effectiveProjectId,
              name: params.name,
              description: params.description,
              state: params.projectState,
              leadId: params.leadId,
              targetDate: params.targetDate,
            }

          case 'linear_archive_project':
            if (!effectiveProjectId) {
              throw new Error('Project ID is required.')
            }
            return {
              ...baseParams,
              projectId: effectiveProjectId,
            }

          case 'linear_list_users':
          case 'linear_list_teams':
            return {
              ...baseParams,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_get_viewer':
            return baseParams

          case 'linear_list_labels':
            return {
              ...baseParams,
              teamId: effectiveTeamId,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_create_label':
            if (!params.name?.trim()) {
              throw new Error('Label name is required.')
            }
            return {
              ...baseParams,
              name: params.name.trim(),
              color: params.color,
              teamId: effectiveTeamId,
            }

          case 'linear_update_label':
            if (!params.labelId?.trim()) {
              throw new Error('Label ID is required.')
            }
            return {
              ...baseParams,
              labelId: params.labelId.trim(),
              name: params.name,
              color: params.color,
            }

          case 'linear_archive_label':
            if (!params.labelId?.trim()) {
              throw new Error('Label ID is required.')
            }
            return {
              ...baseParams,
              labelId: params.labelId.trim(),
            }

          case 'linear_list_workflow_states':
            return {
              ...baseParams,
              teamId: effectiveTeamId,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_create_workflow_state':
            if (!effectiveTeamId || !params.name?.trim() || !params.workflowType) {
              throw new Error('Team ID, name, and workflow type are required.')
            }
            return {
              ...baseParams,
              teamId: effectiveTeamId,
              name: params.name.trim(),
              type: params.workflowType,
              color: params.color?.trim() || undefined,
            }

          case 'linear_update_workflow_state':
            if (!params.stateId?.trim()) {
              throw new Error('State ID is required.')
            }
            return {
              ...baseParams,
              stateId: params.stateId.trim(),
              name: params.name,
              color: params.color,
            }

          case 'linear_list_cycles':
            return {
              ...baseParams,
              teamId: effectiveTeamId,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_get_cycle':
            if (!params.cycleId?.trim()) {
              throw new Error('Cycle ID is required.')
            }
            return {
              ...baseParams,
              cycleId: params.cycleId.trim(),
            }

          case 'linear_create_cycle':
            if (!effectiveTeamId || !params.startDate?.trim() || !params.endDate?.trim()) {
              throw new Error('Team ID, start date, and end date are required.')
            }
            return {
              ...baseParams,
              teamId: effectiveTeamId,
              name: params.name?.trim() || undefined,
              startsAt: params.startDate.trim(),
              endsAt: params.endDate.trim(),
            }

          case 'linear_get_active_cycle':
            if (!effectiveTeamId) {
              throw new Error('Team ID is required.')
            }
            return {
              ...baseParams,
              teamId: effectiveTeamId,
            }

          case 'linear_create_attachment': {
            if (!params.issueId?.trim()) {
              throw new Error('Issue ID is required.')
            }
            // Normalize file input - use canonical param 'file' (raw subBlock IDs are deleted after serialization)
            const attachmentFile = normalizeFileInput(params.file, {
              single: true,
              errorMessage: 'Attachment file must be a single file.',
            })
            const attachmentUrl =
              params.url?.trim() ||
              (attachmentFile ? (attachmentFile as { url?: string }).url : undefined)
            if (!attachmentUrl) {
              throw new Error('URL or file is required.')
            }
            return {
              ...baseParams,
              issueId: params.issueId.trim(),
              url: attachmentUrl,
              file: attachmentFile,
              title: params.attachmentTitle,
            }
          }

          case 'linear_list_attachments':
            if (!params.issueId?.trim()) {
              throw new Error('Issue ID is required.')
            }
            return {
              ...baseParams,
              issueId: params.issueId.trim(),
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_update_attachment':
            if (!params.attachmentId?.trim()) {
              throw new Error('Attachment ID is required.')
            }
            return {
              ...baseParams,
              attachmentId: params.attachmentId.trim(),
              title: params.attachmentTitle,
            }

          case 'linear_delete_attachment':
            if (!params.attachmentId?.trim()) {
              throw new Error('Attachment ID is required.')
            }
            return {
              ...baseParams,
              attachmentId: params.attachmentId.trim(),
            }

          case 'linear_create_issue_relation':
            if (!params.issueId?.trim() || !params.relatedIssueId?.trim() || !params.relationType) {
              throw new Error('Issue ID, related issue ID, and relation type are required.')
            }
            return {
              ...baseParams,
              issueId: params.issueId.trim(),
              relatedIssueId: params.relatedIssueId.trim(),
              type: params.relationType,
            }

          case 'linear_list_issue_relations':
            if (!params.issueId?.trim()) {
              throw new Error('Issue ID is required.')
            }
            return {
              ...baseParams,
              issueId: params.issueId.trim(),
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_delete_issue_relation':
            if (!params.relationId?.trim()) {
              throw new Error('Relation ID is required.')
            }
            return {
              ...baseParams,
              relationId: params.relationId.trim(),
            }

          case 'linear_create_favorite':
            if (!params.favoriteTargetId?.trim() || !params.favoriteType) {
              throw new Error('Target ID and favorite type are required.')
            }
            return {
              ...baseParams,
              type: params.favoriteType,
              [`${params.favoriteType}Id`]: params.favoriteTargetId.trim(),
            }

          case 'linear_list_favorites':
            return {
              ...baseParams,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_create_project_update':
            if (!effectiveProjectId || !params.body?.trim()) {
              throw new Error('Project ID and update body are required.')
            }
            return {
              ...baseParams,
              projectId: effectiveProjectId,
              body: params.body.trim(),
              health: params.health,
            }

          case 'linear_list_project_updates':
            if (!effectiveProjectId) {
              throw new Error('Project ID is required.')
            }
            return {
              ...baseParams,
              projectId: effectiveProjectId,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_list_notifications':
            return {
              ...baseParams,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_update_notification':
            if (!params.notificationId?.trim()) {
              throw new Error('Notification ID is required.')
            }
            return {
              ...baseParams,
              notificationId: params.notificationId.trim(),
              readAt: params.markAsRead ? new Date().toISOString() : null,
            }

          case 'linear_create_customer':
            if (!params.customerName?.trim()) {
              throw new Error('Customer name is required.')
            }
            return {
              ...baseParams,
              name: params.customerName.trim(),
              domains: params.customerDomains
                ? params.customerDomains
                    .split(',')
                    .map((d: string) => d.trim())
                    .filter(Boolean)
                : undefined,
            }

          case 'linear_list_customers':
            return {
              ...baseParams,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
              includeArchived: false,
            }

          case 'linear_create_customer_request':
            if (!params.customerId?.trim()) {
              throw new Error('Customer ID is required.')
            }
            return {
              ...baseParams,
              customerId: params.customerId.trim(),
              body: params.requestBody?.trim(),
              priority:
                params.customerRequestPriority !== undefined
                  ? Number(params.customerRequestPriority)
                  : 0,
              issueId: params.linkedIssueId?.trim(),
              projectId: effectiveProjectId || undefined,
            }

          case 'linear_update_customer_request':
            if (!params.customerNeedId?.trim()) {
              throw new Error('Customer Request ID is required.')
            }
            return {
              ...baseParams,
              customerNeedId: params.customerNeedId.trim(),
              customerId: params.customerId?.trim(),
              body: params.requestBody?.trim(),
              priority:
                params.customerRequestPriority !== undefined
                  ? Number(params.customerRequestPriority)
                  : undefined,
              issueId: params.linkedIssueId?.trim(),
              projectId: effectiveProjectId || undefined,
            }

          case 'linear_list_customer_requests':
            return {
              ...baseParams,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
              includeArchived: false,
            }

          // Customer Management Operations
          case 'linear_get_customer':
            if (!params.customerIdTarget?.trim()) {
              throw new Error('Customer ID is required.')
            }
            return {
              ...baseParams,
              customerId: params.customerIdTarget.trim(),
            }

          case 'linear_update_customer':
            if (!params.customerIdTarget?.trim()) {
              throw new Error('Customer ID is required.')
            }
            return {
              ...baseParams,
              customerId: params.customerIdTarget.trim(),
              name: params.customerName?.trim() || undefined,
              domains: params.customerDomains?.trim()
                ? params.customerDomains.split(',').map((d: string) => d.trim())
                : undefined,
              externalIds: params.customerExternalIds?.trim()
                ? params.customerExternalIds.split(',').map((id: string) => id.trim())
                : undefined,
              logoUrl: params.customerLogoUrl?.trim() || undefined,
              ownerId: params.customerOwnerId?.trim() || undefined,
              revenue: params.customerRevenue ? Number(params.customerRevenue) : undefined,
              size: params.customerSize ? Number(params.customerSize) : undefined,
              statusId: params.statusId?.trim() || undefined,
              tierId: params.tierId?.trim() || undefined,
            }

          case 'linear_delete_customer':
            if (!params.customerIdTarget?.trim()) {
              throw new Error('Customer ID is required.')
            }
            return {
              ...baseParams,
              customerId: params.customerIdTarget.trim(),
            }

          case 'linear_merge_customers':
            if (!params.sourceCustomerId?.trim() || !params.targetCustomerId?.trim()) {
              throw new Error('Both source and target customer IDs are required.')
            }
            return {
              ...baseParams,
              sourceCustomerId: params.sourceCustomerId.trim(),
              targetCustomerId: params.targetCustomerId.trim(),
            }

          // Customer Status Operations
          case 'linear_create_customer_status':
            if (!params.statusName?.trim() || !params.statusColor?.trim()) {
              throw new Error('Status name and color are required.')
            }
            return {
              ...baseParams,
              name: params.statusName.trim(),
              color: params.statusColor.trim(),
              description: params.statusDescription?.trim() || undefined,
              displayName: params.statusDisplayName?.trim() || undefined,
            }

          case 'linear_update_customer_status':
            if (!params.statusId?.trim()) {
              throw new Error('Status ID is required.')
            }
            return {
              ...baseParams,
              statusId: params.statusId.trim(),
              name: params.statusName?.trim() || undefined,
              color: params.statusColor?.trim() || undefined,
              description: params.statusDescription?.trim() || undefined,
              displayName: params.statusDisplayName?.trim() || undefined,
            }

          case 'linear_delete_customer_status':
            if (!params.statusId?.trim()) {
              throw new Error('Status ID is required.')
            }
            return {
              ...baseParams,
              statusId: params.statusId.trim(),
            }

          case 'linear_list_customer_statuses':
            return {
              ...baseParams,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          // Customer Tier Operations
          case 'linear_create_customer_tier':
            if (!params.tierName?.trim() || !params.statusColor?.trim()) {
              throw new Error('Tier name and color are required.')
            }
            return {
              ...baseParams,
              name: params.tierName.trim(),
              displayName: params.tierDisplayName?.trim() || params.tierName.trim(),
              color: params.statusColor.trim(),
              description: params.tierDescription?.trim() || undefined,
            }

          case 'linear_update_customer_tier':
            if (!params.tierId?.trim()) {
              throw new Error('Tier ID is required.')
            }
            return {
              ...baseParams,
              tierId: params.tierId.trim(),
              name: params.tierName?.trim() || undefined,
              displayName: params.tierDisplayName?.trim() || undefined,
              color: params.statusColor?.trim() || undefined,
              description: params.tierDescription?.trim() || undefined,
            }

          case 'linear_delete_customer_tier':
            if (!params.tierId?.trim()) {
              throw new Error('Tier ID is required.')
            }
            return {
              ...baseParams,
              tierId: params.tierId.trim(),
            }

          case 'linear_list_customer_tiers':
            return {
              ...baseParams,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          // Project Management Operations
          case 'linear_delete_project':
            if (!effectiveProjectId) {
              throw new Error('Project ID is required.')
            }
            return {
              ...baseParams,
              projectId: effectiveProjectId,
            }

          // Project Label Operations
          case 'linear_create_project_label':
            if (!params.projectLabelName?.trim()) {
              throw new Error('Project label name is required.')
            }
            return {
              ...baseParams,
              name: params.projectLabelName.trim(),
              description: params.projectLabelDescription?.trim() || undefined,
              color: params.statusColor?.trim() || undefined,
              isGroup: params.projectLabelIsGroup === 'true',
              parentId: params.projectLabelParentId?.trim() || undefined,
            }

          case 'linear_update_project_label':
            if (!params.projectLabelId?.trim()) {
              throw new Error('Project label ID is required.')
            }
            return {
              ...baseParams,
              labelId: params.projectLabelId.trim(),
              name: params.projectLabelName?.trim() || undefined,
              description: params.projectLabelDescription?.trim() || undefined,
              color: params.statusColor?.trim() || undefined,
            }

          case 'linear_delete_project_label':
            if (!params.projectLabelId?.trim()) {
              throw new Error('Project label ID is required.')
            }
            return {
              ...baseParams,
              labelId: params.projectLabelId.trim(),
            }

          case 'linear_list_project_labels':
            return {
              ...baseParams,
              projectId: effectiveProjectId || undefined,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          case 'linear_add_label_to_project':
            if (!params.projectIdForMilestone?.trim() || !params.projectLabelId?.trim()) {
              throw new Error('Project ID and label ID are required.')
            }
            return {
              ...baseParams,
              projectId: params.projectIdForMilestone.trim(),
              labelId: params.projectLabelId.trim(),
            }

          case 'linear_remove_label_from_project':
            if (!params.projectIdForMilestone?.trim() || !params.projectLabelId?.trim()) {
              throw new Error('Project ID and label ID are required.')
            }
            return {
              ...baseParams,
              projectId: params.projectIdForMilestone.trim(),
              labelId: params.projectLabelId.trim(),
            }

          // Project Milestone Operations
          case 'linear_create_project_milestone':
            if (!params.projectIdForMilestone?.trim() || !params.milestoneName?.trim()) {
              throw new Error('Project ID and milestone name are required.')
            }
            return {
              ...baseParams,
              projectId: params.projectIdForMilestone.trim(),
              name: params.milestoneName.trim(),
              description: params.milestoneDescription?.trim() || undefined,
              targetDate: params.milestoneTargetDate?.trim() || undefined,
            }

          case 'linear_update_project_milestone':
            if (!params.milestoneId?.trim()) {
              throw new Error('Milestone ID is required.')
            }
            return {
              ...baseParams,
              milestoneId: params.milestoneId.trim(),
              name: params.milestoneName?.trim() || undefined,
              description: params.milestoneDescription?.trim() || undefined,
              targetDate: params.milestoneTargetDate?.trim() || undefined,
            }

          case 'linear_delete_project_milestone':
            if (!params.milestoneId?.trim()) {
              throw new Error('Milestone ID is required.')
            }
            return {
              ...baseParams,
              milestoneId: params.milestoneId.trim(),
            }

          case 'linear_list_project_milestones':
            if (!params.projectIdForMilestone?.trim()) {
              throw new Error('Project ID is required.')
            }
            return {
              ...baseParams,
              projectId: params.projectIdForMilestone.trim(),
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          // Project Status Operations
          case 'linear_create_project_status':
            if (
              !params.projectStatusName?.trim() ||
              !params.projectStatusType?.trim() ||
              !params.statusColor?.trim() ||
              !params.projectStatusPosition?.trim()
            ) {
              throw new Error('Project status name, type, color, and position are required.')
            }
            return {
              ...baseParams,
              name: params.projectStatusName.trim(),
              type: params.projectStatusType.trim(),
              color: params.statusColor.trim(),
              position: Number.parseFloat(params.projectStatusPosition.trim()),
              description: params.projectStatusDescription?.trim() || undefined,
              indefinite: params.projectStatusIndefinite === 'true',
            }

          case 'linear_update_project_status':
            if (!params.projectStatusId?.trim()) {
              throw new Error('Project status ID is required.')
            }
            return {
              ...baseParams,
              statusId: params.projectStatusId.trim(),
              name: params.projectStatusName?.trim() || undefined,
              color: params.statusColor?.trim() || undefined,
              description: params.projectStatusDescription?.trim() || undefined,
              indefinite: params.projectStatusIndefinite
                ? params.projectStatusIndefinite === 'true'
                : undefined,
            }

          case 'linear_delete_project_status':
            if (!params.projectStatusId?.trim()) {
              throw new Error('Project status ID is required.')
            }
            return {
              ...baseParams,
              statusId: params.projectStatusId.trim(),
            }

          case 'linear_list_project_statuses':
            return {
              ...baseParams,
              first: params.first ? Number(params.first) : undefined,
              after: params.after?.trim() || undefined,
            }

          default:
            return baseParams
        }
      },
    },
  },
  inputs: {
    operation: { type: 'string', description: 'Operation to perform' },
    oauthCredential: { type: 'string', description: 'Linear access token' },
    teamId: { type: 'string', description: 'Linear team identifier (canonical param)' },
    projectId: { type: 'string', description: 'Linear project identifier (canonical param)' },
    issueId: { type: 'string', description: 'Issue identifier' },
    title: { type: 'string', description: 'Title' },
    description: { type: 'string', description: 'Description' },
    body: { type: 'string', description: 'Comment or update body' },
    commentId: { type: 'string', description: 'Comment identifier' },
    labelId: { type: 'string', description: 'Label identifier' },
    name: { type: 'string', description: 'Name field' },
    color: { type: 'string', description: 'Color in hex format' },
    stateId: { type: 'string', description: 'Workflow state identifier' },
    assigneeId: { type: 'string', description: 'Assignee user identifier' },
    priority: { type: 'string', description: 'Priority level' },
    customerRequestPriority: { type: 'string', description: 'Customer request urgency level' },
    estimate: { type: 'string', description: 'Estimate points' },
    query: { type: 'string', description: 'Search query' },
    includeArchived: { type: 'boolean', description: 'Include archived items' },
    labelIds: { type: 'array', description: 'Array of label IDs to filter by' },
    createdAfter: {
      type: 'string',
      description: 'Filter issues created after this date (ISO 8601)',
    },
    updatedAfter: {
      type: 'string',
      description: 'Filter issues updated after this date (ISO 8601)',
    },
    orderBy: { type: 'string', description: 'Sort order: createdAt or updatedAt' },
    cycleId: { type: 'string', description: 'Cycle identifier' },
    startDate: { type: 'string', description: 'Start date' },
    endDate: { type: 'string', description: 'End date' },
    targetDate: { type: 'string', description: 'Target date' },
    url: { type: 'string', description: 'URL' },
    file: { type: 'json', description: 'File to attach (canonical param)' },
    attachmentTitle: { type: 'string', description: 'Attachment title' },
    attachmentId: { type: 'string', description: 'Attachment identifier' },
    relationType: { type: 'string', description: 'Relation type' },
    relatedIssueId: { type: 'string', description: 'Related issue identifier' },
    relationId: { type: 'string', description: 'Relation identifier' },
    favoriteType: { type: 'string', description: 'Favorite type' },
    favoriteTargetId: { type: 'string', description: 'Favorite target identifier' },
    health: { type: 'string', description: 'Project health status' },
    notificationId: { type: 'string', description: 'Notification identifier' },
    markAsRead: { type: 'boolean', description: 'Mark as read flag' },
    workflowType: { type: 'string', description: 'Workflow state type' },
    leadId: { type: 'string', description: 'Project lead identifier' },
    projectState: { type: 'string', description: 'Project state' },
    first: { type: 'number', description: 'Number of items to return for pagination' },
    after: { type: 'string', description: 'Cursor for pagination' },
    customerName: { type: 'string', description: 'Customer name' },
    customerDomains: { type: 'string', description: 'Customer domains (comma-separated)' },
    customerId: { type: 'string', description: 'Customer identifier' },
    customerNeedId: { type: 'string', description: 'Customer request identifier' },
    requestBody: { type: 'string', description: 'Customer request description' },
    linkedIssueId: { type: 'string', description: 'Issue ID to link to customer request' },
    // New customer management inputs
    customerIdTarget: { type: 'string', description: 'Customer ID for operations' },
    sourceCustomerId: { type: 'string', description: 'Source customer ID for merge' },
    targetCustomerId: { type: 'string', description: 'Target customer ID for merge' },
    customerExternalIds: { type: 'string', description: 'Customer external IDs (comma-separated)' },
    customerLogoUrl: { type: 'string', description: 'Customer logo URL' },
    customerOwnerId: { type: 'string', description: 'Customer owner user ID' },
    customerRevenue: { type: 'number', description: 'Customer annual revenue' },
    customerSize: { type: 'number', description: 'Customer organization size' },
    // Customer status and tier inputs
    statusId: { type: 'string', description: 'Status identifier' },
    statusName: { type: 'string', description: 'Status name' },
    statusColor: { type: 'string', description: 'Status color in hex format' },
    statusDescription: { type: 'string', description: 'Status description' },
    statusDisplayName: { type: 'string', description: 'Status display name' },
    tierId: { type: 'string', description: 'Tier identifier' },
    tierName: { type: 'string', description: 'Tier name' },
    tierDisplayName: { type: 'string', description: 'Tier display name' },
    tierDescription: { type: 'string', description: 'Tier description' },
    // Project label inputs
    projectLabelId: { type: 'string', description: 'Project label identifier' },
    projectLabelName: { type: 'string', description: 'Project label name' },
    projectLabelDescription: { type: 'string', description: 'Project label description' },
    projectLabelIsGroup: { type: 'string', description: 'Whether label is a group (true/false)' },
    projectLabelParentId: {
      type: 'string',
      description: 'Parent label ID for hierarchical labels',
    },
    // Project milestone inputs
    projectIdForMilestone: { type: 'string', description: 'Project ID for milestone operations' },
    milestoneId: { type: 'string', description: 'Milestone identifier' },
    milestoneName: { type: 'string', description: 'Milestone name' },
    milestoneDescription: { type: 'string', description: 'Milestone description' },
    milestoneTargetDate: { type: 'string', description: 'Milestone target date (YYYY-MM-DD)' },
    // Project status inputs
    projectStatusId: { type: 'string', description: 'Project status identifier' },
    projectStatusName: { type: 'string', description: 'Project status name' },
    projectStatusDescription: { type: 'string', description: 'Project status description' },
    projectStatusIndefinite: {
      type: 'string',
      description: 'Whether status can persist indefinitely (true/false)',
    },
  },
  outputs: {
    // Issue outputs
    issues: { type: 'json', description: 'Issues list' },
    issue: { type: 'json', description: 'Single issue data' },
    issueId: { type: 'string', description: 'Issue ID for operations' },
    // Comment outputs
    comment: { type: 'json', description: 'Comment data' },
    comments: { type: 'json', description: 'Comments list' },
    // Project outputs
    project: { type: 'json', description: 'Project data' },
    projects: { type: 'json', description: 'Projects list' },
    projectId: { type: 'string', description: 'Project ID for operations' },
    // User/Team outputs
    users: { type: 'json', description: 'Users list' },
    teams: { type: 'json', description: 'Teams list' },
    user: { type: 'json', description: 'User data' },
    viewer: { type: 'json', description: 'Current user data' },
    // Label outputs
    label: { type: 'json', description: 'Label data' },
    labels: { type: 'json', description: 'Labels list' },
    labelId: { type: 'string', description: 'Label ID for operations' },
    // Workflow state outputs
    state: { type: 'json', description: 'Workflow state data' },
    states: { type: 'json', description: 'Workflow states list' },
    // Cycle outputs
    cycle: { type: 'json', description: 'Cycle data' },
    cycles: { type: 'json', description: 'Cycles list' },
    // Attachment outputs
    attachment: { type: 'json', description: 'Attachment data' },
    attachments: { type: 'json', description: 'Attachments list' },
    // Relation outputs
    relation: { type: 'json', description: 'Issue relation data' },
    relations: { type: 'json', description: 'Issue relations list' },
    // Favorite outputs
    favorite: { type: 'json', description: 'Favorite data' },
    favorites: { type: 'json', description: 'Favorites list' },
    // Project update outputs
    update: { type: 'json', description: 'Project update data' },
    updates: { type: 'json', description: 'Project updates list' },
    // Notification outputs
    notification: { type: 'json', description: 'Notification data' },
    notifications: { type: 'json', description: 'Notifications list' },
    // Customer outputs
    customer: { type: 'json', description: 'Customer data' },
    customers: { type: 'json', description: 'Customers list' },
    // Customer request outputs
    customerNeed: { type: 'json', description: 'Customer request data' },
    customerNeeds: { type: 'json', description: 'Customer requests list' },
    // Customer status and tier outputs
    customerStatus: { type: 'json', description: 'Customer status data' },
    customerStatuses: { type: 'json', description: 'Customer statuses list' },
    customerTier: { type: 'json', description: 'Customer tier data' },
    customerTiers: { type: 'json', description: 'Customer tiers list' },
    // Project label outputs
    projectLabel: { type: 'json', description: 'Project label data' },
    projectLabels: { type: 'json', description: 'Project labels list' },
    // Project milestone outputs
    projectMilestone: { type: 'json', description: 'Project milestone data' },
    projectMilestones: { type: 'json', description: 'Project milestones list' },
    // Project status outputs
    projectStatus: { type: 'json', description: 'Project status data' },
    projectStatuses: { type: 'json', description: 'Project statuses list' },
    // Pagination
    pageInfo: {
      type: 'json',
      description: 'Pagination information (hasNextPage, endCursor) for list operations',
    },
    // Success indicators
    success: { type: 'boolean', description: 'Operation success status' },
    // Trigger outputs
    action: { type: 'string', description: 'Webhook action (create, update, remove)' },
    type: {
      type: 'string',
      description: 'Entity type from webhook (Issue, Comment, Project, etc.)',
    },
    webhookId: { type: 'string', description: 'Webhook identifier' },
    webhookTimestamp: { type: 'number', description: 'Webhook timestamp in milliseconds' },
    organizationId: { type: 'string', description: 'Organization identifier' },
    createdAt: { type: 'string', description: 'Event creation timestamp' },
    actor: { type: 'json', description: 'User who triggered the event' },
    data: { type: 'json', description: 'Complete entity data from webhook' },
    updatedFrom: {
      type: 'json',
      description: 'Previous values for changed fields (update events only)',
    },
  },
  triggers: {
    enabled: true,
    available: [
      'linear_issue_created',
      'linear_issue_updated',
      'linear_issue_removed',
      'linear_comment_created',
      'linear_comment_updated',
      'linear_project_created',
      'linear_project_updated',
      'linear_cycle_created',
      'linear_cycle_updated',
      'linear_label_created',
      'linear_label_updated',
      'linear_project_update_created',
      'linear_customer_request_created',
      'linear_customer_request_updated',
      'linear_webhook',
    ],
  },
}

/**
 * Linear V2 Block
 *
 * Uses automatic webhook registration via the Linear GraphQL API.
 * Inherits all tool operations from the legacy block.
 */
export const LinearV2Block: BlockConfig<LinearResponse> = {
  ...LinearBlock,
  type: 'linear_v2',
  name: 'Linear',
  hideFromToolbar: false,
  subBlocks: [
    ...LinearBlock.subBlocks.filter(
      (sb) =>
        !sb.id?.startsWith('webhookUrlDisplay') &&
        !sb.id?.startsWith('webhookSecret') &&
        !sb.id?.startsWith('triggerInstructions') &&
        !sb.id?.startsWith('selectedTriggerId')
    ),
    // V2 Trigger SubBlocks
    ...getTrigger('linear_issue_created_v2').subBlocks,
    ...getTrigger('linear_issue_updated_v2').subBlocks,
    ...getTrigger('linear_issue_removed_v2').subBlocks,
    ...getTrigger('linear_comment_created_v2').subBlocks,
    ...getTrigger('linear_comment_updated_v2').subBlocks,
    ...getTrigger('linear_project_created_v2').subBlocks,
    ...getTrigger('linear_project_updated_v2').subBlocks,
    ...getTrigger('linear_cycle_created_v2').subBlocks,
    ...getTrigger('linear_cycle_updated_v2').subBlocks,
    ...getTrigger('linear_label_created_v2').subBlocks,
    ...getTrigger('linear_label_updated_v2').subBlocks,
    ...getTrigger('linear_project_update_created_v2').subBlocks,
    ...getTrigger('linear_customer_request_created_v2').subBlocks,
    ...getTrigger('linear_customer_request_updated_v2').subBlocks,
    ...getTrigger('linear_webhook_v2').subBlocks,
  ],
  triggers: {
    enabled: true,
    available: [
      'linear_issue_created_v2',
      'linear_issue_updated_v2',
      'linear_issue_removed_v2',
      'linear_comment_created_v2',
      'linear_comment_updated_v2',
      'linear_project_created_v2',
      'linear_project_updated_v2',
      'linear_cycle_created_v2',
      'linear_cycle_updated_v2',
      'linear_label_created_v2',
      'linear_label_updated_v2',
      'linear_project_update_created_v2',
      'linear_customer_request_created_v2',
      'linear_customer_request_updated_v2',
      'linear_webhook_v2',
    ],
  },
}

export const LinearBlockMeta = {
  tags: ['project-management', 'ticketing'],
  url: 'https://linear.app',
  templates: [
    {
      icon: LinearIcon,
      title: 'Linear knowledge search',
      prompt:
        'Create a knowledge base connected to my Linear workspace so all issues, comments, project updates, and decisions are automatically synced and searchable. Then build an agent I can ask things like "why did we deprioritize the mobile app?" or "what was the root cause of the checkout bug?" and get answers traced back to specific issues.',
      modules: ['knowledge-base', 'agent'],
      category: 'engineering',
      tags: ['engineering', 'research', 'product'],
    },
    {
      icon: DevinIcon,
      title: 'Linear ticket to Devin pipeline',
      prompt:
        'Create a workflow that fires when a Linear ticket gets the "devin" label, transforms the ticket description, acceptance criteria, and linked context into a Devin prompt, creates a session, and posts the session link plus an estimated completion window back on the ticket.',
      modules: ['agent', 'workflows'],
      category: 'engineering',
      tags: ['engineering', 'agentic', 'automation'],
      alsoIntegrations: ['devin'],
    },
    {
      icon: SlackIcon,
      title: 'Meeting notes to action items',
      prompt:
        'Create a workflow that takes meeting notes or a transcript, extracts action items with owners and due dates, creates tasks in Linear or Asana for each one, and posts a summary to the relevant Slack channel.',
      modules: ['agent', 'workflows'],
      category: 'productivity',
      tags: ['team', 'automation'],
      alsoIntegrations: ['asana', 'slack'],
    },

    {
      icon: LinearIcon,
      title: 'Linear issue updates in Slack',
      prompt:
        'Build a workflow that monitors Linear for new issues, assignments, and completions, and posts a formatted Slack message for each event so your team is always in the loop.',
      modules: ['agent', 'workflows'],
      category: 'productivity',
      tags: ['automation', 'communication'],
      featured: true,
      alsoIntegrations: ['slack'],
    },
    {
      icon: LinearIcon,
      title: 'Bug report to Linear issue',
      prompt:
        'Build a workflow that watches a Slack channel for bug reports, extracts the steps to reproduce and severity with an agent, creates a labeled Linear issue in the right team, and replies in-thread with the issue link.',
      modules: ['agent', 'workflows'],
      category: 'engineering',
      tags: ['engineering', 'automation'],
      alsoIntegrations: ['slack'],
    },
    {
      icon: LinearIcon,
      title: 'Linear triage labeler',
      prompt:
        'Create a workflow that on a newly created Linear issue reads the title and description, adds the right labels for type and priority, assigns it to the correct team based on the area, and comments a triage summary.',
      modules: ['agent', 'workflows'],
      category: 'engineering',
      tags: ['engineering', 'automation', 'project-management'],
    },
    {
      icon: LinearIcon,
      title: 'Linear sprint review digest',
      prompt:
        'Build a scheduled weekly workflow that searches Linear for issues completed and still open in the active cycle, summarizes progress and blockers with an agent, logs velocity to a table, and posts a sprint review digest to Slack.',
      modules: ['scheduled', 'tables', 'agent', 'workflows'],
      category: 'engineering',
      tags: ['engineering', 'reporting', 'project-management'],
      alsoIntegrations: ['slack'],
    },
  ],
  skills: [
    {
      name: 'create-triaged-issue',
      description:
        'Create a Linear issue in the right team with a clear title, description, priority, and labels.',
      content:
        '# Create Triaged Issue\n\nTurn a request or bug report into a well-formed Linear issue.\n\n## Steps\n1. If the team is unknown, List Teams and pick the team that owns the area.\n2. Write a concise title and a description with context, steps to reproduce, and acceptance criteria.\n3. Create Issue with the team ID, title, description, and a priority that matches severity.\n4. Optionally Add Label to Issue for type and area labels using IDs from List Labels.\n\n## Output\nThe created issue ID, its identifier and URL, and the team, priority, and labels applied.',
    },
    {
      name: 'triage-new-issue',
      description:
        'Read a Linear issue, apply type and priority labels, set assignee and state, and comment a triage summary.',
      content:
        '# Triage New Issue\n\nTriage an incoming Linear issue so it lands in the right place with the right metadata.\n\n## Steps\n1. Get Issue to read the title and description.\n2. Determine the issue type, priority, and owning area from the content.\n3. Add Label to Issue for type and priority, and Update Issue to set the assignee, state, and priority.\n4. Create Comment with a short triage summary explaining the classification and next step.\n\n## Output\nThe issue identifier, the labels added, the assignee and state set, and the triage comment posted.',
    },
    {
      name: 'summarize-active-cycle',
      description:
        'Pull completed and open issues in the active cycle and produce a sprint progress digest.',
      content:
        '# Summarize Active Cycle\n\nProduce a sprint review digest from the current Linear cycle.\n\n## Steps\n1. Get Active Cycle for the team to find the current cycle.\n2. Read Issues or Search Issues scoped to that cycle, separating completed from still-open issues.\n3. Compute counts, completion percentage, and call out blocked or at-risk issues by priority.\n4. Summarize progress, blockers, and what is likely to slip.\n\n## Output\nA digest with completed vs open counts, completion percentage, a list of blockers, and a short narrative of cycle health.',
    },
    {
      name: 'post-project-update',
      description:
        'Assess a Linear project and post a project update with a health status and progress summary.',
      content:
        '# Post Project Update\n\nWrite a stakeholder-ready project update in Linear.\n\n## Steps\n1. Get Project to read its current state, target date, and lead.\n2. Read Issues for the project to gauge progress against the milestone or target date.\n3. Decide a health status of on track, at risk, or off track based on remaining work and timeline.\n4. Create Project Update with the chosen health and a concise body covering progress, risks, and next steps.\n\n## Output\nConfirmation of the posted update, the health status chosen, and the update body.',
    },
  ],
} as const satisfies BlockMeta
