MCPcopy
hub / github.com/cft0808/edict / cmd_todo

Function cmd_todo

scripts/kanban_update.py:648–711  ·  view source on GitHub ↗

添加或更新子任务 todo(原子操作) status: not-started / in-progress / completed detail: 可选,该子任务的详细产出/说明(Markdown 格式) 约束:同一时刻最多只有 1 个 in-progress 状态的 todo。

(task_id, todo_id, title, status='not-started', detail='')

Source from the content-addressed store, hash-verified

646 _append_audit(task_id, _infer_agent_id_from_runtime(), 'progress', None, None, clean)
647
648def cmd_todo(task_id, todo_id, title, status='not-started', detail=''):
649 """添加或更新子任务 todo(原子操作)
650
651 status: not-started / in-progress / completed
652 detail: 可选,该子任务的详细产出/说明(Markdown 格式)
653
654 约束:同一时刻最多只有 1 个 in-progress 状态的 todo。
655 """
656 # 校验 status 值
657 if status not in ('not-started', 'in-progress', 'completed'):
658 status = 'not-started'
659 result_info = [0, 0]
660 rejected = [False]
661 ready_to_close = [False]
662 def modifier(tasks):
663 t = find_task(tasks, task_id)
664 if not t:
665 log.error(f'任务 {task_id} 不存在')
666 return tasks
667 if 'todos' not in t:
668 t['todos'] = []
669
670 # 单一 in-progress 约束
671 if status == 'in-progress':
672 existing_ip = [td for td in t['todos']
673 if td.get('status') == 'in-progress' and str(td.get('id')) != str(todo_id)]
674 if existing_ip:
675 log.warning(
676 f'⚠️ todo #{existing_ip[0]["id"]} 正在执行中,'
677 f'请先完成或取消后再开始 #{todo_id}'
678 )
679 rejected[0] = True
680 return tasks
681
682 existing = next((td for td in t['todos'] if str(td.get('id')) == str(todo_id)), None)
683 if existing:
684 existing['status'] = status
685 if title:
686 existing['title'] = title
687 if detail:
688 existing['detail'] = detail
689 else:
690 item = {'id': todo_id, 'title': title, 'status': status}
691 if detail:
692 item['detail'] = detail
693 t['todos'].append(item)
694 t['updatedAt'] = now_iso()
695 result_info[0] = sum(1 for td in t['todos'] if td.get('status') == 'completed')
696 result_info[1] = len(t['todos'])
697 # 所有 todo 完成 → 标记 ready_to_close
698 if result_info[1] > 0 and result_info[0] == result_info[1]:
699 t['ready_to_close'] = True
700 ready_to_close[0] = True
701 return tasks
702 atomic_json_update(TASKS_FILE, modifier, [])
703 _trigger_refresh()
704 if rejected[0]:
705 log.info(f'❌ {task_id} todo #{todo_id} → in-progress 被拒(已有进行中的 todo)')

Callers 1

kanban_update.pyFile · 0.70

Calls 4

atomic_json_updateFunction · 0.90
_append_auditFunction · 0.85
_trigger_refreshFunction · 0.70

Tested by

no test coverage detected