Skip to content

feat: create calendars without inviting members - #35

Merged
ehs208 merged 8 commits into
ehs208:mainfrom
daylight55:codex/calendar-migration
Oct 7, 2026
Merged

ehs208 merged 8 commits into
ehs208:mainfrom
daylight55:codex/calendar-migration

Conversation

@daylight55

@daylight55 daylight55 commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Description

Add create_calendar to create a calendar with an explicit name and purpose, without inviting members. Calendar creation uses the existing throttled request path and authentication recovery. Rejected requests may retry; timeouts and server errors are not retried.

Invalid input returns safe field-level reasons, authentication failures return a distinct message, and uncertain failures tell the client to check existing calendars before retrying. Successful responses contain only calendar ID, name, and alias code.

Changes

  • Strict input schema requiring both name and purpose; no default calendar purpose.
  • Reuse existing rate limiting, authentication, and CSRF handling, with safe 403 mapping.
  • Add coverage for 429 recovery, no retries on timeout/5xx, authentication errors, validation privacy, and output shape.
  • Update English, Japanese, and Korean README files, COMMANDS.md, CHANGELOG.md, project guidance, and desktop extension manifest.
  • Merge current main and refresh locked MCP SDK/proxy-addr versions to resolve current high/critical dependency audit findings.

Validation

  • Fresh detached checkout with current main included: npm ci && npm run verify passes on Node 22 and 24.
  • 60 tests pass on each runtime; type checking, build, and high-severity dependency audit pass.
  • GitHub Actions CI passed on Node 22 and 24 for commit 974c7bf (run 37591429752).
  • Uses only mock fixtures. No account credentials or personal calendar data are used in this revision.

ehs208 and others added 2 commits October 1, 2026 20:46
Picks up the lockfile refresh from ehs208#36 so this PR no longer carries it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add the missing Korean README entries, use a distinct emoji from
Create Events, list calendar creation in the project guide, and drop the
Security changelog entry now that ehs208#36 ships the lockfile refresh.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@ehs208 ehs208 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. The direction fits the project well: creating a calendar with no invitations, a strict input schema, and avoiding responses that leak upstream payloads.

I pushed two commits to your branch (thanks for allowing maintainer edits), so please pull before you push again:

  • Merged main. #36 shipped the same lockfile refresh, so package-lock.json no longer appears in this diff.
  • Synced the docs: added the Korean README entries, changed the emoji to 🗓️ so it differs from Create Events, listed calendar creation in CLAUDE.md, and removed the ### Security changelog entry because #36 covers it.

A few code changes are needed before merge:

1. Use the rate limiter (src/client/api.ts)
createCalendar is the only write that skips rateLimiter.executeWithRetry, so it also skips request throttling. The retry concern doesn't apply here: executeWithRetry retries only on 429, which means the server rejected the request without processing it, so a retry cannot create a duplicate. Timeouts and 5xx errors are thrown immediately. Please wrap the POST like createEvent does, and map 403 to TimeTreeAPIError the same way. Your existing "called once on failure" test still passes after this change.

2. Make errors distinguishable (src/tools/calendar-tools.ts)
Keeping upstream bodies and submitted names out of responses is the right goal. However, the bare catch {} currently gives a name over 20 characters, an invalid purpose, and an auth failure the same message ("Check existing calendars before retrying"), so the client can't tell what to fix. Suggested handling:

  • ZodError: report which field is invalid and why, without echoing the value.
  • 403 or auth failure: return "Authentication failed".
  • Anything else: keep your current message, which fits timeouts well, and add logger.error('Tool: create_calendar failed', { error }). The shared logger masks sensitive fields.

Please don't reuse commonWriteError from event-crud-tools.ts as is. Its 404 branch says "Event not found", and its fallback forwards error.message.

3. Make purpose required
With a default of lover, a request like "make me a calendar" silently creates a couple calendar for a work or personal use case. Requiring purpose (drop the default and add it to required) makes the client choose one explicitly.

