Fix --tier1-count CLI flag + set Stage on task creation + update docs
- Fix --tier-1 -> --tier1-count in create_task_set.py and create-task-set.md skill - Set initial Stage field when creating tasks (run_cora for most, draft for PR) - Add Quick Reference section to clickup_runner README with stage tables - Add Stage field docs to clickup-task-creation.md - Remove stale xlsx_urls tests from test_claude_runner.py Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>clickup-runner
parent
e4c7bc8e02
commit
e0388b1f6f
|
|
@ -16,6 +16,44 @@ export CLICKUP_SPACE_ID="..."
|
|||
uv run python -m clickup_runner
|
||||
```
|
||||
|
||||
## Quick Reference: Running a Task
|
||||
|
||||
To delegate a task to the runner, it needs **all three fields** set or it will be skipped:
|
||||
|
||||
1. **Work Category** -- which task type (dropdown)
|
||||
2. **Stage** -- which pipeline step to run (dropdown)
|
||||
3. **Delegate to Claude** -- checked (checkbox)
|
||||
|
||||
Plus the task must have a **due date <= today** and be in an **"Overall" list**.
|
||||
|
||||
### Initial Stage by Task Type
|
||||
|
||||
| Task Type | First Stage | What it does | Full pipeline |
|
||||
|-----------|-------------|--------------|---------------|
|
||||
| Content Creation | `run_cora` | Submits Cora analysis | `run_cora` -> `outline` -> `draft` |
|
||||
| On Page Optimization | `run_cora` | Submits Cora analysis | `run_cora` -> `outline` -> `draft` -> `hidden div` |
|
||||
| Press Release | `draft` | Writes full PR + schemas | `draft` (single stage) |
|
||||
| Link Building | `run_cora` | Submits Cora analysis | `run_cora` -> `build` |
|
||||
|
||||
### After Each Stage
|
||||
|
||||
The runner **unchecks** "Delegate to Claude" and sets status to **Review** so you can check the output. To continue to the next stage, review the output, then re-check "Delegate to Claude". The Stage field is advanced automatically.
|
||||
|
||||
### Required Custom Fields by Task Type
|
||||
|
||||
| Task Type | Required Fields |
|
||||
|-----------|----------------|
|
||||
| Content Creation | Keyword, IMSURL (for run_cora) |
|
||||
| On Page Optimization | Keyword, IMSURL (for run_cora) |
|
||||
| Press Release | Keyword, IMSURL |
|
||||
| Link Building | Keyword, IMSURL, CLIFlags (`--tier1-count N`) |
|
||||
|
||||
### If Something Goes Wrong
|
||||
|
||||
The runner sets the **Error** checkbox, posts a comment explaining what failed and how to fix it, unchecks "Delegate to Claude", and sets status to **Review**. Fix the issue, then re-check "Delegate to Claude" to retry.
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
1. Every 720 seconds, polls all "Overall" lists in the ClickUp space
|
||||
|
|
|
|||
|
|
@ -5,7 +5,8 @@
|
|||
```bash
|
||||
uv run python scripts/create_clickup_task.py --name "LINKS - keyword" --client "Client Name" \
|
||||
--category "Link Building" --due-date 2026-03-18 --tag mar26 --time-estimate 2h \
|
||||
--field "Keyword=keyword" --field "IMSURL=https://example.com" --field "LB Method=Cora Backlinks"
|
||||
--field "Keyword=keyword" --field "IMSURL=https://example.com" --field "LB Method=Cora Backlinks" \
|
||||
--dependency TASK_ID
|
||||
```
|
||||
|
||||
## Defaults
|
||||
|
|
@ -20,11 +21,23 @@ uv run python scripts/create_clickup_task.py --name "LINKS - keyword" --client "
|
|||
|
||||
Any field can be set via `--field "Name=Value"`. Dropdowns are auto-resolved by name (case-insensitive).
|
||||
|
||||
## Stage Field (Required for ClickUp Runner)
|
||||
|
||||
Every task must have a **Stage** set or the runner will skip it. Set Stage to the first stage for the task type:
|
||||
|
||||
| Task Type | Initial Stage |
|
||||
|-----------|---------------|
|
||||
| Content Creation | `run_cora` |
|
||||
| On Page Optimization | `run_cora` |
|
||||
| Press Release | `draft` |
|
||||
| Link Building | `run_cora` |
|
||||
|
||||
## Task Types
|
||||
|
||||
### Link Building
|
||||
- **Prefix**: `LINKS - {keyword}`
|
||||
- **Work Category**: "Link Building"
|
||||
- **Stage**: `run_cora`
|
||||
- **Required fields**: Keyword, IMSURL
|
||||
- **LB Method**: default "Cora Backlinks"
|
||||
- **CLIFlags**: only add `--tier1-count N` when count is specified
|
||||
|
|
@ -35,6 +48,7 @@ Any field can be set via `--field "Name=Value"`. Dropdowns are auto-resolved by
|
|||
### On Page Optimization
|
||||
- **Prefix**: `OPT - {keyword}`
|
||||
- **Work Category**: "On Page Optimization"
|
||||
- **Stage**: `run_cora`
|
||||
- **Required fields**: Keyword, IMSURL
|
||||
- **time estimate**: 3h
|
||||
-
|
||||
|
|
@ -42,13 +56,15 @@ Any field can be set via `--field "Name=Value"`. Dropdowns are auto-resolved by
|
|||
### Content Creation
|
||||
- **Prefix**: `CREATE - {keyword}`
|
||||
- **Work Category**: "Content Creation"
|
||||
- **Stage**: `run_cora`
|
||||
- **Required fields**: Keyword
|
||||
- **time estimate**: 4h
|
||||
|
||||
### Press Release
|
||||
- **Prefix**: `PR - {keyword}`
|
||||
- **Required fields**: Keyword, IMSURL
|
||||
- **Work Category**: "Press Release"
|
||||
- **Stage**: `draft`
|
||||
- **Required fields**: Keyword, IMSURL
|
||||
- **PR Topic**: if not provided, ask if there is a topic. it can be blank if they respond with none.
|
||||
- **time estimate**: 1.5h
|
||||
- **Headline tone trigger words**: By default, the PR writer assumes the company already offers the capability (awareness tone). To get announcement-style headlines (Announces, Launches, Introduces), include one of these words in the task name or PR Topic:
|
||||
|
|
@ -61,6 +77,12 @@ Any field can be set via `--field "Name=Value"`. Dropdowns are auto-resolved by
|
|||
|
||||
The `clickup_create_task` tool provides the same capabilities via CheddahBot UI. Arbitrary custom fields are passed as JSON via `custom_fields_json`.
|
||||
|
||||
## Dependencies and Due Dates
|
||||
|
||||
When a CREATE (NEW) task exists, LINKS and PR tasks that need the new page URL should be **blocked by** the CREATE task using `--dependency`. Their due date should be **one week after** the CREATE task's due date. For example, if CREATE is due 4/9, the LINKS and PR tasks should be due 4/16.
|
||||
|
||||
OPT tasks already have a URL, so LINKS paired with an OPT does **not** need a dependency -- just the +1 week due date offset.
|
||||
|
||||
## Client Folder Lookup
|
||||
|
||||
Tasks are created in the "Overall" list inside the client's folder. Folder name is matched case-insensitively.
|
||||
|
|
|
|||
|
|
@ -50,6 +50,13 @@ WORK_CATEGORIES = {
|
|||
"PR": "Press Release",
|
||||
}
|
||||
|
||||
INITIAL_STAGES = {
|
||||
"NEW": "run_cora",
|
||||
"OPT": "run_cora",
|
||||
"LINKS": "run_cora",
|
||||
"PR": "draft",
|
||||
}
|
||||
|
||||
|
||||
def _date_to_unix_ms(date_str: str) -> int:
|
||||
"""Convert YYYY-MM-DD to Unix milliseconds (noon UTC)."""
|
||||
|
|
@ -199,6 +206,9 @@ def main():
|
|||
client.set_custom_field_smart(
|
||||
task_id, list_id, "Work Category", WORK_CATEGORIES[task_type]
|
||||
)
|
||||
client.set_custom_field_smart(
|
||||
task_id, list_id, "Stage", INITIAL_STAGES[task_type]
|
||||
)
|
||||
client.set_custom_field_smart(task_id, list_id, "Delegate to Claude", "true")
|
||||
|
||||
# IMSURL
|
||||
|
|
@ -211,7 +221,7 @@ def main():
|
|||
client.set_custom_field_smart(task_id, list_id, "BrandedPlusRatio", "0.80")
|
||||
if args.articles:
|
||||
client.set_custom_field_smart(
|
||||
task_id, list_id, "CLIFlags", f"--tier-1 {args.articles}"
|
||||
task_id, list_id, "CLIFlags", f"--tier1-count {args.articles}"
|
||||
)
|
||||
if args.anchors:
|
||||
client.set_custom_field_smart(
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ Creates a coordinated set of ClickUp tasks for a client keyword. The user specif
|
|||
|
||||
## Optional
|
||||
|
||||
- **articles**: Number of tier-1 articles for LINKS task. Sets CLIFlags to `--tier-1 {N}`.
|
||||
- **articles**: Number of tier-1 articles for LINKS task. Sets CLIFlags to `--tier1-count {N}`.
|
||||
- **anchors**: Custom anchor texts for LINKS task. Comma-delimited string goes into CustomAnchors field.
|
||||
- **priority**: Default is 2 (High).
|
||||
- **assignee**: Default is 10765627 (Bryan Bigari).
|
||||
|
|
@ -68,26 +68,30 @@ When a URL is provided (or OPT is used instead of NEW):
|
|||
|
||||
### LINKS (Link Building)
|
||||
- Work Category: "Link Building"
|
||||
- Stage: "run_cora"
|
||||
- LB Method: "Cora Backlinks"
|
||||
- BrandedPlusRatio: "0.80"
|
||||
- IMSURL: the url (if available)
|
||||
- CLIFlags: `--tier-1 {N}` (only if articles specified)
|
||||
- CLIFlags: `--tier1-count {N}` (only if articles specified)
|
||||
- CustomAnchors: comma-delimited anchors (only if provided)
|
||||
- Time estimate: 9000000 ms
|
||||
|
||||
### PR (Press Release)
|
||||
- Work Category: "Press Release"
|
||||
- Stage: "draft"
|
||||
- PR Topic: the pr_topic value
|
||||
- IMSURL: the url (if available)
|
||||
- Time estimate: 5400000 ms
|
||||
|
||||
### NEW (Content Creation)
|
||||
- Work Category: "Content Creation"
|
||||
- Stage: "run_cora"
|
||||
- IMSURL: not set (URL does not exist yet)
|
||||
- Time estimate: 14400000 ms
|
||||
|
||||
### OPT (On Page Optimization)
|
||||
- Work Category: "On Page Optimization"
|
||||
- Stage: "run_cora"
|
||||
- IMSURL: the url (required)
|
||||
- Time estimate: 7200000 ms
|
||||
|
||||
|
|
@ -128,4 +132,4 @@ User: "Create OPT, LINKS for RPM Rubber, keyword rubber seals, url https://rpmru
|
|||
|
||||
User: "Create LINKS, PR, NEW for RPM Rubber, keyword rubber gaskets, due April 15, tag apr26, pr topic RPM launches gasket line, 4 articles, anchors rubber gaskets,custom rubber gaskets,industrial rubber gaskets"
|
||||
|
||||
-> Same as first example but LINKS also gets CLIFlags=`--tier-1 4` and CustomAnchors=`rubber gaskets,custom rubber gaskets,industrial rubber gaskets`
|
||||
-> Same as first example but LINKS also gets CLIFlags=`--tier1-count 4` and CustomAnchors=`rubber gaskets,custom rubber gaskets,industrial rubber gaskets`
|
||||
|
|
|
|||
|
|
@ -104,19 +104,6 @@ class TestBuildPrompt:
|
|||
prompt = build_prompt(task, route, "skill content")
|
||||
assert "Write about blue widgets" in prompt
|
||||
|
||||
def test_includes_xlsx_urls(self):
|
||||
task = _make_task()
|
||||
route = _make_route()
|
||||
urls = ["https://cdn.clickup.com/report.xlsx"]
|
||||
prompt = build_prompt(task, route, "skill", xlsx_urls=urls)
|
||||
assert "https://cdn.clickup.com/report.xlsx" in prompt
|
||||
assert "Cora Reports" in prompt
|
||||
|
||||
def test_no_xlsx_section_when_none(self):
|
||||
task = _make_task()
|
||||
route = _make_route()
|
||||
prompt = build_prompt(task, route, "skill")
|
||||
assert "Cora Reports" not in prompt
|
||||
|
||||
def test_no_customer_when_missing(self):
|
||||
task = _make_task(custom_fields={})
|
||||
|
|
|
|||
Loading…
Reference in New Issue