Commit Graph

55 Commits

Author SHA1 Message Date
marcus 08ee5fb84a fix(tasks): send recurrency/reminder as flat top-level params (v1.1.1)
FiZ Ai() encoder does not support nested objects — recurrencyDescriptor
and reminder fields must be top-level params (recurrency=WEEKLY, not
recurrencyDescriptor={recurrency:WEEKLY}). Same fix for reminder fields.
SPEC.md and CLAUDE.md updated to document the flat encoding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 21:18:58 +02:00
marcus f5eb0a46c8 feat(tasks): add recurrency and reminder write support to update_task (v1.1.0)
Verified parameters from JS-Bundle xb-Encoder/fc-Encoder now wired up:
recurrencyDescriptor (recurrency, recurrencyInterval, rrule) and reminder
(reminderUnit, reminderValue). Adds clear_recurrency and clear_reminder flags.
SPEC.md, CHANGELOG.md, CLAUDE.md updated accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 21:15:05 +02:00
marcus bdf9e3c59e chore: finalize v1.0.0 — cleanup, unified errors, date validation
- Move integration tests to tests/; fix .gitignore to scope root-only
- Remove tracked debug artefacts (probe2_stderr/stdout.txt)
- __init__.py: version via importlib.metadata; export create_server in __all__
- server.py: unified JSON error format {"error":"..."} for all tools
- server.py: date validation (YYYY-MM-DD) for all meal-plan tools
- server.py: clear_list reports partial failures (failed_count, failed_ids)
- server.py: -> str annotations on get_circles, get_tasks, get_activities
- server.py: document TODO:94 as known limitation (no name in sortingIndexByTaskList)
- server.py: date validation also added to get_meal_plan
- Add LICENSE (MIT, Marcus van Elst)
- Add CHANGELOG.md (Keep a Changelog, v0.1.0–v1.0.0)
- README.md: restructured by use case; 🔒 marks write tools
- CLAUDE.md: update to v1.0.0 state; condense roadmap history
- SPEC.md: add version stamp
- pyproject.toml: version 1.0.0 (single source of truth)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 15:30:26 +02:00
marcus 0b56ea92bc docs(recipes): document isRecipe-flag behavior in get_recipe_box (v0.11.8)
Documentation-only release explaining the isRecipe flag:
- isRecipe='true': Real recipes in the recipe box
- isRecipe='false': Free-text stubs from meal planner OR old imported recipes
  never properly tagged (e.g. recipe/16282169_7055369 'Elsässer Flammkuchen')

get_recipe_box filters strictly on isRecipe='true' — consistent with Family Wall app.

