feat: add OTHER list type + FW_DEBUG task-field logging (v0.8.3)
- create_list now accepts list_type="OTHER" (previously rejected) - get_tasks logs unknown task fields to stderr when FW_DEBUG=1 (preparation for repeating-task field discovery) - README, CLAUDE.md, version bumped to 0.8.3 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1 +1 @@
|
||||
__version__ = "0.8.2"
|
||||
__version__ = "0.8.3"
|
||||
|
||||
@@ -4,6 +4,8 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
from mcp.server.fastmcp import FastMCP
|
||||
@@ -342,7 +344,9 @@ def get_lists(scope: str | None = None) -> str:
|
||||
candidate = data["a00"]["r"]["r"]
|
||||
if isinstance(candidate, list):
|
||||
raw_lists = candidate
|
||||
elif isinstance(candidate, dict) and isinstance(candidate.get("updatedCreated"), list):
|
||||
elif isinstance(candidate, dict) and isinstance(
|
||||
candidate.get("updatedCreated"), list
|
||||
):
|
||||
raw_lists = candidate["updatedCreated"]
|
||||
except (KeyError, TypeError):
|
||||
pass
|
||||
@@ -392,6 +396,18 @@ def get_tasks(list_id: str, only_open: bool = True):
|
||||
|
||||
raw_tasks = _extract_tasks(data)
|
||||
|
||||
_fw_debug = os.environ.get("FW_DEBUG") == "1"
|
||||
_known_fields = {
|
||||
"metaId",
|
||||
"text",
|
||||
"description",
|
||||
"complete",
|
||||
"taskCategoryId",
|
||||
"dueDate",
|
||||
"assigneeIds",
|
||||
"taskListId",
|
||||
}
|
||||
|
||||
result = []
|
||||
for task in raw_tasks:
|
||||
if task.get("taskListId") != list_id:
|
||||
@@ -399,6 +415,16 @@ def get_tasks(list_id: str, only_open: bool = True):
|
||||
completed = str(task.get("complete", "false")).lower() == "true"
|
||||
if only_open and completed:
|
||||
continue
|
||||
|
||||
if _fw_debug:
|
||||
unknown = {k: v for k, v in task.items() if k not in _known_fields}
|
||||
if unknown:
|
||||
print(
|
||||
f"[FW_DEBUG] task {task.get('metaId')} unknown fields: "
|
||||
+ json.dumps(unknown, ensure_ascii=False),
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
result.append(
|
||||
{
|
||||
"id": task.get("metaId"),
|
||||
@@ -988,7 +1014,7 @@ def create_list(
|
||||
|
||||
Args:
|
||||
name: Display name for the new list (max 200 characters).
|
||||
list_type: List type — either ``"SHOPPING_LIST"`` or ``"TODOS"``.
|
||||
list_type: List type — ``"SHOPPING_LIST"``, ``"TODOS"``, or ``"OTHER"``.
|
||||
shared_to_all: When ``True`` (default) the list is shared with all
|
||||
circle members. When ``False`` it is private to the creator.
|
||||
color: Optional background colour as a hex string (e.g. ``"#4784EC"``).
|
||||
@@ -1003,8 +1029,8 @@ def create_list(
|
||||
Includes ``circle_id`` field showing which circle the list was
|
||||
created in.
|
||||
"""
|
||||
if list_type not in ("SHOPPING_LIST", "TODOS"):
|
||||
return "Error: list_type must be 'SHOPPING_LIST' or 'TODOS'."
|
||||
if list_type not in ("SHOPPING_LIST", "TODOS", "OTHER"):
|
||||
return "Error: list_type must be 'SHOPPING_LIST', 'TODOS', or 'OTHER'."
|
||||
if len(name) > 200:
|
||||
return "Error: name must not exceed 200 characters."
|
||||
|
||||
|
||||
Reference in New Issue
Block a user