Nits (optional):

  • A one-line comment on this.authManager.getCsrfToken(); saying it is a precondition check would help.
  • A handler-level test would be nice: valid input returns only {id, name, alias_code}, and invalid input returns isError.

Resolve CHANGELOG and api-client test conflicts from ehs208#37-ehs208#39 by keeping
both sides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ehs208

ehs208 commented Oct 2, 2026

Copy link
Copy Markdown
Owner

I merged main into this branch to resolve conflicts with #37–#39 (CHANGELOG.md and tests/api-client.test.mjs, keeping both sides; npm run verify passes). Please pull before pushing again.

Since this PR started, main has changed in a few ways that may help with the review items:

  • Every tool now accepts calendar_id as a string or number (src/tools/shared-schemas.ts).
  • CI runs on Node 22 and 24.
  • AGENTS.md (a symlink to CLAUDE.md) now has a Code Review Rules section.

The earlier review items (rate limiter, distinguishable errors, required purpose) are still open.

@daylight55

Copy link
Copy Markdown
Contributor Author

Addressed the three review items and optional test/comment suggestions in 974c7bf:

  1. Calendar creation now uses the shared send path from current main, including rateLimiter.executeWithRetry, authentication recovery, and safe 403 mapping. Regression tests confirm 429 retry and one attempt for timeout/5xx failures.
  2. Validation errors identify the invalid field and reason without echoing supplied values. Authentication failures have a distinct response; other failures retain the uncertain-creation guidance and use the shared masked logger.
  3. purpose is required in both the Zod and MCP schemas; the lover default is removed.

Added handler tests for strict validation, response shape, and error privacy, plus a CSRF precondition comment. Merged current main, preserved its revised READMEs, and added the tool to the desktop extension manifest. Refreshed the locked MCP SDK/proxy-addr versions because current audits otherwise reported high/critical advisories.

Validation: a clean detached checkout passes npm ci && npm run verify on Node 22 and 24 (60 tests each), and GitHub CI passed on both runtimes: https://github.com/ehs208/TimeTree-MCP/actions/runs/37591429752

Ready for another review.

@daylight55

Copy link
Copy Markdown
Contributor Author

Follow-up to my previous review update: pushed 4eb58de with three additional fixes.

  • Prevent authentication recovery from resending HTTP 5xx responses, even when the response body contains a session or CSRF error code. Calendar creation still retries rejected authentication once and preserves the existing 429 handling.
  • Separate input validation from the write operation. If the POST succeeds but its response fails schema validation, the tool now reports an uncertain creation outcome and asks the caller to check existing calendars before retrying, rather than reporting invalid input.
  • Normalize persistent TimeTree authentication rejections (400 / -493 and 422 / -1, as well as 401) to Authentication failed after the single recovery attempt, without exposing upstream details.

Added regression tests for 500/502/503/504 with both authentication error codes, successful authentication recovery, invalid success responses, and persistent authentication rejection. The only shared-client behavior change is the guard against authentication retries on server errors; the remaining changes cover calendar creation, tests, and matching documentation.

Validation:

  • Clean checkout including the latest main: npm ci && npm run verify passed on Node 22.22.0 and 24.5.0, with 64 tests passing on each. Typecheck, build, and the CI audit threshold passed.
  • Desktop extension build and stdio initialization, tools/list, and invalid-input handling passed.
  • GitHub CI passed for both Node 22 and 24 on this commit: run 37601083403.
  • All TimeTree behavior tests used synthetic fixtures and mocked HTTP clients; no live account was used.

@codex review

@daylight55
daylight55 requested a review from ehs208 October 7, 2026 10:47

@ehs208 ehs208 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the follow-up. I reviewed 4eb58de: skipping re-authentication on 5xx, separating input validation from the write so a bad success response reports an uncertain outcome, and normalizing persistent auth rejections all look right. npm run verify (64 tests) and npm run build:mcpb pass locally. Approving.

@ehs208
ehs208 merged commit aef7dd9 into ehs208:main Oct 7, 2026
2 checks passed
@ehs208 ehs208 mentioned this pull request Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants