Template · Marketing

Weekly competitor watch

Each Monday, Claude Code visits every competitor’s homepage, pricing page, changelog and blog, compares them with last week’s snapshot in your folder, and saves the new one. A condition step posts the digest to Slack only when something actually changed, so a quiet week is a quiet channel.

Download .json

Schedule0 7 * * 1Weekly competitor watchMon · 07:00
Pipeline
  1. Last snapshot Shell
  2. Check competitors Claude Code · Sonnet
  3. Anything changed? Condition
  4. Post to Slack Shell
Slack#marketingLedgerly cut its Team plan to $39 and shipped an Xero syncPosted
The pipeline

What each step does

  1. Last snapshot

    Shell

    Reads last week’s snapshot from the folder.

  2. Check competitors

    Claude Code · Sonnet

    Visits every competitor’s site, pricing, changelog and blog, saves a new snapshot and writes a digest of what changed.

  3. Anything changed?

    Condition

    Skips the post when nothing changed.

  4. Post to Slack

    Shell

    Posts the digest to Slack.

Set it up

From copy to first run

  1. Copy the pipeline JSON with the button above.
  2. In Jimothy, open Pipelines → New pipeline, paste it under “Or import a pipeline JSON” and click Import.
  3. Under Workspace, choose an empty folder to keep the weekly snapshots in.
  4. Fill in the variables below under Pipeline settings → Variables.
  5. Triggers → Add trigger → Schedule, cron 0 7 * * 1 (Mondays at 07:00).

Snapshots are saved in competitor-watch/ inside the folder. The first run only records a baseline, so the first digest arrives the week after.

Variables

What to fill in

The prompts and commands read these as {{vars.<name>}}. The examples are placeholders: replace them with your own.

VariableWhat to put in itExample
productWhat you sell, so the digest can say why a change matters.Acme, a reporting tool for finance teams
competitorsOne competitor per line: name and homepage.Ledgerly — https://ledgerly.example CloseKit — https://closekit.example
slackWebhookUrlA Slack incoming webhook for the channel that gets the digest.—
Show the pipeline JSON
{
  "jimothyPipeline": 1,
  "name": "Weekly competitor watch",
  "description": "Checks competitors’ sites, pricing and changelogs, compares with last week’s snapshot, and posts what changed to Slack.",
  "icon": "sparkles",
  "color": "#f472b6",
  "repo": {
    "mode": "inplace",
    "localPath": ""
  },
  "concurrency": 1,
  "variables": {
    "product": "Acme, a reporting tool for finance teams",
    "competitors": "Ledgerly — https://ledgerly.example\nCloseKit — https://closekit.example",
    "slackWebhookUrl": ""
  },
  "steps": [
    {
      "id": "last",
      "name": "Last snapshot",
      "type": "shell",
      "description": "Reads last week’s snapshot from the folder.",
      "timeoutMinutes": 1,
      "command": "cat competitor-watch/latest.md 2>/dev/null || echo \"(no previous snapshot: this is the first run)\""
    },
    {
      "id": "research",
      "name": "Check competitors",
      "type": "agent",
      "description": "Visits every competitor’s site, pricing, changelog and blog, saves a new snapshot and writes a digest of what changed.",
      "harnessId": "claude-code",
      "model": "sonnet",
      "dependsOn": [
        "last"
      ],
      "timeoutMinutes": 30,
      "prompt": "We make {{vars.product}}. Our competitors:\n{{vars.competitors}}\n\nFor each competitor, visit their homepage, pricing page, changelog or release notes, and blog or newsroom. Record plans and prices, headline positioning, features shipped in the last few weeks, and announcements.\n\nLast week's snapshot:\n{{steps.last.output | truncate:15000}}\n\n1. Write this week's full snapshot to competitor-watch/latest.md (overwrite it) and a copy to competitor-watch/<today's date as YYYY-MM-DD>.md, creating the folder if needed. Use one \"## <competitor>\" section each.\n2. Compare it with last week's snapshot. Your final answer is a Slack digest of what changed, using *bold* competitor names and - bullets, with a one-line \"Why it matters\" for us under each change and the URL you saw it on. Ignore wording tweaks and layout changes.\n\nIf this is the first run or nothing meaningful changed, your final answer is exactly NO_CHANGES and nothing else."
    },
    {
      "id": "changed",
      "name": "Anything changed?",
      "type": "condition",
      "description": "Skips the post when nothing changed.",
      "dependsOn": [
        "research"
      ],
      "condition": {
        "match": "all",
        "rules": [
          {
            "value": "{{steps.research.output}}",
            "op": "not_contains",
            "compare": "NO_CHANGES"
          }
        ]
      }
    },
    {
      "id": "post",
      "name": "Post to Slack",
      "type": "shell",
      "description": "Posts the digest to Slack.",
      "dependsOn": [
        "changed"
      ],
      "timeoutMinutes": 2,
      "command": "printf '{\"text\":%s}' {{steps.research.output | json}} | curl -fsS -X POST -H 'Content-Type: application/json' --data @- {{vars.slackWebhookUrl}}"
    }
  ]
}