codecloud
HomeDocsBlog
All posts

How to auto-generate an implementation plan for your Linear or Jira tickets

January 19, 20254 min read

Before writing code, it helps to have a plan. Codecloud's plan mode uses OpenCode's plan mode to generate implementation plans. This isn't a generic plan based on just your prompt, but an actual plan based on analyzing your codebase in context of your prompt.

This post covers how to use the codecloud API to generate plans from tickets and deliver them via webhook to Slack, Linear, Jira, or any other system.

How plan mode works

When you call the codecloud API with "mode": "plan", the agent clones your repository, analyzes the codebase, and returns a detailed implementation plan. No code changes are made. No PR is created.

The plan typically includes:

  • Which files need to be modified or created
  • What changes to make in each file
  • Existing patterns in the codebase to follow
  • Potential edge cases or considerations
  • Suggested order of implementation

Because the agent has access to the full codebase, the plan is grounded in reality. It references actual file paths, existing components, and established conventions in your project.

Basic API call

A minimal request to generate a plan:

curl -X POST https://codecloud.dev/api/v1/agents \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "repo": "your-org/your-repo",
    "prompt": "Add user avatar upload to the settings page",
    "mode": "plan"
  }'

The response includes a run ID. Poll /api/v1/agents/run?id=RUN_ID until the status is completed, then read the plan field.

Using webhooks

Polling works, but webhooks are cleaner. Add a webhook_url to receive the plan when it's ready:

{
  "repo": "your-org/your-repo",
  "prompt": "Add user avatar upload to the settings page",
  "mode": "plan",
  "webhook_url": "https://your-server.com/webhook/plan-ready"
}

When the plan is complete, codecloud sends a POST request to your webhook URL with the full run details, including the plan text.

Use case: Attach plans to Linear tickets

A common pattern: when a ticket is created in Linear, generate a plan and post it as a comment on the ticket. Engineers see the plan before starting work.

The flow:

  1. Linear webhook fires on ticket creation
  2. Your server calls codecloud with the ticket description and a webhook URL
  3. codecloud generates the plan and sends it to your webhook
  4. Your webhook handler posts the plan as a comment on the Linear ticket

The webhook payload from codecloud includes the run ID, which you can map back to the original ticket. Store the mapping when you create the run, then use it when the webhook arrives.

// Webhook handler pseudocode
app.post('/webhook/plan-ready', async (req, res) => {
  const { id, status, plan } = req.body;

  if (status === 'completed' && plan) {
    const ticketId = await getTicketIdForRun(id);
    await linearClient.createComment({
      issueId: ticketId,
      body: `## Implementation Plan\n\n${plan}`
    });
  }

  res.status(200).send('OK');
});

Use case: Slack bot for planning

Another pattern: a Slack bot that generates plans on demand. A user pastes a ticket description or feature request, and the bot responds with an implementation plan.

// Slack command handler
app.post('/slack/plan', async (req, res) => {
  const { text, channel_id, response_url } = req.body;

  // Acknowledge immediately
  res.status(200).send('Generating plan...');

  // Create codecloud run with Slack webhook
  await fetch('https://codecloud.dev/api/v1/agents', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      repo: 'your-org/your-repo',
      prompt: text,
      mode: 'plan',
      webhook_url: `https://your-server.com/slack-plan-callback?channel=${channel_id}`
    })
  });
});

// Callback handler posts plan to Slack
app.post('/slack-plan-callback', async (req, res) => {
  const { plan, status } = req.body;
  const channel = req.query.channel;

  if (status === 'completed' && plan) {
    await slackClient.chat.postMessage({
      channel,
      text: `*Implementation Plan*\n\n${plan}`
    });
  }

  res.status(200).send('OK');
});

Use case: Feed plans to local agents

Plans from codecloud can be used as input for other tools. One pattern: generate a plan in the cloud, then pass it to a local coding agent (like Claude Code or Cursor) to execute.

This separates planning from execution. The cloud agent handles the analysis—which can be time-consuming on large codebases—while the local agent handles the implementation with full access to your development environment.

# Generate plan via API
PLAN=$(curl -s -X POST https://codecloud.dev/api/v1/agents \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "repo": "your-org/your-repo",
    "prompt": "Add rate limiting to the API endpoints",
    "mode": "plan"
  }' | jq -r '.id')

# Poll until complete, then extract plan
# ... (polling logic)

# Pass plan to local agent
claude-code --prompt "Execute this implementation plan: $PLAN_TEXT"

Plan quality

Plan quality depends on the same factors as execution quality: clear prompts with sufficient context. A ticket that says "fix the bug" produces a vague plan. A ticket that describes the expected behavior, current behavior, and relevant area of the codebase produces a detailed plan.

Plans are also affected by model choice. More capable models produce more thorough analysis. For complex features, using a stronger model for planning (even if you use a faster model for execution) can be worth the additional cost.

When to use plan mode

Plan mode is useful when:

  • You want to review the approach before any code is written
  • Engineers need context before starting implementation
  • You're evaluating whether a ticket is well-specified enough
  • You want to estimate complexity before committing to a task
  • You're using a local agent that benefits from pre-computed plans

For straightforward tasks where you trust the agent to execute correctly, skip plan mode and use "mode": "execute" (the default) with "auto_create_pr": true.


For questions or feedback, use the support portal. For full API details, see the API documentation.