Updated SPEC.md, README.md, CLAUDE.md with v0.11.8.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-17 14:09:28 +02:00
marcus 5e3b7e08a3 feat(recipes): add get_recipe_box + parser-fix ingredients_parsed (v0.11.7)
- New tool get_recipe_box: filtered version of get_recipes returning only real recipes (isRecipe=true), excluding stubs created for free-text meal entries
- Parser fix: ingredients_parsed now generated from free-text ingredients field instead of API's ingredientsList which has parser bug on comma+space (e.g. '1, 5g' breaks)
- Updated SPEC.md with parser bug documentation
- Updated version to 0.11.7 in __init__.py and pyproject.toml
- Updated .gitignore to exclude debug/test scripts

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-17 13:55:05 +02:00
marcus 343e8eeb58 feat(tasks): add clear_list tool (v0.11.6)
Deletes all tasks in a list within a single authenticated session,
avoiding N×(login+logout) overhead — Login once, N×delete, logout once.
Supports only_open=True to keep completed tasks.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 13:35:25 +02:00
marcus 3f20b6eda3 feat(meal-planner): add add_meal_note tool (v0.11.5)
New write tool using mpmealput endpoint to create meal/ note entries
with optional free-text and serving count. Response structure verified
from JS-bundle (Sg class); a00.r.r is a plain object (unlike mpcreate).
Structured output matches get_meal_plan meal entry format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:33:31 +02:00
marcus e0054116cb feat(meal-planner): add delete_meal_plan_entry tool (v0.11.4)
Reuses the existing metadelete endpoint (already used for tasks and
recipes). Validates that entry_id starts with 'dish/' or 'meal/' before
calling the API. SPEC.md updated to reflect metadelete's broader scope.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:28:41 +02:00
marcus a26a637c83 feat(meal-planner): structured output for add_meal_to_meal_plan (v0.11.3)
Map verified mpcreate response to same field layout as get_meal_plan.
Key difference: a00.r.r is an array (take [0]) unlike mpcreateByRecipeId
which returns a plain object. is_from_recipe_box is always false.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:24:48 +02:00
marcus 0ed9d62e4a feat(meal-planner): add add_meal_to_meal_plan tool (v0.11.2)
New write tool using mpcreate endpoint for free-text meal entries
(no recipe link). Parameters verified from JS-bundle. Returns raw
response pending production verification; structured output →  v0.11.3.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 12:10:20 +02:00
marcus d344251796 feat(meal-planner): structured output for add_recipe_to_meal_plan (v0.11.1)
Map verified mpcreateByRecipeId response (a00.r.r dish object) to the
same field layout as get_meal_plan entries. is_from_recipe_box is always
true since this tool only creates recipe-box entries.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 11:52:16 +02:00
marcus e7e242151f feat(meal-planner): add add_recipe_to_meal_plan tool (v0.11.0)
New write tool using mpcreateByRecipeId endpoint (parameters verified
from JS-bundle). Returns raw response pending production verification;
structured output planned for v0.11.1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 11:45:28 +02:00
marcus bf086a4f84 feat(meal-planner): add is_from_recipe_box field to get_meal_plan (v0.10.3)
Join recipeList[] from API response as a lookup table: isRecipe="true"
means a real recipe from the recipe box, "false" is a free-text stub.
Dish entries get is_from_recipe_box=true/false; meal entries get null.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 11:31:51 +02:00
marcus 7d912beb5f feat(meal-planner): merge mealList[] into get_meal_plan output (v0.10.2)
- dish entries (list[]) and meal entries (mealList[]) are now merged and
  returned together, sorted by date then type (BREAKFAST→LUNCH→SNACK→DINNER)
- New output fields: note (free-text, meal entries only) and serves (int)
- SPEC.md: document verified mealList[] response structure

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 11:26:21 +02:00
marcus a7b21c1ede feat(meal-planner): structured output for get_meal_plan (v0.10.1)
- Map mplistinterval response to clean JSON list (id, date, type, name,
  recipe_id, can_update, can_delete) — no more raw dump
- SPEC.md: document verified mplistinterval response structure
- Fix two pre-existing ruff SIM warnings (SIM102, SIM105)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 11:13:22 +02:00
marcus 500ad278a4 feat(meal-planner): add get_meal_plan read-only tool (v0.10.0)
- Implement get_meal_plan() tool for accessing Family Wall meal planner
- Parameters: date_from, date_to (ISO 8601 format)
- Returns raw JSON for initial verification via FW_DEBUG=1
- Response structure to be verified in first deployment
- Add Meal Planner API section to SPEC.md documenting mplistinterval and other endpoints
- Update version to 0.10.0 in __init__.py and pyproject.toml
- Update README.md and CLAUDE.md with tool info and roadmap

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-17 11:03:48 +02:00
marcus 36448e68e0 docs: clean up documentation (v0.8.2)
- Roadmap: v0.8.x mpadditemtolist marked as 'cancelled – Family Wall native'
- CLAUDE.md: add recipe.recipeCategoryIdList and scope params to tables; add mpstar/isFavorite limitation section
- README.md: v0.8.0 → v0.8.2; get_lists clarification (returns all circles without scope); get_recipe_categories standard categories list
- SPEC.md: update recipe categories explanation, taskupdatelist scope param, offene punkte clarification
2026-04-17 07:38:38 +02:00
marcus d41ac8e763 docs(spec): document metamood endpoint and mpstar service-worker blocker
Investigated toggle_recipe_favorite (v0.8.3 goal):
- mpstar: not registered server-side (Service Worker intercepts it)
- metamood: registered, accepts recipe IDs, but self-reaction restriction
  prevents state changes on own recipes (same as wallmood for own posts)
