← 返回
安全合规 Key

Ms Todo Oauth

Manage Microsoft To Do lists and tasks through a local Python CLI backed by Microsoft Graph OAuth. Use when an agent needs to inspect, add, complete, delete,...
通过本地 Python CLI(由 Microsoft Graph OAuth 支持)管理 Microsoft ToDo 列表和任务。适用于代理需要检查、添加、完成、删除等操作的场景。
nathanatgit
安全合规 clawhub v1.0.5 2 版本 99931.4 Key: 需要
★ 1
Stars
📥 1,437
下载
💾 24
安装
2
版本
#latest

概述

ms-todo-oauth

A fully-tested Microsoft To Do command-line client for managing tasks and lists via Microsoft Graph API.

Security and OAuth App Credentials

This skill uses OAuth authorization-code login through Microsoft Graph. The script has built-in fallback Azure app credentials, but agents should prefer caller-provided credentials when available. Treat any committed client secret as public and rotate or revoke it before distributing this skill for sensitive accounts.

Credential precedence:

  1. Global CLI options: --client-id, --client-secret, --tenant-id
  2. Environment variables: MS_TODO_CLIENT_ID, MS_TODO_CLIENT_SECRET, MS_TODO_TENANT_ID
  3. Built-in fallback values in scripts/ms-todo-oauth.py

Recommended handling:

  1. Register your own app at portal.azure.com: Microsoft Entra ID > App registrations > New registration.
  2. For personal Microsoft accounts only, select "Personal Microsoft accounts only". For broader use, select the account type that matches your target users.
  3. Add Microsoft Graph delegated permission Tasks.ReadWrite; add Tasks.ReadWrite.Shared only if shared-list access is needed.
  4. Generate a client secret under Certificates & secrets.
  5. Set MS_TODO_CLIENT_ID and MS_TODO_CLIENT_SECRET, or pass --client-id and --client-secret before the subcommand.
  6. If the existing secret has been published, rotate or revoke it in Azure.

Do not print or paste client secrets in user-facing responses or logs.

✨ Features

  • Full Task Management: Create, complete, delete, and search tasks
  • 🗂️ List Organization: Create and manage multiple task lists
  • Rich Task Options: Priorities, due dates, reminders, descriptions, tags
  • 🔄 Recurring Tasks: Daily, weekly, monthly patterns with custom intervals
  • 📊 Multiple Views: Today, overdue, pending, statistics
  • 🔍 Powerful Search: Find tasks across all lists
  • 💾 Data Export: Export all tasks to JSON
  • 🧪 Fully Tested: 33 comprehensive automated tests
  • 🌐 Unicode Support: Full support for Chinese characters and emojis

Prerequisites

  1. Python >= 3.9 must be installed
  2. Dependencies from requirements.txt: msal and requests
  3. Working directory: All commands MUST be run from the root of this skill (the directory containing this SKILL.md file)
  4. Network access: Requires internet access to Microsoft Graph API endpoints
  5. Microsoft Account: Personal Microsoft account (Hotmail, Outlook.com) or work/school account
  6. Authentication: First-time use requires OAuth2 login via browser. See Authentication section
    • Token cache: ~/.mstodo_token_cache.json (persists across sessions, auto-refreshed)

Installation & Setup

First-Time Setup

Before using this skill for the first time, dependencies must be installed. This repository does not include pyproject.toml or uv.lock, so do not use uv sync unless those files are added later.

# Navigate to skill directory
cd <path-to-ms-todo-oauth>

# Install dependencies into the active Python/Conda environment
python -m pip install -r requirements.txt

# Optional: set your own Azure app credentials for the current PowerShell session
$env:MS_TODO_CLIENT_ID = "<your-client-id>"
$env:MS_TODO_CLIENT_SECRET = "<your-client-secret>"
$env:MS_TODO_TENANT_ID = "consumers"

# Optional uv one-shot without a project file
uv run --with-requirements requirements.txt python scripts/ms-todo-oauth.py --help

Dependencies:

  • msal (Microsoft Authentication Library) - Official Microsoft OAuth library
  • requests - HTTP client for API calls
  • Specified in requirements.txt

Environment Verification

After installation, verify the setup:

# Check if Python can import dependencies and load the script
python scripts/ms-todo-oauth.py --help

# Expected: Command help text should be displayed

Troubleshooting:

  • If Python not found, install Python 3.9 or higher or activate the environment where dependencies were installed.
  • If script fails with import errors, run python -m pip install -r requirements.txt in the same environment used to run the script.

Testing (Optional but Recommended)

Verify all functionality works correctly:

# Run comprehensive automated test suite (33 tests)
python scripts/test_ms_todo_oauth.py

# Run only non-destructive CLI/configuration checks
python scripts/test_ms_todo_oauth.py --preflight-only

# Expected: All tests pass (100% pass rate)

See Testing section for details.

Security Notes

  • Uses official Microsoft Graph API via Microsoft's msal library
  • All code is plain Python (.py files), readable and auditable
  • Tokens stored locally in ~/.mstodo_token_cache.json
  • All API calls go directly to Microsoft endpoints (graph.microsoft.com)
  • OAuth2 standard authentication flow
  • No third-party services involved

Command Reference

All commands follow this pattern:

python scripts/ms-todo-oauth.py [GLOBAL_OPTIONS] <command> [COMMAND_OPTIONS]

Global Options

