commune-cli 0.2.0__tar.gz → 0.2.2__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.
- {commune_cli-0.2.0 → commune_cli-0.2.2}/PKG-INFO +13 -2
- {commune_cli-0.2.0 → commune_cli-0.2.2}/README.md +12 -1
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/__init__.py +1 -1
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/describe.py +23 -1
- commune_cli-0.2.2/commune_cli/commands/feedback.py +101 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/main.py +2 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/pyproject.toml +1 -1
- {commune_cli-0.2.0 → commune_cli-0.2.2}/.gitignore +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/LICENSE +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/banner.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/client.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/__init__.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/attachments.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/config_cmd.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/context.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/credits.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/data.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/delivery.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/dmarc.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/doctor.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/domains.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/inboxes.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/messages.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/phone_numbers.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/search.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/sms.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/threads.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/commands/webhooks.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/config.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/errors.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/output.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/commune_cli/state.py +0 -0
- {commune_cli-0.2.0 → commune_cli-0.2.2}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: commune-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Official CLI for the Commune email API — agent-native, pipe-friendly, covers every API surface.
|
|
5
5
|
Project-URL: Homepage, https://commune.email
|
|
6
6
|
Project-URL: Documentation, https://docs.commune.email
|
|
@@ -249,12 +249,23 @@ Full API reference: https://docs.commune.email
|
|
|
249
249
|
|
|
250
250
|
| Package | Description |
|
|
251
251
|
|---------|-------------|
|
|
252
|
-
| [commune](https://github.com/shanjai-raj/commune) | Email
|
|
252
|
+
| [commune](https://github.com/shanjai-raj/commune) | Email infrastructure — self-hostable backend |
|
|
253
253
|
| [commune-ai](https://github.com/shanjai-raj/commune-ai) | TypeScript/Node.js SDK |
|
|
254
254
|
| [commune-python](https://github.com/shanjai-raj/commune-python) | Python SDK |
|
|
255
255
|
| [commune-mcp](https://github.com/shanjai-raj/commune-mcp) | MCP server for Claude Desktop, Cursor, Windsurf |
|
|
256
256
|
| **[commune-cli](https://github.com/shanjai-raj/commune-cli)** | **Command-line interface** |
|
|
257
257
|
|
|
258
|
+
## Guides
|
|
259
|
+
|
|
260
|
+
- [LangChain agent with email](https://commune.email/blog/email-for-langchain-agents)
|
|
261
|
+
- [CrewAI email agent](https://commune.email/blog/crewai-email-agent)
|
|
262
|
+
- [AutoGen email agent](https://commune.email/blog/autogen-email-agent)
|
|
263
|
+
- [Inbound email API](https://commune.email/inbound-email-api)
|
|
264
|
+
- [SendGrid alternative for AI agents](https://commune.email/sendgrid-alternative)
|
|
265
|
+
- [Mailgun alternative for AI agents](https://commune.email/mailgun-alternative)
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
258
269
|
## License
|
|
259
270
|
|
|
260
271
|
Apache-2.0
|
|
@@ -219,12 +219,23 @@ Full API reference: https://docs.commune.email
|
|
|
219
219
|
|
|
220
220
|
| Package | Description |
|
|
221
221
|
|---------|-------------|
|
|
222
|
-
| [commune](https://github.com/shanjai-raj/commune) | Email
|
|
222
|
+
| [commune](https://github.com/shanjai-raj/commune) | Email infrastructure — self-hostable backend |
|
|
223
223
|
| [commune-ai](https://github.com/shanjai-raj/commune-ai) | TypeScript/Node.js SDK |
|
|
224
224
|
| [commune-python](https://github.com/shanjai-raj/commune-python) | Python SDK |
|
|
225
225
|
| [commune-mcp](https://github.com/shanjai-raj/commune-mcp) | MCP server for Claude Desktop, Cursor, Windsurf |
|
|
226
226
|
| **[commune-cli](https://github.com/shanjai-raj/commune-cli)** | **Command-line interface** |
|
|
227
227
|
|
|
228
|
+
## Guides
|
|
229
|
+
|
|
230
|
+
- [LangChain agent with email](https://commune.email/blog/email-for-langchain-agents)
|
|
231
|
+
- [CrewAI email agent](https://commune.email/blog/crewai-email-agent)
|
|
232
|
+
- [AutoGen email agent](https://commune.email/blog/autogen-email-agent)
|
|
233
|
+
- [Inbound email API](https://commune.email/inbound-email-api)
|
|
234
|
+
- [SendGrid alternative for AI agents](https://commune.email/sendgrid-alternative)
|
|
235
|
+
- [Mailgun alternative for AI agents](https://commune.email/mailgun-alternative)
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
228
239
|
## License
|
|
229
240
|
|
|
230
241
|
Apache-2.0
|
|
@@ -37,6 +37,7 @@ _GROUPS: dict[str, str] = {
|
|
|
37
37
|
"dmarc": "DMARC reports and compliance summary",
|
|
38
38
|
"data": "Data deletion requests (GDPR)",
|
|
39
39
|
"config": "CLI config, agent registration, API keys",
|
|
40
|
+
"feedback": "Submit feedback: errors, feature requests, and signals",
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
|
|
@@ -133,6 +134,7 @@ _GROUP_TYPES: dict[str, list[str]] = {
|
|
|
133
134
|
"dmarc": [],
|
|
134
135
|
"data": [],
|
|
135
136
|
"config": [],
|
|
137
|
+
"feedback": [],
|
|
136
138
|
}
|
|
137
139
|
|
|
138
140
|
|
|
@@ -533,7 +535,7 @@ _COMMANDS: dict[str, dict] = {
|
|
|
533
535
|
},
|
|
534
536
|
"sms.thread": {
|
|
535
537
|
"description": "Get all messages in an SMS thread",
|
|
536
|
-
"method": "GET /v1/sms/
|
|
538
|
+
"method": "GET /v1/sms/conversations/{remote_number}",
|
|
537
539
|
"parameters": {
|
|
538
540
|
"remote_number": {"type": "string (E.164)", "required": True},
|
|
539
541
|
"--phone-number-id": {"type": "string", "required": True},
|
|
@@ -580,6 +582,26 @@ _COMMANDS: dict[str, dict] = {
|
|
|
580
582
|
},
|
|
581
583
|
"returns": "{ id, status }",
|
|
582
584
|
},
|
|
585
|
+
# ── Feedback ─────────────────────────────────────────────────────
|
|
586
|
+
"feedback.submit": {
|
|
587
|
+
"description": "Submit feedback to the Commune product team. Use for errors, feature requests, or signals (observations/impressions).",
|
|
588
|
+
"method": "POST /v1/feedback",
|
|
589
|
+
"parameters": {
|
|
590
|
+
"--type": {
|
|
591
|
+
"type": "string",
|
|
592
|
+
"required": True,
|
|
593
|
+
"enum": ["error", "feature", "signal"],
|
|
594
|
+
"description": (
|
|
595
|
+
"error = something broke or behaved unexpectedly; "
|
|
596
|
+
"feature = need a capability that doesn't exist; "
|
|
597
|
+
"signal = observation or impression (positive or improvement)"
|
|
598
|
+
),
|
|
599
|
+
},
|
|
600
|
+
"--message": {"type": "string", "required": True, "description": "Feedback description (max 4000 chars). Prompted if omitted."},
|
|
601
|
+
"--context": {"type": "json", "required": False, "description": 'Structured metadata, e.g. \'{"command":"list_threads","status_code":500}\''},
|
|
602
|
+
},
|
|
603
|
+
"returns": "{ id, type, status: received, created_at }",
|
|
604
|
+
},
|
|
583
605
|
# ── Config ───────────────────────────────────────────────────────
|
|
584
606
|
"config.register": {
|
|
585
607
|
"description": "Self-register as an agent using Ed25519 keypair. No dashboard required.",
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"""commune feedback — submit errors, feature requests, and signals to Commune."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from enum import Enum
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from ..client import CommuneClient
|
|
12
|
+
from ..errors import api_error, auth_required_error, network_error
|
|
13
|
+
from ..output import print_json, print_success
|
|
14
|
+
from ..state import AppState
|
|
15
|
+
|
|
16
|
+
app = typer.Typer(
|
|
17
|
+
help=(
|
|
18
|
+
"Submit feedback to Commune.\n\n"
|
|
19
|
+
"Three types:\n\n"
|
|
20
|
+
" error — something broke or behaved unexpectedly\n\n"
|
|
21
|
+
" feature — request for new functionality\n\n"
|
|
22
|
+
" signal — observations, impressions, things working well or needing polish"
|
|
23
|
+
),
|
|
24
|
+
no_args_is_help=True,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class FeedbackType(str, Enum):
|
|
29
|
+
error = "error"
|
|
30
|
+
feature = "feature"
|
|
31
|
+
signal = "signal"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@app.command("submit")
|
|
35
|
+
def feedback_submit(
|
|
36
|
+
ctx: typer.Context,
|
|
37
|
+
type: FeedbackType = typer.Option(
|
|
38
|
+
...,
|
|
39
|
+
"--type",
|
|
40
|
+
"-t",
|
|
41
|
+
help="Feedback type: error, feature, or signal.",
|
|
42
|
+
show_choices=True,
|
|
43
|
+
),
|
|
44
|
+
message: Optional[str] = typer.Option(
|
|
45
|
+
None,
|
|
46
|
+
"--message",
|
|
47
|
+
"-m",
|
|
48
|
+
help="Feedback message (prompted if omitted).",
|
|
49
|
+
),
|
|
50
|
+
context: Optional[str] = typer.Option(
|
|
51
|
+
None,
|
|
52
|
+
"--context",
|
|
53
|
+
help='Optional JSON context object, e.g. \'{"command":"list_threads","status_code":500}\'.',
|
|
54
|
+
),
|
|
55
|
+
json_output: bool = typer.Option(False, "--json", help="Output JSON."),
|
|
56
|
+
) -> None:
|
|
57
|
+
"""Submit feedback. POST /v1/feedback.
|
|
58
|
+
|
|
59
|
+
Examples:
|
|
60
|
+
|
|
61
|
+
commune feedback submit --type error --message "Thread list 500s when inbox is empty"
|
|
62
|
+
|
|
63
|
+
commune feedback submit --type feature --message "Add cursor pagination to search"
|
|
64
|
+
|
|
65
|
+
commune feedback submit --type signal --message "Semantic search quality has improved a lot"
|
|
66
|
+
"""
|
|
67
|
+
state: AppState = ctx.obj or AppState()
|
|
68
|
+
if not state.has_any_auth():
|
|
69
|
+
auth_required_error(json_output=json_output or state.should_json())
|
|
70
|
+
|
|
71
|
+
# Prompt for message if not provided
|
|
72
|
+
if not message:
|
|
73
|
+
message = typer.prompt(f"[{type.value}] Feedback message")
|
|
74
|
+
|
|
75
|
+
payload: dict = {"type": type.value, "message": message}
|
|
76
|
+
|
|
77
|
+
if context:
|
|
78
|
+
try:
|
|
79
|
+
payload["context"] = json.loads(context)
|
|
80
|
+
except json.JSONDecodeError:
|
|
81
|
+
typer.echo("Error: --context must be valid JSON.", err=True)
|
|
82
|
+
raise typer.Exit(1)
|
|
83
|
+
|
|
84
|
+
client = CommuneClient.from_state(state)
|
|
85
|
+
try:
|
|
86
|
+
r = client.post("/v1/feedback", json=payload)
|
|
87
|
+
except Exception as exc:
|
|
88
|
+
network_error(exc, json_output=json_output or state.should_json())
|
|
89
|
+
|
|
90
|
+
if not r.is_success:
|
|
91
|
+
api_error(r, json_output=json_output or state.should_json())
|
|
92
|
+
|
|
93
|
+
data = r.json()
|
|
94
|
+
if json_output or state.should_json():
|
|
95
|
+
print_json(data)
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
record = data.get("data", data)
|
|
99
|
+
feedback_id = record.get("id", "")
|
|
100
|
+
type_label = {"error": "Error", "feature": "Feature request", "signal": "Signal"}.get(type.value, type.value)
|
|
101
|
+
print_success(f"[bold]{type_label}[/bold] received. ID: [dim]{feedback_id}[/dim]")
|
|
@@ -30,6 +30,7 @@ from .commands import (
|
|
|
30
30
|
phone_numbers,
|
|
31
31
|
sms,
|
|
32
32
|
credits,
|
|
33
|
+
feedback,
|
|
33
34
|
)
|
|
34
35
|
|
|
35
36
|
app = typer.Typer(
|
|
@@ -64,6 +65,7 @@ app.add_typer(data.app, name="data", help="Data deletion requests
|
|
|
64
65
|
app.add_typer(phone_numbers.app, name="phone-numbers", help="Phone number management: list, get, settings.")
|
|
65
66
|
app.add_typer(sms.app, name="sms", help="Send SMS and manage conversations.")
|
|
66
67
|
app.add_typer(credits.app, name="credits", help="Credit balance and available bundles.")
|
|
68
|
+
app.add_typer(feedback.app, name="feedback", help="Submit feedback: errors, feature requests, and signals.")
|
|
67
69
|
|
|
68
70
|
|
|
69
71
|
@app.callback(invoke_without_command=True)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "commune-cli"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
8
|
description = "Official CLI for the Commune email API — agent-native, pipe-friendly, covers every API surface."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|