- isFavorite cannot be set via any discovered endpoint

Added to SPEC.md:
- metamood endpoint spec with known limitations (FiZClassId 8004, self-reaction)
- mpstar investigation summary with unblock requirements
- mpstar / isFavorite added to Offene Punkte

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 07:02:25 +02:00
marcus b15af18606 feat(lists): get_lists() without scope returns all circles (v0.8.2)
Implement v0.8.2: When get_lists() is called without a scope parameter,
it now fetches lists from ALL circles instead of only the primary circle.

Implementation:
- Login once, call famlistfamily to get all circle IDs
- For each circle, call taskgettasklists(scope=<circle_id>)
- Merge results and return all lists with circle_id field

All tests passed: test_multi circle creation, list creation in secondary
circle, get_lists() without scope returns lists from both circles.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-17 06:40:09 +02:00
marcus 4c60b5b5fa feat(recipes): add recipe categories support (v0.8.0)
- New tool: get_recipe_categories() lists available recipe category IDs
- Enhanced create_recipe and update_recipe with optional category_ids parameter
- Extended get_recipe and get_recipes to include category_ids in response
- Updated parse_recipe_full() to extract recipeCategoryIdList from API response
- Extended build_create_params() and build_update_params() to handle category_ids

Recipe categories are managed via recipe.recipeCategoryIdList in mprecipeput API.
Categories are represented as a list of category IDs (e.g. ["category/23431854_2"]).
No direct API endpoint exists for listing all categories; they are discovered from
existing recipes or must be known in advance.

Version: 0.7.5 → 0.8.0
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-04-17 06:24:48 +02:00
marcus 02f9d62720 feat(circles): add update_circle tool (v0.7.4)
Implements accupdatefamily endpoint (verified via FW_DEBUG=1):
- Parameter 'scope' targets any circle (primary or secondary)
- Without scope: renames the primary circle (API default)
- Server always capitalises the first letter of the new name
- Verifies circle existence via famlistfamily in same session
- Response a00.r.r = full circle object with updated name

Also corrects SPEC.md: accupdatefamily with scope= works for any
circle, not just the primary (previous note was incomplete).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 21:33:07 +02:00
marcus d144a77662 feat(lists): add update_list tool (v0.7.3)
Implements taskupdatelist endpoint (verified via FW_DEBUG=1):
- Parameter 'metaId' (not 'id') identifies the list
- Partial update: only provided fields (name/color/emoji) are changed
- Reads rights.canUpdate before calling the endpoint (single session)
- System lists (canUpdate != 'true') are rejected with a clear error
- Scope derived from list metaId for secondary-circle support

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 20:12:28 +02:00
marcus dc21416a61 feat: add delete_circle tool (v0.7.2)
Implements `delete_circle(circle_id)` using the verified `adminwipefamily`
endpoint. Protects the primary circle via `isFirstFamily` check. Probe
circles family/23447370 and family/23447378 cleaned up during testing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 18:28:22 +02:00
marcus abb557e96b fix(lists): circle scope support for get_lists, create_list, delete_list (v0.7.1)
- get_lists(scope): API scope parameter now used server-side; accepts circle
  metaId ("family/XXXX") or circle name; returns circle_id field per list
- create_list(circle_id): new optional param; passes as API scope param
- delete_list: derives circle from list metaId and passes scope for
  secondary-circle lists
