feat: surface newly-created subtasks standalone in New Today

When a subtask is created today, it now appears as its own item
in the New Today section with the parent task shown as context
("under #PARENT_ID Parent Name"). Also still rendered inline
under the parent in Needs Work.

Requires API change: children now include created_at.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-17 08:35:50 +02:00
parent d74595b89a
commit 5950eb16d9

View File

@@ -116,12 +116,20 @@ def print_task(task, indent=" "):
assigned = task.get('on_behalf_of') assigned = task.get('on_behalf_of')
age = days_ago(created) age = days_ago(created)
is_today = is_new(created) is_today = is_new(created)
is_subtask = task.get('is_subtask', False)
# Task number + name # Task number + name (prefix with ↳ if this is a standalone subtask view)
badge = new_badge() if is_today else "" badge = new_badge() if is_today else ""
line = f"{indent}{YELLOW}#{nid}{RESET} {BOLD}{WHITE}{name}{RESET}{badge}" prefix = f"{GREY}↳{RESET} " if is_subtask else ""
line = f"{indent}{prefix}{YELLOW}#{nid}{RESET} {BOLD}{WHITE}{name}{RESET}{badge}"
print(line) print(line)
# Parent context for subtasks
if is_subtask and task.get('parent_name'):
parent_nid = task.get('parent_nodesid')
parent_name = task.get('parent_name', '')
print(f"{indent} {DIM}under {YELLOW}#{parent_nid}{RESET} {DIM}{parent_name}{RESET}")
# Meta line # Meta line
parts = [format_status(status), format_priority(priority)] parts = [format_status(status), format_priority(priority)]
if age: if age:
@@ -230,12 +238,34 @@ def render_tasks(tasks):
if not tasks: if not tasks:
return return
# Separate new tasks # Separate new tasks (parent-level)
new_tasks = [t for t in tasks if t.get('category') == 'actionable' and is_new(t.get('created_at', ''))] new_tasks = [t for t in tasks if t.get('category') == 'actionable' and is_new(t.get('created_at', ''))]
actionable = [t for t in tasks if t.get('category') == 'actionable' and not is_new(t.get('created_at', ''))] actionable = [t for t in tasks if t.get('category') == 'actionable' and not is_new(t.get('created_at', ''))]
waiting = [t for t in tasks if t.get('category') == 'waiting'] waiting = [t for t in tasks if t.get('category') == 'waiting']
done = [t for t in tasks if t.get('category') == 'done'] done = [t for t in tasks if t.get('category') == 'done']
# Also surface any SUBTASKS created today as their own items in New Today
waiting_statuses = {'done', 'completed', 'cancelled'}
for t in tasks:
for ch in (t.get('children') or []):
if not is_new(ch.get('created_at', '')):
continue
if (ch.get('status') or '').lower() in waiting_statuses:
continue
new_tasks.append({
'nodesid': ch['nodesid'],
'node_name': ch.get('node_name', 'Untitled'),
'created_at': ch.get('created_at'),
'status': ch.get('status'),
'priority': ch.get('priority'),
'on_behalf_of': ch.get('on_behalf_of'),
'client': t.get('client'),
'project': t.get('project'),
'is_subtask': True,
'parent_nodesid': t.get('nodesid'),
'parent_name': t.get('node_name'),
})
# New today # New today
if new_tasks: if new_tasks:
print(f"\n{BOLD}{RED}{'─' * 60}{RESET}") print(f"\n{BOLD}{RED}{'─' * 60}{RESET}")