mgraphctl 0.1.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of mgraphctl might be problematic. Click here for more details.

Files changed (57) hide show
  1. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/PKG-INFO +21 -3
  2. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/README.md +17 -1
  3. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/pyproject.toml +5 -3
  4. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/pyproject.toml.orig +5 -3
  5. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/__init__.py +1 -1
  6. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/config.py +6 -1
  7. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/http.py +2 -2
  8. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/render.py +2 -2
  9. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/LICENSE +0 -0
  10. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/__main__.py +0 -0
  11. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/auth.py +0 -0
  12. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/cli.py +0 -0
  13. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/__init__.py +0 -0
  14. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/api.py +0 -0
  15. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/calendar.py +0 -0
  16. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/chats.py +0 -0
  17. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/config_cmd.py +0 -0
  18. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/groups.py +0 -0
  19. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/mail.py +0 -0
  20. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/mailbox.py +0 -0
  21. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/meetings.py +0 -0
  22. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/onedrive.py +0 -0
  23. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/onenote.py +0 -0
  24. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/org.py +0 -0
  25. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/people.py +0 -0
  26. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/planner.py +0 -0
  27. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/presence.py +0 -0
  28. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/search.py +0 -0
  29. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/sharepoint.py +0 -0
  30. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/teams.py +0 -0
  31. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/todo.py +0 -0
  32. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/commands/top.py +0 -0
  33. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/errors.py +0 -0
  34. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/fixtures.py +0 -0
  35. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/__init__.py +0 -0
  36. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/calendar.py +0 -0
  37. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/chats.py +0 -0
  38. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/files.py +0 -0
  39. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/groups.py +0 -0
  40. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/mail.py +0 -0
  41. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/mailbox.py +0 -0
  42. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/meetings.py +0 -0
  43. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/onedrive.py +0 -0
  44. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/onenote.py +0 -0
  45. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/org.py +0 -0
  46. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/people.py +0 -0
  47. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/planner.py +0 -0
  48. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/presence.py +0 -0
  49. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/search.py +0 -0
  50. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/sharepoint.py +0 -0
  51. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/teams.py +0 -0
  52. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/todo.py +0 -0
  53. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/graph/users.py +0 -0
  54. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/html.py +0 -0
  55. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/odata.py +0 -0
  56. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/resolve.py +0 -0
  57. {mgraphctl-0.1.0 → mgraphctl-0.2.1}/src/mgraphctl/token_store.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mgraphctl
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Summary: Microsoft Graph CLI behind the mgraphctl Claude Code skill
5
5
  Keywords: microsoft-graph,microsoft-365,outlook,teams,sharepoint,onedrive,cli
6
6
  Author: Sviatoslav Sviridov
@@ -13,6 +13,7 @@ Classifier: Intended Audience :: Developers
13
13
  Classifier: Intended Audience :: End Users/Desktop
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
16
17
  Classifier: Programming Language :: Python :: 3.11
17
18
  Classifier: Programming Language :: Python :: 3.12
18
19
  Classifier: Programming Language :: Python :: 3.13
@@ -25,7 +26,8 @@ Requires-Dist: typer>=0.27,<1
25
26
  Requires-Dist: markdownify>=1.2,<2
26
27
  Requires-Dist: keyring>=24,<26
27
28
  Requires-Dist: tzdata ; sys_platform == 'win32'
28
- Requires-Python: >=3.11, <3.14
29
+ Requires-Dist: tomli>=2,<3 ; python_full_version < '3.11'
30
+ Requires-Python: >=3.10, <3.14
29
31
  Project-URL: Homepage, https://github.com/svd/mgraphctl
30
32
  Project-URL: Source, https://github.com/svd/mgraphctl
31
33
  Project-URL: Changelog, https://github.com/svd/mgraphctl/blob/main/CHANGELOG.md
@@ -118,6 +120,22 @@ uv run --project <plugin> --frozen --no-dev mgraphctl login
118
120
  Every other command reads the cached sign-in silently and never opens a browser or a device-code
119
121
  prompt — a missing or expired token fails with an actionable hint instead.
120
122
 
123
+ ## Commands
124
+
125
+ All 123 verbs are documented inside the skill, and `--help` works at every level.
126
+
127
+ | Where | What |
128
+ |---|---|
129
+ | [`skills/mgraphctl/SKILL.md`](skills/mgraphctl/SKILL.md) | the skill itself: setup, a cheat-sheet of every noun and its verbs, recipes, guardrails, exit codes |
130
+ | [`skills/mgraphctl/reference/commands.md`](skills/mgraphctl/reference/commands.md) | the conventions every verb shares — argument resolution, the list envelope, paging defaults, exit codes, environment variables — and the index of the files below |
131
+ | [`skills/mgraphctl/reference/commands/`](skills/mgraphctl/reference/commands/) | one file per noun (`mail.md`, `calendar.md`, `teams.md`, …): each verb's options, the Graph call it makes and the scopes it needs |
132
+
133
+ ```bash
134
+ ${CLAUDE_PLUGIN_ROOT}/mgraphctl --help
135
+ ${CLAUDE_PLUGIN_ROOT}/mgraphctl mail --help
136
+ ${CLAUDE_PLUGIN_ROOT}/mgraphctl mail list --help
137
+ ```
138
+
121
139
  ## Where things live