- Added _circle_id_from_list_id() helper (taskList/FAMNUM_LISTNUM -> family/FAMNUM)
- SPEC.md: documented scope param for taskgettasklists, taskcreatelist, taskdeletelist
- Verified: familyId/circleId/id params ignored by API, only scope works

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 18:10:05 +02:00
marcus 2bc03e2165 feat(circles): create_circle + add_member_to_circle (v0.7.0)
- acccreatefamily endpoint creates a new circle (returns numeric ID)
- accinvite endpoint invites new users by email (familyId, identifier, role, firstname)
- fw_client now detects a00.ex errors (was only checking a00.un before)
- New modules/circles.py with FamilyRoleTypeEnum constants
- SPEC.md updated with acccreatefamily, accinvite, accupdatefamily docs
- Note: circle deletion not supported by FW API (metadelete → "delete not supported")
- Note: accinvite only works for new (non-existing) FW accounts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 17:59:20 +02:00
marcus bc28b09d49 fix(recipes): normalize newlines + add update_recipe (v0.6.1)
Bug fix: literal backslash-n sequences in ingredients/instructions are now
converted to real newline characters before sending to the API, so the server
correctly splits ingredient lines into ingredientsList[].

New tool: update_recipe — partial update via mprecipeput with recipe.metaId;
fetches current recipe in the same session to verify can_update and supply
name fallback. Verified: recipe.metaId triggers update (not create).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 15:01:40 +02:00
marcus ebbbf38ab9 feat(recipes): implement get_recipes, get_recipe, create_recipe, delete_recipe (v0.6.0)
Adds 4 new MCP tools for the Family Wall recipe box:
- get_recipes: list all family recipes via metasync id='recipe'
- get_recipe: fetch full recipe detail by id (filters from metasync response)
- create_recipe: create a new recipe via mprecipeput (params use 'recipe.' prefix)
- delete_recipe: delete a recipe via metadelete (same endpoint as tasks)

Verified endpoints and parameter names via FW_DEBUG=1 probe scripts.
All 4 tools pass the create → read → get_single → delete integration test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 14:51:53 +02:00
marcus 4a3fe6be87 feat(lists): expose emoji + color in get_lists + create_list (v0.5.1)
get_lists now includes emoji and color fields per list entry.
create_list response also returns emoji and color from the API.

Field name verification (FW_DEBUG=1, 2026-04-16):
- emoji: API returns "" when unset -> normalised to null
- color: API omits key when unset -> normalised to null
- Both fields present in taskgettasklists and taskcreatelist responses

SPEC.md: taskgettasklists documented with full response structure
         and emoji/color normalisation notes.
         taskcreatelist response updated with emoji + color fields.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 13:50:36 +02:00
marcus 311f37d72b feat(lists): implement create_list + delete_list (v0.5.0)
Adds two new MCP tools:
- create_list(name, list_type, shared_to_all, color, emoji)
  POST taskcreatelist; returns full list object incl. metaId
- delete_list(list_id) – with canDelete safety guard
  POST taskdeletelist; param 'id' (same pattern as metadelete)

Both endpoints verified via FW_DEBUG=1 on 2026-04-16.
SPEC.md and CLAUDE.md updated with verified parameter names
and response structures.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 12:26:16 +02:00
marcus e76d80ece3 Dokumente aktualisiert 2026-04-16 11:11:48 +02:00
marcus 0517241ee5 feat(tasks): implement clear_due_date via FiZ \$empty sentinel (v0.4.16)
The Family Wall API (FiZ framework) uses the special string "\$empty"
to clear optional date fields. Sending dueDate=\$empty to taskupdate2
reliably removes the due date (verified via direct API probing).

- update_task(clear_due_date=True) now sends dueDate=\$empty instead
  of returning an error
- Remove the "not supported" limitation message from the docstring
- Update SPEC.md, README.md, CLAUDE.md to document the discovery
- Bump version to 0.4.16

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 10:57:21 +02:00
marcus 6c955d67c8 fix: surface a00.un API errors + document dueDate-clearing limitation (v0.4.15)
- fw_client: detect nested a00.un errors (previously silent-failed as success)
- update_task: add clear_due_date=True parameter that returns a clear error
  explaining the Family Wall API cannot clear dueDate once set
- SPEC.md: document all tested clearing candidates and their API responses,
  add Fehlerstruktur-Varianten section
- Verified: dueDate cannot be removed via any form-encoded value; all invalid
  date strings are rejected via a00.un.un (silently swallowed before this fix)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 09:47:51 +02:00
