Add task set creation skill + ClickUp dependency support
Add add_dependency() to ClickUpClient and clickup_add_dependency chat tool for setting "blocked by" relationships between tasks. New create-task-set skill enables bundled task creation (LINKS, PR, NEW, OPT) with correct fields, time estimates, due date offsets, and automatic dependencies. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>clickup-runner
parent
99b000f25a
commit
935ab2d772
|
|
@ -500,6 +500,32 @@ class ClickUpClient:
|
|||
)
|
||||
return False
|
||||
|
||||
def add_dependency(self, task_id: str, depends_on: str) -> bool:
|
||||
"""Add a 'blocked by' dependency: *task_id* is blocked by *depends_on*.
|
||||
|
||||
Uses POST /task/{task_id}/dependency with {"depends_on": ...}.
|
||||
"""
|
||||
try:
|
||||
|
||||
def _call():
|
||||
resp = self._client.post(
|
||||
f"/task/{task_id}/dependency",
|
||||
json={"depends_on": depends_on},
|
||||
)
|
||||
resp.raise_for_status()
|
||||
return resp
|
||||
|
||||
self._retry(_call)
|
||||
log.info(
|
||||
"Added dependency: task %s blocked by %s", task_id, depends_on
|
||||
)
|
||||
return True
|
||||
except (httpx.TransportError, httpx.HTTPStatusError) as e:
|
||||
log.error(
|
||||
"Failed to add dependency on task %s: %s", task_id, e
|
||||
)
|
||||
return False
|
||||
|
||||
def get_custom_field_by_name(self, task_id: str, field_name: str) -> Any:
|
||||
"""Read a custom field value from a task by field name.
|
||||
|
||||
|
|
|
|||
|
|
@ -255,6 +255,39 @@ def clickup_create_task(
|
|||
client_obj.close()
|
||||
|
||||
|
||||
@tool(
|
||||
"clickup_add_dependency",
|
||||
"Add a 'blocked by' dependency between two ClickUp tasks. "
|
||||
"The blocked_task_id will be blocked by blocker_task_id "
|
||||
"(i.e. blocker must complete before blocked can start).",
|
||||
category="clickup",
|
||||
)
|
||||
def clickup_add_dependency(
|
||||
blocked_task_id: str,
|
||||
blocker_task_id: str,
|
||||
ctx: dict | None = None,
|
||||
) -> str:
|
||||
"""Set blocked_task_id as blocked by blocker_task_id."""
|
||||
client = _get_clickup_client(ctx)
|
||||
if not client:
|
||||
return "Error: ClickUp API token not configured."
|
||||
|
||||
try:
|
||||
ok = client.add_dependency(blocked_task_id, depends_on=blocker_task_id)
|
||||
if ok:
|
||||
return (
|
||||
f"Dependency added: task {blocked_task_id} "
|
||||
f"is now blocked by {blocker_task_id}."
|
||||
)
|
||||
return (
|
||||
f"Failed to add dependency. Check that both task IDs are valid."
|
||||
)
|
||||
except Exception as e:
|
||||
return f"Error adding dependency: {e}"
|
||||
finally:
|
||||
client.close()
|
||||
|
||||
|
||||
@tool(
|
||||
"clickup_reset_task",
|
||||
"Reset a ClickUp task to 'to do' status so it can be retried on the next poll. "
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
---
|
||||
name: create-task-set
|
||||
description: Create a bundled set of ClickUp tasks (LINKS, PR, NEW, OPT) for a client keyword. Use when the user asks to create a task set, task bundle, or multiple related SEO tasks at once.
|
||||
tools: [clickup_create_task, clickup_add_dependency]
|
||||
agents: [default]
|
||||
---
|
||||
|
||||
# Create Task Set
|
||||
|
||||
Creates a coordinated set of ClickUp tasks for a client keyword. The user specifies which task types to create and you build them with the correct fields, time estimates, due dates, and dependencies.
|
||||
|
||||
## Task Types
|
||||
|
||||
| Code | Task Name | Work Category | Time Estimate |
|
||||
|------|-----------|--------------|---------------|
|
||||
| LINKS | `LINKS - {keyword}` | Link Building | 2h 30m (9000000 ms) |
|
||||
| PR | `PR - {keyword}` | Press Release | 1h 30m (5400000 ms) |
|
||||
| NEW | `NEW - {keyword}` | Content Creation | 4h (14400000 ms) |
|
||||
| OPT | `OPT - {keyword}` | On Page Optimization | 2h (7200000 ms) |
|
||||
|
||||
## Required Information (ask if not provided)
|
||||
|
||||
- **client**: Client/folder name (e.g. "RPM Rubber")
|
||||
- **keyword**: The SEO keyword (e.g. "rubber gaskets")
|
||||
- **types**: Which tasks to create -- any combination of LINKS, PR, NEW, OPT
|
||||
- **due_date**: Due date for the content task (YYYY-MM-DD)
|
||||
- **tag**: Month tag (e.g. "apr26")
|
||||
|
||||
## Conditionally Required
|
||||
|
||||
- **pr_topic**: Required ONLY when PR is in the set. The press release topic (different from keyword).
|
||||
- **url**: The IMSURL. Required when OPT is in the set or when LINKS/PR are in the set WITHOUT a NEW task. If NEW is in the set and no URL is provided, LINKS and PR are blocked by the NEW task.
|
||||
|
||||
## Optional
|
||||
|
||||
- **articles**: Number of tier-1 articles for LINKS task. Sets CLIFlags to `--tier-1 {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).
|
||||
|
||||
## Common Fields (set on ALL tasks)
|
||||
|
||||
Every task gets these fields set after creation:
|
||||
- **Client**: Set to the client name (dropdown)
|
||||
- **Delegate to Claude**: Set to `true` (checkbox)
|
||||
- **Tag**: The month tag
|
||||
- **Priority**: High (2) unless overridden
|
||||
- **Assignee**: Bryan unless overridden
|
||||
|
||||
## Due Date Logic
|
||||
|
||||
- The content task (NEW or OPT) gets the provided due date.
|
||||
- LINKS and PR get due date + 7 days (same day of week, one week later).
|
||||
- If there is no content task in the set, all tasks get the provided due date.
|
||||
|
||||
## Dependency Logic
|
||||
|
||||
When NEW is in the set and no URL is provided:
|
||||
- Create the NEW task FIRST.
|
||||
- For each LINKS and PR task in the set, call `clickup_add_dependency` with `blocked_task_id` = the LINKS/PR task ID and `blocker_task_id` = the NEW task ID.
|
||||
- Do NOT set IMSURL on LINKS or PR since the URL does not exist yet.
|
||||
|
||||
When a URL is provided (or OPT is used instead of NEW):
|
||||
- Set IMSURL on all tasks that have the field.
|
||||
- No dependencies needed.
|
||||
|
||||
## Field Reference Per Task Type
|
||||
|
||||
### LINKS (Link Building)
|
||||
- Work Category: "Link Building"
|
||||
- LB Method: "Cora Backlinks"
|
||||
- BrandedPlusRatio: "0.80"
|
||||
- IMSURL: the url (if available)
|
||||
- CLIFlags: `--tier-1 {N}` (only if articles specified)
|
||||
- CustomAnchors: comma-delimited anchors (only if provided)
|
||||
- Time estimate: 9000000 ms
|
||||
|
||||
### PR (Press Release)
|
||||
- Work Category: "Press Release"
|
||||
- PR Topic: the pr_topic value
|
||||
- IMSURL: the url (if available)
|
||||
- Time estimate: 5400000 ms
|
||||
|
||||
### NEW (Content Creation)
|
||||
- Work Category: "Content Creation"
|
||||
- IMSURL: not set (URL does not exist yet)
|
||||
- Time estimate: 14400000 ms
|
||||
|
||||
### OPT (On Page Optimization)
|
||||
- Work Category: "On Page Optimization"
|
||||
- IMSURL: the url (required)
|
||||
- Time estimate: 7200000 ms
|
||||
|
||||
## Execution Steps
|
||||
|
||||
1. Confirm you have all required info for the requested task types. Ask for anything missing.
|
||||
2. Convert the due date to Unix milliseconds (noon UTC): parse YYYY-MM-DD, set to 12:00 UTC, multiply epoch seconds by 1000.
|
||||
3. Calculate the +7 day due date for LINKS/PR if a content task is in the set.
|
||||
4. If NEW is in the set, create it first (you need its task ID for dependencies).
|
||||
5. Create each task using `clickup_create_task` with:
|
||||
- name: `{TYPE} - {keyword}`
|
||||
- client: the client name
|
||||
- work_category: per the table above
|
||||
- status: "to do"
|
||||
- due_date: the appropriate Unix ms value
|
||||
- tags: the tag value
|
||||
- priority: 2 (or override)
|
||||
- assignee: 10765627 (or override)
|
||||
- time_estimate_ms: per the table above
|
||||
- custom_fields_json: JSON object with all type-specific fields plus `{"Delegate to Claude": true}`
|
||||
6. If NEW is in the set with no URL, call `clickup_add_dependency` for each LINKS/PR task.
|
||||
7. Report back with a summary: task names, IDs, URLs, and any dependencies set.
|
||||
|
||||
## Examples
|
||||
|
||||
User: "Create LINKS, PR, NEW for RPM Rubber, keyword rubber gaskets, due April 15, tag apr26, pr topic RPM Rubber launches new gasket product line"
|
||||
|
||||
-> Create 3 tasks:
|
||||
1. `NEW - rubber gaskets` (Content Creation, due 2026-04-15, 4h)
|
||||
2. `LINKS - rubber gaskets` (Link Building, due 2026-04-22, 2.5h, blocked by NEW)
|
||||
3. `PR - rubber gaskets` (Press Release, due 2026-04-22, 1.5h, blocked by NEW)
|
||||
|
||||
User: "Create OPT, LINKS for RPM Rubber, keyword rubber seals, url https://rpmrubber.com/rubber-seals, due April 10, tag apr26"
|
||||
|
||||
-> Create 2 tasks:
|
||||
1. `OPT - rubber seals` (On Page Optimization, due 2026-04-10, 2h, IMSURL set)
|
||||
2. `LINKS - rubber seals` (Link Building, due 2026-04-17, 2.5h, IMSURL set)
|
||||
|
||||
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`
|
||||
Loading…
Reference in New Issue