122
140
 
123
141
  - Virtual environment: under `${CLAUDE_PLUGIN_DATA}` when Claude Code sets it, otherwise
@@ -215,7 +233,7 @@ uv run ruff format src tests
215
233
  The test suite runs entirely offline against recorded fixtures — no Microsoft 365 account or
216
234
  network access is needed to run it.
217
235
 
218
- CI (`.github/workflows/ci.yml`) runs the suite on Python 3.11–3.13, ruff, `uv lock --check` and a
236
+ CI (`.github/workflows/ci.yml`) runs the suite on Python 3.10–3.13, ruff, `uv lock --check` and a
219
237
  credential scan on every push. Releases are annotated `mgraphctl--vX.Y.Z` tags on `main`, cut with
220
238
  `claude plugin tag`; the tag publishes the package to PyPI and a GitHub Release. See `VERSIONING.md`.
221
239
 
@@ -84,6 +84,22 @@ uv run --project <plugin> --frozen --no-dev mgraphctl login
84
84
  Every other command reads the cached sign-in silently and never opens a browser or a device-code
85
85
  prompt — a missing or expired token fails with an actionable hint instead.
86
86
 
87
+ ## Commands
88
+
89
+ All 123 verbs are documented inside the skill, and `--help` works at every level.
90
+
91
+ | Where | What |
92
+ |---|---|
93
+ | [`skills/mgraphctl/SKILL.md`](skills/mgraphctl/SKILL.md) | the skill itself: setup, a cheat-sheet of every noun and its verbs, recipes, guardrails, exit codes |
94
+ | [`skills/mgraphctl/reference/commands.md`](skills/mgraphctl/reference/commands.md) | the conventions every verb shares — argument resolution, the list envelope, paging defaults, exit codes, environment variables — and the index of the files below |
95
+ | [`skills/mgraphctl/reference/commands/`](skills/mgraphctl/reference/commands/) | one file per noun (`mail.md`, `calendar.md`, `teams.md`, …): each verb's options, the Graph call it makes and the scopes it needs |
96
+
97
+ ```bash
98
+ ${CLAUDE_PLUGIN_ROOT}/mgraphctl --help
99
+ ${CLAUDE_PLUGIN_ROOT}/mgraphctl mail --help
100
+ ${CLAUDE_PLUGIN_ROOT}/mgraphctl mail list --help
101
+ ```
102
+
87
103
  ## Where things live
88
104
 
89
105
  - Virtual environment: under `${CLAUDE_PLUGIN_DATA}` when Claude Code sets it, otherwise
@@ -181,7 +197,7 @@ uv run ruff format src tests
181
197
  The test suite runs entirely offline against recorded fixtures — no Microsoft 365 account or
182
198
  network access is needed to run it.
183
199
 
184
- CI (`.github/workflows/ci.yml`) runs the suite on Python 3.11–3.13, ruff, `uv lock --check` and a
200
+ CI (`.github/workflows/ci.yml`) runs the suite on Python 3.10–3.13, ruff, `uv lock --check` and a
185
201
  credential scan on every push. Releases are annotated `mgraphctl--vX.Y.Z` tags on `main`, cut with
186
202
  `claude plugin tag`; the tag publishes the package to PyPI and a GitHub Release. See `VERSIONING.md`.
187
203
 
@@ -1,11 +1,11 @@
1
1
  [project]
2
2
  name = "mgraphctl"
3
- version = "0.1.0"
3
+ version = "0.2.1"
4
4
  description = "Microsoft Graph CLI behind the mgraphctl Claude Code skill"
5
5
  readme = "README.md"
6
6
  license = "MIT"
7
7
  license-files = ["LICENSE"]