OptionDescription
----------------------------------------------------------------------------------------------------------------------------------------------------
-v, --verboseShow detailed information (IDs, dates, notes).Must be placed BEFORE the subcommand.
--debugEnable debug mode to display API requests and responses. Useful for troubleshooting.Must be placed BEFORE the subcommand.
--reauthForce re-authentication by clearing the token cache and starting fresh login
--client-idAzure app client ID. Overrides MS_TODO_CLIENT_ID and the built-in fallback. Must be placed BEFORE the subcommand.
--client-secretAzure app client secret. Overrides MS_TODO_CLIENT_SECRET and the built-in fallback. Must be placed BEFORE the subcommand.
--tenant-idAzure tenant ID or account type. Defaults to MS_TODO_TENANT_ID or consumers. Must be placed BEFORE the subcommand.

> ⚠️ Common mistake: Global options MUST come before the subcommand.

>

> - ✅ python scripts/ms-todo-oauth.py -v lists

> - ✅ python scripts/ms-todo-oauth.py --debug add "Task"

> - ✅ python scripts/ms-todo-oauth.py --client-id "" --client-secret "" lists

> - ❌ python scripts/ms-todo-oauth.py lists -v


Authentication

Authentication uses OAuth2 authorization code flow, designed for both interactive and automated environments.

login get — Get OAuth2 authorization URL

python scripts/ms-todo-oauth.py login get

Output example:

======================================================================
🔐 OAuth2 Authorization Required
======================================================================

Please visit the following URL to authorize the application:

  https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?...

After authorization, you will be redirected to a callback URL.
Copy the `code` parameter from the callback URL and run:

  python scripts/ms-todo-oauth.py login verify <authorization_code>

======================================================================

What to do:

  1. Open the provided URL in your browser
  2. Sign in with your Microsoft account
  3. Grant permissions when prompted
  4. You'll be redirected to a URL like: http://localhost:8000/callback?code=M.R3_BAY.abc123...
  5. If the browser shows that localhost:8000 cannot be reached, that is expected.
  6. Copy either the full callback URL or the entire code value after code=.
  7. Quote the value in the shell because Microsoft authorization codes can contain punctuation.

Agent behavior: Present the URL to the user and explain they need to:

  1. Visit the URL
  2. Complete the login
  3. Copy the authorization code from the callback URL
  4. Provide it to you

login verify — Complete login with authorization code

python scripts/ms-todo-oauth.py login verify "<authorization_code_or_callback_url>"

Example:

python scripts/ms-todo-oauth.py login verify "M.R3_BAY.abc123def456..."
python scripts/ms-todo-oauth.py login verify "http://localhost:8000/callback?code=M.R3_BAY.abc123def456..."

Output on success:

✓ Authentication successful!
✓ Login information saved, you will be logged in automatically next time.

Output on failure:

❌ Token acquisition failed
Error: invalid_grant
Description: AADSTS54005: OAuth2 Authorization code was already redeemed...

Exit code: 0 on success, 1 on failure.

Important notes:

  • Each authorization code can only be used ONCE
  • If verification fails, you need to run login get again to get a new code
  • Once successfully logged in, the token is cached and you won't need to login again unless:
  • You run logout
  • You run --reauth
  • The token expires and cannot be auto-refreshed

logout — Clear saved login

python scripts/ms-todo-oauth.py logout

Output: ✓ Login information cleared

Only use when the user explicitly asks to switch accounts or clear login data. Under normal circumstances, the token is cached and login is automatic.


List Management

lists — List all task lists

python scripts/ms-todo-oauth.py lists
python scripts/ms-todo-oauth.py -v lists  # with IDs and creation dates

Output example:

📋 Task Lists (3 total):

1. 任务
   ID: AQMkADAwATYwMAItYTQwZC04OThhLTAwAi0wMAoALgAAA0QJKpxW32BIsIlHaM...
   Created: 2024-12-15T08:30:00Z
2. Work
3. Shopping

create-list — Create a new list

python scripts/ms-todo-oauth.py create-list "<name>"
ArgumentRequiredDescription
---------------------------------------------------------------
nameYesName of the new list (supports Unicode/Chinese)

Example:

python scripts/ms-todo-oauth.py create-list "项目 A"

Output: ✓ List created: 项目 A

delete-list — Delete a list

python scripts/ms-todo-oauth.py delete-list "<name>" [-y]
Argument/OptionRequiredDescription
-------------------------------------------------
nameYesName of the list to delete
-y, --yesNoSkip confirmation prompt

> ⚠️ This is a destructive operation. Without -y, the command will prompt for confirmation. All tasks in the list will be deleted. Consider asking the user before deleting important lists.

Output: ✓ List deleted:

Exit code: 1 if list not found, 0 on success


Task Operations

add — Add a new task

python scripts/ms-todo-oauth.py add "<title>" [options]
OptionRequiredDefaultDescription
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
titleYesTask title (positional argument, supports Unicode/Chinese/emojis)
-l, --listNo(default list)Target list name. If not specified, uses your Microsoft To Do default list.
-p, --priorityNonormalPriority:low, normal, high
-d, --dueNoDue date. Accepts days from now (3 or 3d) or date (2026-02-15). Note: Only date is supported by Microsoft To Do API, not time.
-r, --reminderNoReminder datetime. Formats:3h (hours from now), 2d (days from now), 2026-02-15 14:30 (date+time with space, needs quotes), 2026-02-15T14:30:00 (ISO format), 2026-02-15 (date only, defaults to 09:00).
-R, --recurrenceNoRecurrence pattern. Formats:daily (every day), weekdays (Mon-Fri), weekly (every week), monthly (every month). With interval: daily:2 (every 2 days), weekly:3 (every 3 weeks), monthly:2 (every 2 months).
-D, --descriptionNoTask description/notes (supports multiline with quotes)
-t, --tagsNoComma-separated tags/categories (e.g.,"work,urgent")
--create-listNoFalseCreate the list if it doesn't exist (deprecated, lists auto-create now)