marcus 4411e6d93e feat: due_date, assignee_ids, list_id for create_task/update_task (v0.4.14)
- create_task: new optional params due_date (ISO 8601) and assignee_ids (list[str])
- update_task: new optional params due_date, assignee_ids, and list_id (move task)
- get_tasks: returns due_date and assignee_ids fields per task
- API params verified via FW_DEBUG=1: dueDate, assignee, taskListId
- SPEC.md, README, CLAUDE.md updated

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 09:01:04 +02:00
marcus 0d8036fd4a fix: get_categories always includes custom categories (v0.4.12)
Custom categories (rights.canDelete=true) have no locale field set by
the API and were silently excluded by the locale filter. They now bypass
both the locale and taskListType filters so they always appear in
get_categories output regardless of the locale parameter.

Also: deleted 7 test categories (TEmojiApple, Obst & Gemüse (old),
TestKategorie, ProbeKat2, [TEST]emoji=apple, ProbeKat1, TDelMeta)
and restored 'Obst & Gemüse' (emoji 🍎) as a clean custom category.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 08:06:21 +02:00
marcus 5698196c43 feat: create_category + delete_category tools (v0.4.11)
Verified via systematic FW_DEBUG=1 probing:
- taskcategoryput: requires 'name'; optional 'emoji' (Unicode or string code)
  accepted as-is. 'listId' param has no per-list effect — categories are
  family-wide.
- taskcategorydelete: uses 'id' param (not 'metaId'), returns r='true'.

Changes:
- create_category(list_id, name, icon=None): creates custom category via
  taskcategoryput; icon maps to 'emoji' API param
- delete_category(category_id): safety check via accgetallfamily looks up
  rights.canDelete='true'; system categories (rights.canDelete=null) are
  refused with a clear error
- get_categories: now exposes 'custom' bool field (rights.canDelete='true')
  so callers can identify deletable categories
- SPEC.md: document taskcategoryput + taskcategorydelete params, responses,
  error formats, and system-category protection behaviour

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 07:43:54 +02:00
marcus a76dc0fd51 feat: category assignment in create_task / update_task (v0.4.10)
Verified via FW_DEBUG=1 + systematic param-name probing that the
correct parameter is `taskCategoryId` with value = full metaId from
get_categories (e.g. taskCategory/23431854_200).  Numeric systemCategoryId
alone causes API error; full metaId is accepted and stored.

Changes:
- create_task: add optional category_id parameter → sent as taskCategoryId
- update_task: add optional category_id parameter → sent as taskCategoryId;
  guard now accepts category_id-only updates
- get_tasks: expose category_id field in returned task objects
- get_categories: update docstring (param name now known)
- SPEC.md: document verified taskCategoryId param + clarify categories[]
  vs taskCategoryId field distinction
- scripts/find_category_param.py: discovery script used to find param name

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 06:54:10 +02:00
marcus 9bc6a54783 fix: get_categories locale filter and list-type filter (v0.4.9)
Bug 1: all 171 category locale variants were returned; now filtered by
locale parameter (default "de") → 13 German categories for shopping lists.

Bug 2: TODO lists returned 171 shopping categories because
sortingIndexByTaskList contains ALL list IDs regardless of type.
Fix: look up list's taskListType via taskgettasklists, then match against
category's taskListType. TODO lists (type=TODOS) return empty list since
all API categories are SHOPPING_LIST type.

sortingIndexByTaskList is explicitly documented as unreliable for type
filtering in both code comments and SPEC.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 21:22:00 +02:00
marcus ffb8b062c8 feat: get_categories tool, author resolution in get_activities, update CLAUDE.md (v0.4.8)
- get_categories(list_id): new tool filtering taskcategorysync by
  sortingIndexByTaskList, returns {id, name, emoji} ordered by sort index
- get_activities: author IDs now resolved to display names (firstName) via
  famlistfamily members; raw author_id preserved as separate field; member
  lookup is non-fatal (falls back to raw ID on error)
- CLAUDE.md: tools table updated to reflect all implemented tools (v0.4.8)
- SPEC.md: full accgetallfamily response structure documented including
  categories[] on tasks and category parameter investigation findings
