mattermost-cli 0.0.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.
- mattermost_cli-0.0.1/.github/workflows/publish.yml +28 -0
- mattermost_cli-0.0.1/.gitignore +13 -0
- mattermost_cli-0.0.1/AGENTS.md +97 -0
- mattermost_cli-0.0.1/LICENSE +21 -0
- mattermost_cli-0.0.1/PKG-INFO +105 -0
- mattermost_cli-0.0.1/README.md +76 -0
- mattermost_cli-0.0.1/mmchat/__init__.py +6 -0
- mattermost_cli-0.0.1/mmchat/_version.py +34 -0
- mattermost_cli-0.0.1/mmchat/cli.py +673 -0
- mattermost_cli-0.0.1/mmchat/client.py +157 -0
- mattermost_cli-0.0.1/mmchat/config.py +97 -0
- mattermost_cli-0.0.1/mmchat/formatters.py +229 -0
- mattermost_cli-0.0.1/mmchat/resolve.py +136 -0
- mattermost_cli-0.0.1/mmchat/time_utils.py +73 -0
- mattermost_cli-0.0.1/pyproject.toml +50 -0
- mattermost_cli-0.0.1/tests/__init__.py +0 -0
- mattermost_cli-0.0.1/tests/test_client.py +177 -0
- mattermost_cli-0.0.1/tests/test_config.py +104 -0
- mattermost_cli-0.0.1/tests/test_time_utils.py +90 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
publish:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
environment: pypi
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
|
|
21
|
+
- name: Install build tools
|
|
22
|
+
run: pip install build
|
|
23
|
+
|
|
24
|
+
- name: Build
|
|
25
|
+
run: python -m build
|
|
26
|
+
|
|
27
|
+
- name: Publish to PyPI
|
|
28
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Agent Instructions
|
|
2
|
+
|
|
3
|
+
Instructions for AI agents working on this repository.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
mattermost-cli is a Mattermost CLI for humans and agents. JSON output by default for agent consumption, `--human` flag for markdown. Published to PyPI as `mattermost-cli`, CLI command is `mm`.
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
mmchat/
|
|
13
|
+
cli.py # Click commands - all 8 commands, State object, argument resolution
|
|
14
|
+
client.py # Driver wrapper - URL parsing, auth, MMContext, Team dataclass
|
|
15
|
+
config.py # Token storage at ~/.config/mm/config.json (0600 perms)
|
|
16
|
+
resolve.py # User/channel ID resolution with in-memory caching (Resolver class)
|
|
17
|
+
formatters.py # JSON (default) and markdown output formatting
|
|
18
|
+
time_utils.py # --since argument parsing (relative, named, absolute, raw epoch)
|
|
19
|
+
tests/
|
|
20
|
+
test_time_utils.py # Pure function tests
|
|
21
|
+
test_config.py # File I/O with tmp_path fixtures
|
|
22
|
+
test_client.py # URL parsing, formatter output shapes
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Key design decisions
|
|
26
|
+
|
|
27
|
+
**Read-only**: No write operations to Mattermost. The `_resolve_channel` function scans existing channels for DMs instead of using `create_direct_message_channel` (which is a write op).
|
|
28
|
+
|
|
29
|
+
**JSON-first output**: Default output is JSON for agent consumption. `--human` flag switches to markdown tables. All formatters have both `format_*_json` and `format_*_md` variants.
|
|
30
|
+
|
|
31
|
+
**Agent-tuned defaults**: Commands are tuned for an agent running them bare (no flags), then using `--help` to refine:
|
|
32
|
+
- `mm thread` defaults to `--limit 10` (root + last 9 replies), not full thread
|
|
33
|
+
- `mm mentions` defaults to `--since 1d`, not all time
|
|
34
|
+
- `mm messages` defaults to `--limit 30`
|
|
35
|
+
|
|
36
|
+
**Cross-team by default**: All data commands iterate all user teams and deduplicate results. `--team` narrows to one.
|
|
37
|
+
|
|
38
|
+
**No passwords on disk**: Only session tokens are stored. Password+MFA login creates a session token and stores that. Config file has 0600 permissions, directory 0700.
|
|
39
|
+
|
|
40
|
+
## Dependencies
|
|
41
|
+
|
|
42
|
+
- `mattermostdriver` (7.3.2) - wraps Mattermost REST API v4. The driver takes separate scheme/host/port options, NOT a full URL. `client.py:create_driver()` handles URL parsing.
|
|
43
|
+
- `click` (8.0+) - CLI framework
|
|
44
|
+
- `httpx` - HTTP client (used by mattermostdriver internally, also imported for ConnectError handling)
|
|
45
|
+
|
|
46
|
+
## Testing
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install -e ".[dev]"
|
|
50
|
+
pytest tests/ -v
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Tests cover pure logic only (config, time parsing, URL parsing, formatters). API-dependent commands are tested manually against a live instance.
|
|
54
|
+
|
|
55
|
+
When adding tests: use `tmp_path` and `monkeypatch` for isolation. Don't mock the driver - test pure functions that don't need it.
|
|
56
|
+
|
|
57
|
+
## Common patterns
|
|
58
|
+
|
|
59
|
+
**Adding a new CLI command**:
|
|
60
|
+
1. Add the function in `cli.py` with `@main.command()` and `@pass_state`
|
|
61
|
+
2. Use `get_context(state)` to get authenticated `MMContext`
|
|
62
|
+
3. Create `Resolver(ctx.driver, ctx.user_id)` if you need name resolution
|
|
63
|
+
4. Output with `format_*_json` / `format_*_md` based on `state.human`
|
|
64
|
+
|
|
65
|
+
**JSON output fields for posts**: Every post includes `thread_id` (root_id if reply, own id if root), `is_reply`, `reply_count` (on root posts only), `created_at` (ISO 8601), `file_count`, and `files` (with name/size when available). These fields exist specifically for agent triage workflows.
|
|
66
|
+
|
|
67
|
+
**The `ref` field**: `mm unread` and `mm channels` JSON output includes a `ref` field - the exact string to pass to `mm messages <ref>`. For named channels this is the channel name (e.g. `gtt`), for DMs/group DMs it's the channel_id (since their display names like "karan, rhnvrm, shravan.bk" aren't addressable). Always use `ref`, never `channel` or `channel_id` directly.
|
|
68
|
+
|
|
69
|
+
**Resolver caching**: `Resolver` caches user and channel lookups per session. Use `resolve_users()` for batch resolution (one API call for all uncached IDs). Call `format_channel()` (public method) for channel info - not `_resolve_dm_name` directly.
|
|
70
|
+
|
|
71
|
+
## Gotchas
|
|
72
|
+
|
|
73
|
+
- The mattermostdriver logs passwords when `debug=True`. `create_driver()` always sets `debug=False`.
|
|
74
|
+
- DM channel names are `{uid1}__{uid2}` (double underscore). Group DMs are hashes.
|
|
75
|
+
- `get_channels_for_user` returns raw API channel dicts. The `type` field is a single letter: O/P/D/G. Formatters map these to "Public"/"Private"/"DM"/"Group DM".
|
|
76
|
+
- Thread API returns posts newest-first. Must sort by `create_at` for chronological display.
|
|
77
|
+
- The `--since` filter on `mm thread` keeps the root post regardless of age (for context), then filters replies by time.
|
|
78
|
+
- `reply_count` comes from the Mattermost API post object - only present on root posts that have replies.
|
|
79
|
+
- File metadata (`name`, `size`) is in `post["metadata"]["files"]` - only present when the API returns it (depends on post age and server config).
|
|
80
|
+
- `mm mentions` uses Mattermost search API with `@username after:YYYY-MM-DD` syntax. The `--since 0` disables the date filter.
|
|
81
|
+
|
|
82
|
+
## Publishing
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Build
|
|
86
|
+
python -m build
|
|
87
|
+
|
|
88
|
+
# Upload to PyPI
|
|
89
|
+
twine upload dist/*
|
|
90
|
+
|
|
91
|
+
# Users install with
|
|
92
|
+
uvx mmchat
|
|
93
|
+
# or
|
|
94
|
+
pip install mmchat
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The PyPI package name is `mattermost-cli`. The CLI command is `mm`.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rohan Verma
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mattermost-cli
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Mattermost CLI for humans and agents
|
|
5
|
+
Project-URL: Homepage, https://github.com/rhnvrm/mattermost-cli
|
|
6
|
+
Project-URL: Repository, https://github.com/rhnvrm/mattermost-cli
|
|
7
|
+
Project-URL: Issues, https://github.com/rhnvrm/mattermost-cli/issues
|
|
8
|
+
Author-email: Rohan Verma <hello@rohanverma.net>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Communications :: Chat
|
|
22
|
+
Requires-Python: >=3.9
|
|
23
|
+
Requires-Dist: click>=8.0
|
|
24
|
+
Requires-Dist: httpx<1.0.0,>=0.20.0
|
|
25
|
+
Requires-Dist: mattermostdriver>=7.3
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# mattermost-cli
|
|
31
|
+
|
|
32
|
+
Mattermost CLI for humans and agents.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# via uvx (recommended)
|
|
38
|
+
uvx mattermost-cli --help
|
|
39
|
+
|
|
40
|
+
# or pip
|
|
41
|
+
pip install mattermost-cli
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Setup
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Interactive login (password + MFA)
|
|
48
|
+
mm login
|
|
49
|
+
|
|
50
|
+
# Or with a Personal Access Token
|
|
51
|
+
mm login --token <your-pat>
|
|
52
|
+
|
|
53
|
+
# Verify
|
|
54
|
+
mm whoami
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# List channels
|
|
61
|
+
mm channels
|
|
62
|
+
|
|
63
|
+
# Show unread messages
|
|
64
|
+
mm unread
|
|
65
|
+
|
|
66
|
+
# Read messages from a channel
|
|
67
|
+
mm messages general
|
|
68
|
+
mm messages general --since 1h
|
|
69
|
+
mm messages @username # DM with a user
|
|
70
|
+
|
|
71
|
+
# Read a thread
|
|
72
|
+
mm thread <post-id>
|
|
73
|
+
|
|
74
|
+
# Search
|
|
75
|
+
mm search "deployment issue"
|
|
76
|
+
mm mentions
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Options
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
--human Human-readable markdown output (default is JSON)
|
|
83
|
+
--team Filter to a specific team
|
|
84
|
+
--debug Enable debug output
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Auth
|
|
88
|
+
|
|
89
|
+
Two methods supported:
|
|
90
|
+
|
|
91
|
+
**Password + MFA** (primary): `mm login` prompts interactively. Session token
|
|
92
|
+
is stored locally - password is never saved to disk. When the session expires,
|
|
93
|
+
run `mm login` again.
|
|
94
|
+
|
|
95
|
+
**Personal Access Token** (optional): `mm login --token <pat>`. Requires admin
|
|
96
|
+
to enable PATs on the Mattermost server. Tokens don't expire.
|
|
97
|
+
|
|
98
|
+
Credentials stored at `~/.config/mm/config.json` (token only, 600 permissions).
|
|
99
|
+
|
|
100
|
+
Environment variables override config: `MATTERMOST_URL`, `MATTERMOST_TOKEN`,
|
|
101
|
+
`MATTERMOST_TEAM`.
|
|
102
|
+
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
MIT
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# mattermost-cli
|
|
2
|
+
|
|
3
|
+
Mattermost CLI for humans and agents.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# via uvx (recommended)
|
|
9
|
+
uvx mattermost-cli --help
|
|
10
|
+
|
|
11
|
+
# or pip
|
|
12
|
+
pip install mattermost-cli
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Setup
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Interactive login (password + MFA)
|
|
19
|
+
mm login
|
|
20
|
+
|
|
21
|
+
# Or with a Personal Access Token
|
|
22
|
+
mm login --token <your-pat>
|
|
23
|
+
|
|
24
|
+
# Verify
|
|
25
|
+
mm whoami
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# List channels
|
|
32
|
+
mm channels
|
|
33
|
+
|
|
34
|
+
# Show unread messages
|
|
35
|
+
mm unread
|
|
36
|
+
|
|
37
|
+
# Read messages from a channel
|
|
38
|
+
mm messages general
|
|
39
|
+
mm messages general --since 1h
|
|
40
|
+
mm messages @username # DM with a user
|
|
41
|
+
|
|
42
|
+
# Read a thread
|
|
43
|
+
mm thread <post-id>
|
|
44
|
+
|
|
45
|
+
# Search
|
|
46
|
+
mm search "deployment issue"
|
|
47
|
+
mm mentions
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Options
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
--human Human-readable markdown output (default is JSON)
|
|
54
|
+
--team Filter to a specific team
|
|
55
|
+
--debug Enable debug output
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Auth
|
|
59
|
+
|
|
60
|
+
Two methods supported:
|
|
61
|
+
|
|
62
|
+
**Password + MFA** (primary): `mm login` prompts interactively. Session token
|
|
63
|
+
is stored locally - password is never saved to disk. When the session expires,
|
|
64
|
+
run `mm login` again.
|
|
65
|
+
|
|
66
|
+
**Personal Access Token** (optional): `mm login --token <pat>`. Requires admin
|
|
67
|
+
to enable PATs on the Mattermost server. Tokens don't expire.
|
|
68
|
+
|
|
69
|
+
Credentials stored at `~/.config/mm/config.json` (token only, 600 permissions).
|
|
70
|
+
|
|
71
|
+
Environment variables override config: `MATTERMOST_URL`, `MATTERMOST_TOKEN`,
|
|
72
|
+
`MATTERMOST_TEAM`.
|
|
73
|
+
|
|
74
|
+
## License
|
|
75
|
+
|
|
76
|
+
MIT
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '0.0.1'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 1)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|