Auto-created lists: If the specified list doesn't exist, it will be automatically created.

Output example:

✓ Task added: Complete report

With recurrence:

✓ Task added: Daily standup
🔄 Recurring task created

Examples:

# Simple task
python scripts/ms-todo-oauth.py add "Buy milk" -l "Shopping"

# High priority task due in 3 days
python scripts/ms-todo-oauth.py add "Submit report" -l "Work" -p high -d 3

# Task with reminder in 2 hours
python scripts/ms-todo-oauth.py add "Call client" -r 2h

# Task with specific date and time reminder
python scripts/ms-todo-oauth.py add "Meeting" -d 2026-03-15 -r "2026-03-15 14:30"

# Daily recurring task
python scripts/ms-todo-oauth.py add "Daily standup" -l "Work" -R daily

# Weekday recurring task  
python scripts/ms-todo-oauth.py add "Gym" -R weekdays -l "Personal"

# Task with all options
python scripts/ms-todo-oauth.py add "Project Review" \
  -l "Work" \
  -p high \
  -d 7 \
  -r "2026-02-20 14:00" \
  -D "Review Q1 deliverables and prepare presentation" \
  -t "work,important,meeting"

# Chinese task with emoji
python scripts/ms-todo-oauth.py add "🎉 完成项目" -l "任务" -p high

complete — Mark a task as completed

python scripts/ms-todo-oauth.py complete "<title>" [-l "<list>"]
OptionRequiredDefaultDescription
--------------------------------------------------------------------
titleYesExact task title
-l, --listNo(default list)List name where the task resides

Title matching: Requires exact match. If unsure of exact title, use search first.

