{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "ef4b2323-2cdd-4f5e-98af-2400f64d15c3",
      "name": "Sticky Note - Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        9120,
        2816
      ],
      "parameters": {
        "width": 480,
        "height": 700,
        "content": "## Start an AI Coding Agent (Claude Code, Gemini or Codex) from Linear Issues with CloudCLI\n\n### When a Linear issue is created, this workflow sends it to a CloudCLI cloud dev environment where an AI agent handles the implementation, then posts the results and a live session link back to Linear for review.\n\n### How it works\n1. A Linear webhook fires when an issue event occurs.\n2. The workflow filters for newly created issues only.\n3. The issue title and description are composed into an agent prompt.\n4. CloudCLI fetches the target environment details (including its live access URL).\n5. The AI coding agent (Claude Code, Cursor CLI, or Codex) runs the task.\n6. The agent's output, VS Code/Cursor deep links, SSH resume command, and environment URL are posted back to Linear as a comment.\n\n### Set up steps\n1. Install the CloudCLI verified community node from the n8n nodes panel.\n2. Connect your Linear account credentials.\n3. Connect your CloudCLI API credentials (get your key at [cloudcli.ai](https://cloudcli.ai)).\n4. Select which CloudCLI environment to use in the \"Get Environment Details\" node.\n5. Customize the prompt template in \"Compose Agent Prompt\" to fit your codebase.\n\n### Requirements\n- Linear account\n- CloudCLI account with API key ([cloudcli.ai](https://cloudcli.ai))\n- A running CloudCLI environment with your repo cloned\n\n### Need Help?\n[n8n Discord](https://discord.com/invite/XPKeKXeB7d) | [n8n Forum](https://community.n8n.io/) | [CloudCLI Docs](https://developer.cloudcli.ai)"
      },
      "typeVersion": 1
    },
    {
      "id": "2e788329-1b2f-47d5-a813-56612580bae4",
      "name": "Sticky Note - Step 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        9664,
        2976
      ],
      "parameters": {
        "color": 7,
        "width": 500,
        "height": 360,
        "content": "## 1. Capture New Linear Issues\n\nThe Linear Trigger fires on all issue events (create and update). The IF node filters for newly created issues only by checking that the action equals \"create\".\n\nThis prevents the agent from re-running every time someone updates the issue."
      },
      "typeVersion": 1
    },
    {
      "id": "0b304b18-5ca4-4512-aa9a-b54eff825c8d",
      "name": "Sticky Note - Step 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        10208,
        2976
      ],
      "parameters": {
        "color": 7,
        "width": 300,
        "height": 360,
        "content": "## 2. Compose Agent Prompt\n\nThe issue title and description are formatted into a prompt for the AI agent. Customize this to include your project's coding standards, conventions, or any context the agent should know."
      },
      "typeVersion": 1
    },
    {
      "id": "67968123-acc7-4d32-8d58-db7496e2eb89",
      "name": "Sticky Note - Step 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        10544,
        2976
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 360,
        "content": "## 3. Get Environment & Run Agent\n[CloudCLI Docs](https://developer.cloudcli.ai)\n\nThe Get Environment node fetches your environment's details including its live access URL. The agent then runs the task inside that environment's isolated container.\n\nSelect your target environment in the \"Get Environment Details\" node. The agent auto-detects the project path from the environment name."
      },
      "typeVersion": 1
    },
    {
      "id": "c75da46c-6c6b-4f15-b164-b13ef3840666",
      "name": "Sticky Note - Step 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        11152,
        2976
      ],
      "parameters": {
        "color": 7,
        "width": 560,
        "height": 360,
        "content": "## 4. Post Results to Linear\n\nThe agent's result text, session duration, cost, and multiple ways to continue the session are extracted and posted back to the Linear issue as a comment:\n\n- **Web UI** link to the CloudCLI dashboard\n- **VS Code / Cursor** deep links that open the environment directly via Remote SSH\n- **SSH command** with `claude -r` to resume the agent session from terminal\n\nReviewers pick whichever entry point they prefer and continue where the agent left off."
      },
      "typeVersion": 1
    },
    {
      "id": "4f61c581-35b2-463a-b781-4ae3df824b58",
      "name": "Sticky Note - Community Node",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        9120,
        3696
      ],
      "parameters": {
        "color": 5,
        "width": 480,
        "height": 140,
        "content": "### Community Node\nThis workflow uses the **CloudCLI** verified community node (`@cloudcli-ai/n8n-nodes-cloud-cli`). Install it from the n8n nodes panel. [Learn more](https://docs.n8n.io/integrations/community-nodes/installation/verified-install/)."
      },
      "typeVersion": 1
    },
    {
      "id": "d21cfed3-0fe5-441e-9d56-b6969546fce6",
      "name": "Linear Trigger",
      "type": "n8n-nodes-base.linearTrigger",
      "position": [
        9728,
        3280
      ],
      "parameters": {
        "resources": [
          "issue"
        ]
      },
      "credentials": {},
      "typeVersion": 1
    },
    {
      "id": "a2121813-5861-451d-8cc5-7e9fd828971d",
      "name": "Is New Issue?",
      "type": "n8n-nodes-base.if",
      "position": [
        9984,
        3280
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "condition-action-create",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.action }}",
              "rightValue": "create"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "6d0ac61b-467b-4238-a29a-62024374a41a",
      "name": "Compose Agent Prompt",
      "type": "n8n-nodes-base.set",
      "position": [
        10272,
        3280
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "field-prompt",
              "name": "agentPrompt",
              "type": "string",
              "value": "=You are working on Linear issue {{ $json.data.identifier }}.\n\nTask: {{ $json.data.title }}\n\nDetails:\n{{ $json.data.description }}\n\nImplement the changes described above. Write clean, well-documented code. When finished, provide a summary of what was changed and any notes for the reviewer."
            },
            {
              "id": "field-issue-id",
              "name": "issueId",
              "type": "string",
              "value": "={{ $json.data.id }}"
            },
            {
              "id": "field-issue-identifier",
              "name": "issueIdentifier",
              "type": "string",
              "value": "={{ $json.data.identifier }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e5b1491d-58f1-4d43-b3e2-a6df5afbb21a",
      "name": "Get Environment Details",
      "type": "@cloudcli-ai/n8n-nodes-cloud-cli.cloudCli",
      "position": [
        10608,
        3280
      ],
      "parameters": {
        "operation": "get",
        "environmentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 1
    },
    {
      "id": "829f92d2-91bd-45fa-93b8-2b5edd7344e4",
      "name": "Run AI Coding Agent",
      "type": "@cloudcli-ai/n8n-nodes-cloud-cli.cloudCli",
      "position": [
        10880,
        3280
      ],
      "parameters": {
        "message": "={{ $('Compose Agent Prompt').item.json.agentPrompt }}",
        "resource": "agent",
        "additionalOptions": {},
        "agentEnvironmentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Get Environment Details').item.json.id }}"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "7cffb369-621a-48af-9107-3603e3f77fca",
      "name": "Extract Agent Result",
      "type": "n8n-nodes-base.set",
      "position": [
        11200,
        3280
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "field-result",
              "name": "agentResult",
              "type": "string",
              "value": "={{ $json.events.find(e => e.type === 'claude-response' && e.data && e.data.type === 'result').data.result }}"
            },
            {
              "id": "field-session-id",
              "name": "sessionId",
              "type": "string",
              "value": "={{ $json.events.find(e => e.type === 'session-created').sessionId }}"
            },
            {
              "id": "field-access-url",
              "name": "accessUrl",
              "type": "string",
              "value": "={{ $('Get Environment Details').item.json.access_url }}"
            },
            {
              "id": "field-vscode-url",
              "name": "vscodeUrl",
              "type": "string",
              "value": "=vscode://vscode-remote/ssh-remote+{{ $('Get Environment Details').item.json.subdomain }}@ssh.cloudcli.ai/workspace/{{ $('Get Environment Details').item.json.name.replace(/[^a-zA-Z0-9-]/g, '') }}?windowId=_blank"
            },
            {
              "id": "field-cursor-url",
              "name": "cursorUrl",
              "type": "string",
              "value": "=cursor://vscode-remote/ssh-remote+{{ $('Get Environment Details').item.json.subdomain }}@ssh.cloudcli.ai/workspace/{{ $('Get Environment Details').item.json.name.replace(/[^a-zA-Z0-9-]/g, '') }}?windowId=_blank"
            },
            {
              "id": "field-issue-id",
              "name": "issueId",
              "type": "string",
              "value": "={{ $('Compose Agent Prompt').item.json.issueId }}"
            },
            {
              "id": "field-issue-identifier",
              "name": "issueIdentifier",
              "type": "string",
              "value": "={{ $('Compose Agent Prompt').item.json.issueIdentifier }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "fa4c475d-7023-431a-bb8a-f7a412affa76",
      "name": "Post Results to Linear",
      "type": "n8n-nodes-base.linear",
      "position": [
        11488,
        3280
      ],
      "parameters": {
        "comment": "=**CloudCLI agent completed work on {{ $json.issueIdentifier }}**\n\n{{ $json.agentResult }}\n\n---\n\n**Continue this session:**\n- Web UI: [Open in CloudCLI]({{ $json.accessUrl }})\n- VS Code: [Open in VS Code]({{ $json.vscodeUrl }})\n- Cursor: [Open in Cursor]({{ $json.cursorUrl }})\n- SSH + resume: `ssh {{ $('Get Environment Details').item.json.subdomain }}@ssh.cloudcli.ai` then run `claude -r` to resume session `{{ $json.sessionId }}`\n\n*Automated by n8n + CloudCLI*",
        "issueId": "={{ $json.issueId }}",
        "resource": "comment",
        "additionalFields": {}
      },
      "credentials": {},
      "typeVersion": 1.1
    }
  ],
  "connections": {
    "Is New Issue?": {
      "main": [
        [
          {
            "node": "Compose Agent Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Linear Trigger": {
      "main": [
        [
          {
            "node": "Is New Issue?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run AI Coding Agent": {
      "main": [
        [
          {
            "node": "Extract Agent Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compose Agent Prompt": {
      "main": [
        [
          {
            "node": "Get Environment Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Agent Result": {
      "main": [
        [
          {
            "node": "Post Results to Linear",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Environment Details": {
      "main": [
        [
          {
            "node": "Run AI Coding Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}