- Category assignment in create/update task: all tested parameter names
  ignored by API; still to verify (Service Worker blocks web inspection)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 17:04:35 +02:00
marcus 70b1f73079 feat: add get_members tool, refactor get_circles via _famlistfamily helper (v0.4.7)
famlistfamily response already contains members[] on each circle object.
get_members(circle_id=None) extracts id, name, email, role, right, color,
avatar, circle_id and circle_name. get_circles refactored to use the new
_famlistfamily() helper, eliminating duplicated auth/call/logout logic.
SPEC.md updated with full famlistfamily response structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 16:22:59 +02:00
marcus 4cd0bdc499 fix: use moodStarShortcut+moodMap for liked state, warn on silent fail (v0.4.6)
FW_DEBUG=1 investigation revealed:
- wallmood can silently fail (200 OK, frozen modifDate, no state change) due to
  self-like restriction, unsupported post type (FAMILY_CREATED), or rate limit
- Response contains two complementary like indicators: moodStarShortcut (primary)
  and moodMap (secondary) — both must be checked
- liked: false with like=True now surfaces a warning instead of silently
  returning a misleading result
- SPEC.md documents silent-fail scenarios and dual indicator pattern

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 16:12:05 +02:00
marcus da5be55070 fix: unlike not supported — wallmood is idempotent SET, not toggle (v0.4.5)
Extensive FW_DEBUG=1 testing revealed:
- wallmood with moodType=STAR is an idempotent SET operation, not a toggle
- Tested: all moodType variations, moodStarShortcut param, 9 alternative
  endpoints — none could remove a like
- Service Worker in the web app prevents intercepting the real unlike payload
- like=False now returns a clear error; like=True continues to work correctly
- SPEC.md updated with full investigation notes and ruled-out approaches

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 16:02:08 +02:00
marcus a3274b349a fix: use moodType=STAR for wallmood, parse moodMap from response (v0.4.4)
FW_DEBUG=1 verification revealed:
- moodType "LIKE" was silently mapped to "STAR" server-side; use "STAR" directly
- Response a00.r.r contains full wall object with moodMap showing actual like state
- liked status now derived from moodMap rather than echoing the input bool
- SPEC.md updated with fully verified wallmood endpoint details

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:48:54 +02:00
marcus 9534658472 fix: correct wallmood parameter name to wall_message_id (v0.4.3)
API error message confirmed the expected parameter is 'wall_message_id',
not 'wallId'. SPEC.md updated to reflect verified finding.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:37:53 +02:00
marcus c412c24c86 feat: add like_post tool via wallmood endpoint (v0.4.2)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:32:12 +02:00
marcus 61e0d63931 fix: correct parameter names for taskmark (taskId) and metadelete (id)
Verified via FW_DEBUG=1: taskmark expects 'taskId' (not 'metaId'),
metadelete expects 'id' (not 'metaId'). Wrong names caused silent
no-ops because the API wraps errors in a00.un.un instead of top-level
un/ex, bypassing the standard error check in fw_client.

Also documents verified response structures in SPEC.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:17:45 +02:00
marcus 5aff3ac9bf feat: add Task CRUD tools – create, update, toggle, delete (v0.4.0)
Implements four new MCP write tools via taskcreate2, taskupdate2,
taskmark, and metadelete endpoints. Confirmation prompts noted in
docstrings for destructive/mutating operations. Body parameters
documented in SPEC.md as pending verification via FW_DEBUG=1.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-15 15:06:38 +02:00
marcus 332b01718e fix: correct get_activities field mapping, document wallget response (v0.3.2) 2026-04-15 14:47:59 +02:00
marcus 8276647fcf feat: add get_activities tool via wallget endpoint (v0.3.0) 2026-04-15 14:15:20 +02:00
marcus c954a245ca feat: use taskgettasklists endpoint for get_lists (v0.2.4) 2026-04-15 14:05:58 +02:00
marcus 8cf707e3bd fix: extract list IDs from sortingIndexByTaskList, remove tasklistsync (v0.2.2) 2026-04-15 13:38:52 +02:00