Output: ✓ Task completed: </code></p><p><strong>Exit code</strong>: 1 if task not found, 0 on success</p><h4><code>delete</code> — Delete a task</h4><pre><code>python scripts/ms-todo-oauth.py delete "<title>" [-l "<list>"] [-y] </code></pre><table><thead><tr><th>Option</th><th>Required</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td>--------------</td><td>--------</td><td>--------------</td><td>--------------------------------</td></tr><tr><td><code>title</code></td><td>Yes</td><td>—</td><td><strong>Exact</strong> task title</td></tr><tr><td><code>-l, --list</code></td><td>No</td><td>(default list)</td><td>List name where the task resides</td></tr><tr><td><code>-y, --yes</code></td><td>No</td><td>—</td><td>Skip confirmation prompt</td></tr></tbody></table><p>> ⚠️ <strong>Destructive operation</strong>. Without <code>-y</code>, will prompt for confirmation.</p><p>Output: <code>✓ Task deleted: <title></code></p><p><strong>Exit code</strong>: 1 if task not found, 0 on success</p><hr><h3>Task Views</h3><h4><code>tasks</code> — List tasks in a specific list</h4><pre><code>python scripts/ms-todo-oauth.py tasks "<list>" [-a] </code></pre><table><thead><tr><th>Option</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td>-------------</td><td>--------</td><td>--------------------------------------------------</td></tr><tr><td><code>list</code></td><td>Yes</td><td>List name (exact match)</td></tr><tr><td><code>-a, --all</code></td><td>No</td><td>Include completed tasks (default: incomplete only)</td></tr></tbody></table><p><strong>Output example:</strong></p><pre><code>📋 Tasks in list "Work" (2 total): 1. [In Progress] Write documentation ⭐ 2. [In Progress] Review PR </code></pre><p><strong>With <code>-a</code> flag:</strong></p><pre><code>📋 Tasks in list "Work" (3 total): 1. [In Progress] Write documentation ⭐ 2. [Completed] Submit report 3. [In Progress] Review PR </code></pre><p><strong>Exit code</strong>: 1 if list not found, 0 on success</p><h4><code>pending</code> — All incomplete tasks across all lists</h4><pre><code>python scripts/ms-todo-oauth.py pending [-g] </code></pre><table><thead><tr><th>Option</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td>---------------</td><td>--------</td><td>---------------------</td></tr><tr><td><code>-g, --group</code></td><td>No</td><td>Group results by list</td></tr></tbody></table><p><strong>Output example (with <code>-g</code>):</strong></p><pre><code>📋 All incomplete tasks (3 total): 📂 Work: [In Progress] Write documentation ⭐ [In Progress] Review PR 📂 Shopping: [In Progress] Buy groceries </code></pre><p><strong>Without <code>-g</code>:</strong></p><pre><code>📋 All incomplete tasks (3 total): [In Progress] Write documentation ⭐ List: Work [In Progress] Review PR List: Work [In Progress] Buy groceries List: Shopping </code></pre><h4><code>today</code> — Tasks due today</h4><pre><code>python scripts/ms-todo-oauth.py today </code></pre><p>Lists incomplete tasks with due date matching today's date.</p><p><strong>Output example:</strong></p><pre><code>📅 Tasks due today (2 total): [In Progress] Submit report ⭐ List: Work [In Progress] Buy groceries List: Shopping </code></pre><p>If no tasks: <code>📅 No tasks due today</code></p><h4><code>overdue</code> — Overdue tasks</h4><pre><code>python scripts/ms-todo-oauth.py overdue </code></pre><p>Lists incomplete tasks past their due date, sorted by days overdue.</p><p><strong>Output example:</strong></p><pre><code>⚠️ Overdue tasks (1 total): [In Progress] Submit report ⭐ List: Work Overdue: 3 days </code></pre><p>If no overdue tasks: <code>✓ No overdue tasks</code></p><h4><code>detail</code> — View full task details</h4><pre><code>python scripts/ms-todo-oauth.py detail "<title>" [-l "<list>"] </code></pre><table><thead><tr><th>Option</th><th>Required</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td>--------------</td><td>--------</td><td>--------------</td><td>--------------------------------------------------</td></tr><tr><td><code>title</code></td><td>Yes</td><td>—</td><td>Task title (supports<strong>partial/fuzzy match</strong>)</td></tr><tr><td><code>-l, --list</code></td><td>No</td><td>(default list)</td><td>List name</td></tr></tbody></table><p><strong>Fuzzy matching</strong>: Matches tasks containing the search string (case-insensitive).</p><p>When multiple tasks match:</p><ul><li>Prefers <strong>incomplete</strong> tasks over completed</li><li>Returns most recently modified task</li></ul><p><strong>Output example:</strong></p><pre><code>============================================================ 📌 Task Details ============================================================ 📋 Title: Complete Q1 Report 🔖 Status: [In Progress] ⚡ Priority: ⭐ High 📅 Created: 2026-01-15 08:30:00 📝 Modified: 2026-02-10 14:22:00 ⏰ Due: 2026-02-20 00:00:00 🔔 Reminder: 2026-02-20 09:00:00 📝 Notes: - Review sales figures - Include charts - Prepare for board meeting 🏷️ Categories: work, important, Q1 🔄 Recurrence: Every week on Monday Start date: 2026-02-17 No end date ============================================================ </code></pre><h4><code>search</code> — Search tasks by keyword</h4><pre><code>python scripts/ms-todo-oauth.py search "<keyword>" </code></pre><p>Searches across <strong>all lists</strong> in both task titles and descriptions (case-insensitive).</p><p><strong>Output example:</strong></p><pre><code>🔍 Search results for "report" (2 found): [In Progress] Complete Q1 Report ⭐ List: Work Notes: Review sales figures... [Completed] Submit weekly report List: Work </code></pre><h4><code>stats</code> — Task statistics</h4><pre><code>python scripts/ms-todo-oauth.py stats </code></pre><p>Shows aggregate statistics across all lists.</p><p><strong>Output example:</strong></p><pre><code>📊 Task Statistics: Total lists: 3 Total tasks: 15 Completed: 10 Pending: 5 High priority: 2 Overdue: 1 Completion rate: 66.7% </code></pre><h4><code>export</code> — Export all tasks to JSON</h4><pre><code>python scripts/ms-todo-oauth.py export [-o "<filename>"] </code></pre><table><thead><tr><th>Option</th><th>Required</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td>----------------</td><td>--------</td><td>--------------------</td><td>----------------</td></tr><tr><td><code>-o, --output</code></td><td>No</td><td><code>todo_export.json</code></td><td>Output file path</td></tr></tbody></table><p>Exports complete task data from all lists in JSON format.</p><p><strong>Output:</strong> <code>✓ Tasks exported to: <filename></code></p><p><strong>JSON structure:</strong></p><pre><code>{ "Work": [ { "id": "AQMkADAwATYwMAItYTQw...", "title": "Complete report", "status": "notStarted", "importance": "high", "createdDateTime": "2026-01-15T08:30:00Z", "dueDateTime": { "dateTime": "2026-02-20T00:00:00.0000000", "timeZone": "UTC" }, "body": { "content": "Review Q1 numbers", "contentType": "text" }, "categories": ["work", "important"] } ], "Shopping": [...] } </code></pre><hr><h2>Error Handling</h2><h3>Exit Codes</h3><table><thead><tr><th>Code</th><th>Meaning</th></tr></thead><tbody><tr><td>-----</td><td>-------------------------------------------------------------------------</td></tr><tr><td><code>0</code></td><td>Success</td></tr><tr><td><code>1</code></td><td>Failure (not logged in, API error, invalid arguments, resource not found)</td></tr><tr><td><code>2</code></td><td>Invalid command-line arguments</td></tr></tbody></table><h3>Common Error Messages</h3><table><thead><tr><th>Error</th><th>Cause</th><th>Resolution</th></tr></thead><tbody><tr><td>-----------------------------------------------</td><td>---------------------------------</td><td>---------------------------------------------------------------------------</td></tr><tr><td><code>❌ Not logged in</code></td><td>No cached token or token expired</td><td>Run <code>login get</code> then <code>login verify <code></code></td></tr><tr><td><code>ModuleNotFoundError: No module named 'msal'</code></td><td>Dependencies not installed</td><td>Run <code>python -m pip install -r requirements.txt</code> or <code>pip install -r requirements.txt</code></td></tr><tr><td><code>❌ List not found: <name></code></td><td>Specified list does not exist</td><td>Check list name with <code>lists</code> command. Note: exact match required.</td></tr><tr><td><code>❌ Task not found: <name></code></td><td>No task with exact matching title</td><td>Use <code>search</code> to find exact title, or <code>tasks "<list>"</code> to list all tasks</td></tr><tr><td><code>❌ Error: Invalid isoformat string</code></td><td>DateTime parsing error</td><td>This should not occur in the current unreleased maintenance state. If you see this, report as bug.</td></tr><tr><td><code>❌ Error: Unsupported HTTP method</code></td><td>Internal API error</td><td>This should not occur in the current unreleased maintenance state. If you see this, report as bug.</td></tr><tr><td><code>❌ Error: <API error message></code></td><td>Microsoft Graph API error</td><td>Retry; check network; use <code>--debug</code> for full details</td></tr><tr><td><code>Network error</code> / <code>Connection timeout</code></td><td>No internet or API unreachable</td><td>Check network connection; verify access to graph.microsoft.com</td></tr></tbody></table><hr><h2>Testing</h2><p>This skill includes a comprehensive test suite to ensure reliability.</p><h3>Automated Testing</h3><p>Run the full test suite:</p><pre><code>cd <skill-directory> python scripts/test_ms_todo_oauth.py </code></pre><p>Run only non-destructive CLI/configuration checks:</p><pre><code>python scripts/test_ms_todo_oauth.py --preflight-only </code></pre><p><strong>Prerequisites:</strong></p><ul><li>Must be authenticated (logged in) before running tests</li><li>Internet connection required</li><li>Approximately 2-3 minutes to complete</li></ul><p><strong>Test Coverage</strong> (33 tests):</p><ul><li>✅ Authentication (login/logout)</li><li>✅ CLI setup, credential override, and authorization-code normalization preflight checks</li><li>✅ List management (create, delete, list)</li><li>✅ Basic task operations (add, complete, delete, list)</li><li>✅ Task options (priorities, due dates, reminders, descriptions, tags)</li><li>✅ Recurring tasks (daily, weekly, weekdays, monthly, custom intervals)</li><li>✅ Task views (today, overdue, pending, search, stats)</li><li>✅ Data export and validation</li><li>✅ Error handling (non-existent resources)</li><li>✅ Unicode support (Chinese characters, emojis)</li></ul><p><strong>Expected output:</strong></p><pre><code>======================================================================== TEST SUMMARY ======================================================================== Total tests: 33 Passed: 29 Failed: 0 Pass rate: 100.0% ======================================================================== 🎉 ALL TESTS PASSED! 🎉 ======================================================================== </code></pre><h3>Manual Testing</h3><p>For manual verification, see <code>MANUAL_TEST_CHECKLIST.txt</code> which provides:</p><ul><li>Step-by-step test procedures</li><li>Expected outcomes</li><li>9 test categories covering all functionality</li></ul><h3>Test Cleanup</h3><p>The automated test suite:</p><ul><li>Creates a temporary test list (e.g., <code>🧪 Test List 14:23:45</code>)</li><li>Runs all tests in isolation</li><li>Deletes the test list on completion</li><li>Cleans up any temporary files</li></ul><p>If tests are interrupted, you may need to manually delete leftover test lists.</p><hr><h2>Agent Usage Guidelines</h2><h3>Critical Rules</h3><ol><li><strong>Working directory</strong>: Always <code>cd</code> to the directory containing this SKILL.md before running commands.</li><li><strong>Dependency installation</strong>: Before first use or when encountering import errors, run <code>python -m pip install -r requirements.txt</code> to ensure all dependencies are installed.</li><li><strong>Check authentication first</strong>: Before any operation, verify authentication status:</li></ol><p> ```bash</p><p> python scripts/ms-todo-oauth.py lists</p><p> ```</p><p> If this returns "Not logged in" error (exit code 1), initiate the login flow.</p><ol><li><strong>Task list organization</strong>: When adding tasks:</li></ol><ul><li>First, run <code>lists</code> to see available task lists</li><li>If user doesn't specify a list, tasks will be added to their <strong>default list</strong> (usually "Tasks" or "任务")</li><li>Intelligently categorize tasks into appropriate lists:</li><li>Work tasks → "Work" list</li><li>Personal errands → "Personal" or default list</li><li>Shopping → "Shopping" list</li><li>Project-specific → Use project name as list</li><li>Lists will be auto-created if they don't exist</li><li>Support Chinese list names and Unicode characters</li></ul><ol><li><strong>Destructive operations</strong>: For <code>delete</code> and <code>delete-list</code>:</li></ol><ul><li>These commands prompt for confirmation by default (blocking behavior)</li><li>Use <code>-y</code> flag ONLY when:</li><li>User has explicitly requested to delete without confirmation</li><li>The deletion intent is unambiguous and confirmed through conversation</li><li>When in doubt, ask the user for confirmation instead of using <code>-y</code></li><li>These operations return exit code 1 on failure (resource not found)</li></ul><ol><li><strong>Global option placement</strong>: <code>-v</code>, <code>--debug</code>, <code>--reauth</code>, <code>--client-id</code>, <code>--client-secret</code>, and <code>--tenant-id</code> must come BEFORE the subcommand:</li></ol><ul><li>✅ <code>python scripts/ms-todo-oauth.py -v lists</code></li><li>✅ <code>python scripts/ms-todo-oauth.py --client-id "<id>" --client-secret "<secret>" lists</code></li><li>❌ <code>python scripts/ms-todo-oauth.py lists -v</code></li></ul><ol><li><strong>Login flow</strong>:</li></ol><ul><li>Do NOT call <code>login verify</code> until user confirms they've completed browser authentication</li><li>Each authorization code can only be used once</li><li>If verify fails, you must run <code>login get</code> again for a new code</li></ul><ol><li><strong>Error handling</strong>:</li></ol><ul><li>Check exit codes: 0 = success, 1 = failure, 2 = invalid arguments</li><li>Parse error messages to provide helpful guidance</li><li>Use <code>--debug</code> flag when troubleshooting API issues</li></ul><h3>Recommended Workflow for Agents</h3><pre><code>Step 1: Setup and Authentication Check --------------------------------------- cd <skill_directory> python -m pip install -r requirements.txt # Ensure dependencies (first time only) python scripts/ms-todo-oauth.py lists # Test auth & see available lists If exit code is 1 and output contains "Not logged in": a. python scripts/ms-todo-oauth.py login get b. Present URL to user c. Explain: "Visit this URL, login, and copy the 'code' parameter from callback URL" d. Wait for user to provide authorization code e. python scripts/ms-todo-oauth.py login verify "<code>" f. Verify success (exit code 0) Step 2: Task Analysis and List Selection ----------------------------------------- When user requests to add task(s): a. Analyze task context from user's description b. Review available lists (from Step 1 output) c. Choose appropriate list or use default: - Work-related → "Work" - Personal errands → "Personal" or default - Shopping items → "Shopping" - Project-specific → "<ProjectName>" d. If list doesn't exist, it will be auto-created Step 3: Execute Operation -------------------------- Add task with appropriate options: python scripts/ms-todo-oauth.py add "Task Title" \ -l "Work" \ -p high \ -d 3 \ -r 2h \ -D "Detailed description" \ -t "tag1,tag2" Step 4: Verify and Report -------------------------- Check exit code: - 0: Success → Confirm to user - 1: Failure → Parse error, provide guidance - 2: Invalid args → Fix command syntax Optionally verify: python scripts/ms-todo-oauth.py tasks "<list>" # Show updated list </code></pre><h3>Task Title Matching Rules</h3><ul><li><strong>Exact match required</strong>: <code>complete</code>, <code>delete</code> commands</li><li><strong>Partial/fuzzy match supported</strong>: <code>detail</code>, <code>search</code> commands</li><li><strong>Case-insensitive</strong>: All search operations</li><li><strong>Best practice</strong>: Use <code>search</code> first to find exact title, then use it in subsequent commands</li></ul><p><strong>Example workflow:</strong></p><pre><code># Find task with fuzzy search python scripts/ms-todo-oauth.py search "report" # Output shows: "Complete Q1 Report" # Use exact title from search results python scripts/ms-todo-oauth.py complete "Complete Q1 Report" -l "Work" </code></pre><h3>Default List Behavior</h3><ul><li>When <code>-l</code> is not specified, operations use the Microsoft To Do default list</li><li>The default list is typically named "Tasks" (English) or "任务" (Chinese)</li><li>To target a specific list, always provide <code>-l "<ListName>"</code></li></ul><h3>Example Task Categorization</h3><p><strong>User request:</strong> "Add these tasks: buy milk, finish report, call dentist"</p><p><strong>Agent approach:</strong></p><pre><code># First check available lists python scripts/ms-todo-oauth.py lists # Categorize intelligently: python scripts/ms-todo-oauth.py add "Buy milk" -l "Shopping" python scripts/ms-todo-oauth.py add "Finish report" -l "Work" -p high -d 2 python scripts/ms-todo-oauth.py add "Call dentist" -l "Personal" # Or use default list if no specific context: add "Call dentist" </code></pre><hr><h2>Quick Reference</h2><h3>Common Workflows</h3><p><strong>Daily task review:</strong></p><pre><code>python scripts/ms-todo-oauth.py today # Check today's tasks python scripts/ms-todo-oauth.py overdue # Check overdue tasks python scripts/ms-todo-oauth.py -v pending -g # Review all pending, grouped </code></pre><p><strong>Adding various task types:</strong></p><pre><code># Simple task (default list) python scripts/ms-todo-oauth.py add "Buy milk" # Work task with priority and deadline python scripts/ms-todo-oauth.py add "Quarterly review" -l "Work" -p high -d 7 # Task with reminder python scripts/ms-todo-oauth.py add "Call client" -r 3h # Detailed task with all options python scripts/ms-todo-oauth.py add "Project meeting" \ -l "Work" \ -p high \ -d 2026-03-15 \ -r "2026-03-15 14:30" \ -D "Discuss Q1 goals and resource allocation" \ -t "meeting,important,Q1" # Recurring tasks python scripts/ms-todo-oauth.py add "Daily standup" -R daily -l "Work" python scripts/ms-todo-oauth.py add "Weekly review" -R weekly -d 7 python scripts/ms-todo-oauth.py add "Gym" -R weekdays -l "Personal" python scripts/ms-todo-oauth.py add "Monthly report" -R monthly -p high </code></pre><p><strong>Task completion workflow:</strong></p><pre><code># Search for task python scripts/ms-todo-oauth.py search "report" # Complete using exact title from search results python scripts/ms-todo-oauth.py complete "Quarterly review" -l "Work" </code></pre><p><strong>Data management:</strong></p><pre><code># Export for backup python scripts/ms-todo-oauth.py export -o "backup_$(date +%Y%m%d).json" # View statistics python scripts/ms-todo-oauth.py stats </code></pre><hr><h2>Changelog</h2><h3>Unreleased</h3><ul><li>Normalize <code>login verify</code> input so URL-encoded codes and full callback URLs work</li><li>Added preflight coverage for authorization-code URL decoding and callback extraction</li><li>Updated login instructions to quote authorization codes in the shell</li><li>Added non-destructive preflight tests for help output and credential resolution</li><li>Added <code>--preflight-only</code> mode for safe local verification without live To Do changes</li><li>Updated documented test count to 33 tests</li><li>Added credential override support through CLI options and environment variables</li><li>Kept the existing built-in OAuth app credentials as fallback defaults</li><li>Made the skill description more agent-neutral for OpenClaw-style usage</li><li>Fixed setup workflow to match the existing <code>requirements.txt</code>-only package layout</li><li>Replaced stale <code>uv sync</code> guidance with active Python/Conda installation commands</li><li>Corrected automated test paths and OAuth callback guidance</li><li>Added stronger handling guidance for embedded OAuth app credentials</li></ul><h3>Version 1.0.5 (Current)</h3><ul><li>✅ <strong>Fixed</strong>: DateTime parsing errors (Microsoft's 7-decimal format)</li><li>✅ <strong>Fixed</strong>: HTTP method parameter order bugs</li><li>✅ <strong>Fixed</strong>: Missing <code>start_date</code> parameter in <code>create_task()</code></li><li>✅ <strong>Fixed</strong>: Missing <code>complete_task()</code> method</li><li>✅ <strong>Fixed</strong>: Error exit codes now correctly return 1 on failure</li><li>✅ <strong>Added</strong>: Comprehensive test suite (33 automated tests)</li><li>✅ <strong>Added</strong>: Better error messages and troubleshooting</li><li>✅ <strong>Improved</strong>: OAuth2 authentication flow documentation</li><li>✅ <strong>Improved</strong>: Unicode and emoji support documentation</li><li>✅ <strong>Improved</strong>: Agent usage guidelines</li></ul><h3>Version 1.0.2 (Previous)</h3><ul><li>Initial release with OAuth2 authentication</li><li>Basic task and list management</li><li>Recurring task support</li><li>Multiple task views</li><li>Data export functionality</li></ul><hr><h2>Troubleshooting</h2><h3>Authentication Issues</h3><p><strong>Problem:</strong> <code>❌ Not logged in</code></p><ul><li><strong>Solution</strong>: Run <code>login get</code>, complete browser flow, then <code>login verify <code></code></li></ul><p><strong>Problem:</strong> <code>❌ Token acquisition failed: invalid_grant</code></p><ul><li><strong>Cause</strong>: Authorization code already used or expired</li><li><strong>Solution</strong>: Run <code>login get</code> again to get a fresh code</li></ul><p><strong>Problem:</strong> Login worked but now getting "Not logged in" again</p><ul><li><strong>Cause</strong>: Token expired and auto-refresh failed</li><li><strong>Solution</strong>: Run <code>--reauth</code> to force fresh login:</li></ul><p> ```bash</p><p> python scripts/ms-todo-oauth.py --reauth lists</p><p> ```</p><h3>Import/Dependency Issues</h3><p><strong>Problem:</strong> <code>ModuleNotFoundError: No module named 'msal'</code></p><ul><li><strong>Solution</strong>: Install dependencies: <code>python -m pip install -r requirements.txt</code> or <code>pip install -r requirements.txt</code></li></ul><p><strong>Problem:</strong> <code>uv: command not found</code></p><ul><li><strong>Solution</strong>: Install uv: <code>pip install uv</code></li></ul><h3>API/Network Issues</h3><p><strong>Problem:</strong> Connection timeout or network errors</p><ul><li><strong>Check</strong>: Internet connection</li><li><strong>Check</strong>: Can you access https://graph.microsoft.com in browser?</li><li><strong>Try</strong>: Using <code>--debug</code> flag to see full API request/response</li></ul><p><strong>Problem:</strong> Unexpected API errors</p><ul><li><strong>Try</strong>: Re-authenticate: <code>python scripts/ms-todo-oauth.py --reauth lists</code></li><li><strong>Try</strong>: Debug mode: <code>python scripts/ms-todo-oauth.py --debug <command></code></li></ul><h3>Task/List Not Found</h3><p><strong>Problem:</strong> <code>❌ Task not found: <title></code></p><ul><li><strong>Solution</strong>: Use <code>search</code> to find exact title</li><li><strong>Note</strong>: <code>complete</code> and <code>delete</code> require exact title match</li></ul><p><strong>Problem:</strong> <code>❌ List not found: <name></code></p><ul><li><strong>Solution</strong>: Run <code>lists</code> to see exact list names</li><li><strong>Note</strong>: List names are case-sensitive</li></ul><h3>Test Failures</h3><p><strong>Problem:</strong> Tests failing with datetime errors</p><ul><li><strong>Solution</strong>: Ensure the current unreleased maintenance fixes are present</li><li><strong>Check</strong>: Verify <code>_parse_ms_datetime()</code> helper function exists</li></ul><p><strong>Problem:</strong> Tests failing with "Not logged in"</p><ul><li><strong>Solution</strong>: Authenticate before running tests:</li></ul><p> ```bash</p><p> python scripts/ms-todo-oauth.py login get</p><p> # Complete browser flow</p><p> python scripts/ms-todo-oauth.py login verify "<code-or-callback-url>"</p><p> # Then run tests</p><p> python scripts/test_ms_todo_oauth.py</p><p> ```</p><hr><h2>Additional Resources</h2><ul><li><strong>Test Suite</strong>: <code>scripts/test_ms_todo_oauth.py</code> - Automated tests</li><li><strong>Manual Tests</strong>: <code>scripts/MANUAL_TEST_CHECKLIST.txt</code> - Step-by-step testing guide</li><li><strong>Quick Reference</strong>: <code>scripts/QUICK_REFERENCE.txt</code> - Command cheat sheet</li></ul><hr><h2>Support & Contributing</h2><p><strong>Reporting Issues:</strong></p><ul><li>Provide error message and command used</li><li>Include output from <code>--debug</code> flag if applicable</li><li>Note your Python version: <code>python3 --version</code></li><li>Note your OS: Windows/Mac/Linux</li></ul><p><strong>Testing New Features:</strong></p><ul><li>Always run the test suite after code changes</li><li>Add new test cases to <code>scripts/test_ms_todo_oauth.py</code> for new features</li><li>Update <code>MANUAL_TEST_CHECKLIST.txt</code> with manual test procedures</li></ul><hr><h2>License</h2><p>MIT License - See LICENSE file for details</p><hr><p><strong>Version</strong>: 1.0.5</p><p><strong>Last Updated</strong>: 2026-02-13</p><p><strong>Status</strong>: ✅ Fully Tested & Production Ready</p></div> </div> </div> <div id="tab-versions" class="detail-content"> <div class="detail-section"> <h2>版本历史</h2> <p style="margin-bottom:12px;font-size:14px;color:#94a3b8;">共 2 个版本</p> <ul class="version-list"> <li> <div> <span class="version-tag">v1.0.5</span> <span style="font-size:11px;color:#5b6abf;margin-left:8px;background:#eef0ff;padding:1px 8px;border-radius:10px;">当前</span> </div> <div style="font-size:12px;color:#94a3b8;"> 2026-05-21 12:21 安全 安全 </div> </li> <li> <div> <span class="version-tag">v1.0.4</span> </div> <div style="font-size:12px;color:#94a3b8;"> 2026-03-29 03:36 安全 安全 </div> </li> </ul> </div> </div> <div id="tab-security" class="detail-content"> <div class="detail-section"> <h2>安全检测</h2> <div class="sec-grid"> <div class="sec-card"> <h4>腾讯云安全 (Keen)</h4> <div class="sec-status sec-safe"> 安全,无风险 </div> <a href="https://tix.qq.com/search/skill?keyword=33b23618b7006fc7bb81b568c56badba" target="_blank">查看报告</a> </div> <div class="sec-card"> <h4>腾讯云安全 (Sanbu)</h4> <div class="sec-status sec-safe"> 安全,无风险 </div> <a href="https://static.cloudsec.tencent.com/html-report-v2/2026/05/25/396208_74448c1fdcb328c812cd1dd7a0e7ad55.html?q-sign-algorithm=sha1&q-ak=AKID8JMG1bzBC1dz96qNhssfFftujT1NCoFi&q-sign-time=1781286634%3B1812822634&q-key-time=1781286634%3B1812822634&q-header-list=host&q-url-param-list=&q-signature=a781e676a76f5d43f44f55ec57b5bfb15353125c" target="_blank">查看报告</a> </div> </div> </div> </div> <!-- Recommended Skills --> <div style="margin-top:24px;"> <h2 style="font-size:18px;font-weight:600;margin-bottom:16px;">🔗 相关推荐</h2> <div class="rec-grid"> <div class="rec-card"> <span class="badge-cat" style="margin-bottom:8px;display:inline-block;">security-compliance</span> <h3><a href="/s/skill-vetter">Skill Vetter</a></h3> <div class="rec-owner">spclaudehome</div> <div class="rec-desc">AI智能体技能安全预审工具。安装ClawdHub、GitHub等来源技能前,检查风险信号、权限范围及可疑模式。</div> <div class="rec-stats"> <span style="color:#f39c12;">★ 1,215</span> <span style="color:#5b6abf;">📥 266,534</span> </div> </div> <div class="rec-card"> <span class="badge-cat" style="margin-bottom:8px;display:inline-block;">security-compliance</span> <h3><a href="/s/1password">1password</a></h3> <div class="rec-owner">steipete</div> <div class="rec-desc">设置和使用 1Password CLI (op)。适用于:安装 CLI、启用桌面应用集成、登录(单/多账户)、通过 op 读取/注入/运行密钥。</div> <div class="rec-stats"> <span style="color:#f39c12;">★ 53</span> <span style="color:#5b6abf;">📥 31,171</span> </div> </div> <div class="rec-card"> <span class="badge-cat" style="margin-bottom:8px;display:inline-block;">security-compliance</span> <h3><a href="/s/moltguard">MoltGuard - Security & Antivirus & Guardrails</a></h3> <div class="rec-owner">thomaslwang</div> <div class="rec-desc">MoltGuard — OpenClaw 安全守卫,由 OpenGuardrails 提供。安装 MoltGuard,保护您和您的用户免受提示注入、数据泄露和恶意攻击。</div> <div class="rec-stats"> <span style="color:#f39c12;">★ 116</span> <span style="color:#5b6abf;">📥 30,720</span> </div> </div> </div> </div> </div> <script> document.addEventListener('DOMContentLoaded',function(){ document.querySelectorAll('.detail-tab').forEach(function(btn){ btn.addEventListener('click',function(e){ var tab = this.getAttribute('data-tab'); document.querySelectorAll('.detail-tab').forEach(function(b){b.classList.remove('active')}); document.querySelectorAll('.detail-content').forEach(function(c){c.classList.remove('active')}); this.classList.add('active'); var el = document.getElementById('tab-'+tab); if(el) el.classList.add('active'); }); }); }); </script> <div class="footer"> <p>Skill工具集 © 2026</p> </div></body> </html>