8
- requires-python = ">=3.11,<3.14"
8
+ requires-python = ">=3.10,<3.14"
9
9
  keywords = [
10
10
  "microsoft-graph",
11
11
  "microsoft-365",
@@ -22,6 +22,7 @@ classifiers = [
22
22
  "Intended Audience :: End Users/Desktop",
23
23
  "Operating System :: OS Independent",
24
24
  "Programming Language :: Python :: 3",
25
+ "Programming Language :: Python :: 3.10",
25
26
  "Programming Language :: Python :: 3.11",
26
27
  "Programming Language :: Python :: 3.12",
27
28
  "Programming Language :: Python :: 3.13",
@@ -36,6 +37,7 @@ dependencies = [
36
37
  "markdownify>=1.2,<2",
37
38
  "keyring>=24,<26",
38
39
  "tzdata; sys_platform == 'win32'",
40
+ "tomli>=2,<3; python_version < '3.11'",
39
41
  ]
40
42
 
41
43
  [[project.authors]]
@@ -70,7 +72,7 @@ module-name = "mgraphctl"
70
72
 
71
73
  [tool.ruff]
72
74
  line-length = 100
73
- target-version = "py311"
75
+ target-version = "py310"
74
76
  extend-exclude = ["docs"]
75
77
 
76
78
  [tool.ruff.lint]
@@ -1,12 +1,12 @@
1
1
  [project]
2
2
  name = "mgraphctl"
3
- version = "0.1.0"
3
+ version = "0.2.1"
4
4
  description = "Microsoft Graph CLI behind the mgraphctl Claude Code skill"
5
5
  readme = "README.md"
6
6
  license = "MIT"
7
7
  license-files = ["LICENSE"]
8
8
  authors = [{ name = "Sviatoslav Sviridov", email = "sviridov@gmail.com" }]
9
- requires-python = ">=3.11,<3.14"
9
+ requires-python = ">=3.10,<3.14"
10
10
  keywords = ["microsoft-graph", "microsoft-365", "outlook", "teams", "sharepoint", "onedrive", "cli"]
11
11
  classifiers = [
12
12
  "Development Status :: 4 - Beta",
@@ -15,6 +15,7 @@ classifiers = [
15
15
  "Intended Audience :: End Users/Desktop",
16
16
  "Operating System :: OS Independent",
17
17
  "Programming Language :: Python :: 3",
18
+ "Programming Language :: Python :: 3.10",
18
19
  "Programming Language :: Python :: 3.11",
19
20
  "Programming Language :: Python :: 3.12",
20
21
  "Programming Language :: Python :: 3.13",
@@ -29,6 +30,7 @@ dependencies = [
29
30
  "markdownify>=1.2,<2",
30
31
  "keyring>=24,<26",
31
32
  "tzdata; sys_platform == 'win32'",
33
+ "tomli>=2,<3; python_version < '3.11'",
32
34
  ]
33
35
 
34
36
  [project.urls]
@@ -55,7 +57,7 @@ module-name = "mgraphctl"
55
57
 
56
58
  [tool.ruff]
57
59
  line-length = 100
58
- target-version = "py311"
60
+ target-version = "py310"
59
61
  # Markdown under docs/ holds illustrative Python blocks; ruff must not rewrite them.
60
62
  extend-exclude = ["docs"]
61
63
 
@@ -1,3 +1,3 @@
1
1
  """mgraphctl: Microsoft Graph CLI for the mgraphctl skill."""
2
2
 
3
- __version__ = "0.1.0"
3
+ __version__ = "0.2.1"
@@ -5,12 +5,17 @@ from __future__ import annotations
5
5
 
6
6
  import os
7
7
  import re
8
- import tomllib
8
+ import sys
9
9
  from collections.abc import Iterable
10
10
  from dataclasses import dataclass
11
11
  from pathlib import Path
12
12
  from typing import Any
13
13
 
14
+ if sys.version_info >= (3, 11):
15
+ import tomllib
16
+ else: # tomllib is stdlib from 3.11; on 3.10 the same parser ships as tomli
17
+ import tomli as tomllib
18
+
14
19
  from mgraphctl import __version__
15
20
 
16
21
  CLIENT_ID_DEFAULT = "00000000-0000-0000-0000-000000000000"
@@ -14,7 +14,7 @@ import time
14
14
  import uuid
15
15
  from collections.abc import Callable, Mapping
16
16
  from dataclasses import dataclass, field, replace
17
- from datetime import UTC, datetime
17
+ from datetime import datetime, timezone
18
18
  from pathlib import Path
19
19
  from typing import Any, Literal
20
20
  from urllib.parse import urlsplit
@@ -399,7 +399,7 @@ class GraphClient:
399
399
  return float(min(int(value), config.RETRY_AFTER_CAP))
400
400
  with contextlib.suppress(TypeError, ValueError):
401
401
  when = email.utils.parsedate_to_datetime(value)
402
- seconds = (when - datetime.now(UTC)).total_seconds()
402
+ seconds = (when - datetime.now(timezone.utc)).total_seconds()
403
403
  return max(0.0, min(seconds, config.RETRY_AFTER_CAP))
404
404
  base = self.retry_base_ms / 1000
405
405
  return min(2**attempt * base, config.BACKOFF_CAP) + random.uniform(0, base)
@@ -13,7 +13,7 @@ import sys
13
13
  import time
14
14
  from collections.abc import Callable
15
15
  from dataclasses import dataclass
16
- from datetime import UTC, date, datetime, timedelta
16
+ from datetime import date, datetime, timedelta, timezone
17
17
  from pathlib import Path
18
18
  from typing import Any
19
19
  from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
@@ -343,7 +343,7 @@ def parse_graph_dt(value: str | None) -> datetime | None:
343
343
  dt = datetime.fromisoformat(text)
344
344
  except ValueError:
345
345
  return None
346
- return dt if dt.tzinfo is not None else dt.replace(tzinfo=UTC)
346
+ return dt if dt.tzinfo is not None else dt.replace(tzinfo=timezone.utc)
347
347
 
348
348
 
349
349
  def fmt_dt(value: str | None, tz: str) -> str:
File without changes