teardrop-cli 0.2.0__tar.gz → 0.3.0__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.
Files changed (70) hide show
  1. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/PKG-INFO +29 -2
  2. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/README.md +27 -0
  3. teardrop_cli-0.3.0/docs/cli-json-schema.md +130 -0
  4. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/docs/cli-reference.md +56 -0
  5. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/pyproject.toml +2 -2
  6. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/_templates.py +1 -3
  7. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/cli.py +2 -0
  8. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/agent_tools.py +1 -1
  9. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/auth.py +6 -7
  10. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/balance.py +2 -3
  11. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/chat.py +2 -4
  12. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/config_cmd.py +1 -3
  13. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/earnings.py +4 -8
  14. teardrop_cli-0.3.0/src/teardrop_cli/commands/event_triggers.py +457 -0
  15. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/llm_config.py +7 -13
  16. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/marketplace.py +8 -13
  17. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/quickstart.py +4 -10
  18. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/run.py +1 -3
  19. teardrop_cli-0.3.0/src/teardrop_cli/commands/schedules.py +386 -0
  20. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/tools.py +13 -29
  21. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/config.py +3 -9
  22. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/formatting.py +3 -1
  23. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/pricing.py +2 -4
  24. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/conftest.py +111 -3
  25. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/e2e/conftest.py +1 -4
  26. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/e2e/test_auth_e2e.py +2 -8
  27. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/e2e/test_marketplace_e2e.py +3 -9
  28. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/e2e/test_signup_e2e.py +4 -11
  29. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/e2e/test_siwe_login_e2e.py +3 -9
  30. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_auth.py +5 -7
  31. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_billing.py +2 -7
  32. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_chat.py +6 -13
  33. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_credential_priority.py +10 -8
  34. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_earnings.py +2 -6
  35. teardrop_cli-0.3.0/tests/test_event_triggers.py +240 -0
  36. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_init_and_byok.py +31 -23
  37. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_llm_config.py +3 -9
  38. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_marketplace.py +15 -45
  39. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_quickstart.py +38 -44
  40. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_run.py +18 -11
  41. teardrop_cli-0.3.0/tests/test_schedules.py +217 -0
  42. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_signup.py +5 -15
  43. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_token_expiry_fallback.py +24 -14
  44. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_tools.py +7 -21
  45. teardrop_cli-0.2.0/docs/cli-json-schema.md +0 -27
  46. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/.github/workflows/publish.yml +0 -0
  47. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/.github/workflows/test.yml +0 -0
  48. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/.gitignore +0 -0
  49. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/.vscode/settings.json +0 -0
  50. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/LICENSE +0 -0
  51. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/__init__.py +0 -0
  52. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/_fixtures.py +0 -0
  53. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/_lazy.py +0 -0
  54. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/__init__.py +0 -0
  55. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/mcp.py +0 -0
  56. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/models.py +0 -0
  57. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/src/teardrop_cli/commands/usage.py +0 -0
  58. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/e2e/README.md +0 -0
  59. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/e2e/__init__.py +0 -0
  60. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/e2e/test_billing_e2e.py +0 -0
  61. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/e2e/test_run_e2e.py +0 -0
  62. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/smoke/__init__.py +0 -0
  63. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/smoke/conftest.py +0 -0
  64. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/smoke/test_config_persistence.py +0 -0
  65. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/smoke/test_keyring_integration.py +0 -0
  66. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/smoke/test_perf_lazygroup.py +0 -0
  67. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/smoke/test_siwe_signing.py +0 -0
  68. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_config_cmd.py +0 -0
  69. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_mcp.py +0 -0
  70. {teardrop_cli-0.2.0 → teardrop_cli-0.3.0}/tests/test_models.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: teardrop-cli
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: Command-line interface for the Teardrop AI agent platform
5
5
  Project-URL: Homepage, https://github.com/teardrop-ai/teardrop-cli
6
6
  Project-URL: Repository, https://github.com/teardrop-ai/teardrop-cli
@@ -45,7 +45,7 @@ Requires-Dist: httpx>=0.27
45
45
  Requires-Dist: keyring>=25.0
46
46
  Requires-Dist: platformdirs>=4.0
47
47
  Requires-Dist: rich>=13.0
48
- Requires-Dist: teardrop-sdk>=0.1.8
48
+ Requires-Dist: teardrop-sdk>=0.2.0
49
49
  Requires-Dist: tomli-w>=1.0
50
50
  Requires-Dist: typer>=0.12
51
51
  Provides-Extra: dev
@@ -206,6 +206,33 @@ Streaming output renders Markdown live with inline tool calls and structured UI
206
206
 
207
207
  ---
208
208
 
209
+ ## Automate Runs
210
+
211
+ Use interval schedules for recurring prompts and event triggers for inbound webhooks:
212
+
213
+ ```bash
214
+ teardrop schedules create \
215
+ --name hourly-briefing \
216
+ --prompt "Summarize open incidents" \
217
+ --interval-seconds 3600
218
+
219
+ teardrop schedules list
220
+ teardrop schedules runs <schedule-id>
221
+
222
+ teardrop event-triggers create \
223
+ --name inbound-orders \
224
+ --prompt "Validate and process this order payload"
225
+
226
+ teardrop event-triggers runs <trigger-id>
227
+ teardrop event-triggers rotate-secret <trigger-id>
228
+ ```
229
+
230
+ `event-triggers create` and `event-triggers rotate-secret` print the signing secret once. Store it immediately.
231
+
232
+ Full reference: [docs/cli-reference.md](docs/cli-reference.md#schedules) and [docs/cli-reference.md](docs/cli-reference.md#event-triggers).
233
+
234
+ ---
235
+
209
236
  ## Chat with an Agent
210
237
 
211
238
  A stateful chat mode that automatically continues the same thread across invocations:
@@ -146,6 +146,33 @@ Streaming output renders Markdown live with inline tool calls and structured UI
146
146
 
147
147
  ---
148
148
 
149
+ ## Automate Runs
150
+
151
+ Use interval schedules for recurring prompts and event triggers for inbound webhooks:
152
+
153
+ ```bash
154
+ teardrop schedules create \
155
+ --name hourly-briefing \
156
+ --prompt "Summarize open incidents" \
157
+ --interval-seconds 3600
158
+
159
+ teardrop schedules list
160
+ teardrop schedules runs <schedule-id>
161
+
162
+ teardrop event-triggers create \
163
+ --name inbound-orders \
164
+ --prompt "Validate and process this order payload"
165
+
166
+ teardrop event-triggers runs <trigger-id>
167
+ teardrop event-triggers rotate-secret <trigger-id>
168
+ ```
169
+
170
+ `event-triggers create` and `event-triggers rotate-secret` print the signing secret once. Store it immediately.
171
+
172
+ Full reference: [docs/cli-reference.md](docs/cli-reference.md#schedules) and [docs/cli-reference.md](docs/cli-reference.md#event-triggers).
173
+
174
+ ---
175
+
149
176
  ## Chat with an Agent
150
177
 
151
178
  A stateful chat mode that automatically continues the same thread across invocations:
@@ -0,0 +1,130 @@
1
+ # Teardrop CLI Agent Run JSON Schema
2
+
3
+ When running `teardrop run "..." --json` or `teardrop chat "..." --json`,
4
+ the output is a single JSON object (implies `--no-stream`).
5
+
6
+ ## Schema Details
7
+
8
+ The JSON object contains the following fields:
9
+
10
+ - `text` (string): The final text response from the agent.
11
+ - `thread_id` (string | null): The ID of the thread used for the run. This can be used with the `--thread` flag in future runs (or `teardrop chat`) to continue the conversation.
12
+
13
+ ## Example Output
14
+
15
+ ```json
16
+ {
17
+ "text": "The price of ETH is currently $2,450.32.",
18
+ "thread_id": "thr_abc123"
19
+ }
20
+ ```
21
+
22
+ ## Usage
23
+ To capture specific fields, use `jq`:
24
+ ```bash
25
+ teardrop run "ETH price" --json | jq -r .text
26
+ teardrop chat "ETH price" --json | jq -r .thread_id
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Schedules (`schedules create/get/list/update --json`)
32
+
33
+ `schedules list --json` returns a JSON array; all other commands return a single object.
34
+
35
+ | Field | Type | Description |
36
+ |---|---|---|
37
+ | `id` | string (UUID) | Schedule identifier |
38
+ | `org_id` | string | Owning org |
39
+ | `user_id` | string | Creator user |
40
+ | `name` | string | Display name |
41
+ | `prompt` | string | Agent prompt |
42
+ | `schedule_kind` | `"interval"` | Fixed constant |
43
+ | `interval_seconds` | integer | Run frequency |
44
+ | `enabled` | boolean | Active state |
45
+ | `callback_url` | string \| null | Webhook called after each run |
46
+ | `next_run_at` | string (ISO 8601) | Next scheduled time |
47
+ | `last_run_at` | string \| null (ISO 8601) | Last completed run |
48
+ | `consecutive_failures` | integer | Failures since last success |
49
+ | `created_at` | string (ISO 8601) | |
50
+ | `updated_at` | string (ISO 8601) | |
51
+
52
+ ```bash
53
+ teardrop schedules create --name my-schedule --prompt "..." --interval-seconds 3600 --json | jq -r .id
54
+ teardrop schedules update <id> --enabled false --json | jq .enabled
55
+ teardrop schedules list --json | jq '.[].name'
56
+ ```
57
+
58
+ ---
59
+
60
+ ## Event Triggers (`event-triggers create/get/list/update --json`)
61
+
62
+ `event-triggers list --json` returns a JSON array; all other commands return a single object.
63
+
64
+ | Field | Type | Description |
65
+ |---|---|---|
66
+ | `id` | string (UUID) | Trigger identifier |
67
+ | `org_id` | string | Owning org |
68
+ | `user_id` | string | Creator user |
69
+ | `name` | string | Display name |
70
+ | `prompt` | string | Prompt template (supports `{{field}}` / `{{event_json}}`) |
71
+ | `schedule_kind` | `"event"` | Fixed constant |
72
+ | `enabled` | boolean | Active state |
73
+ | `callback_url` | string \| null | Webhook called after each run |
74
+ | `trigger_token` | string | Public route discriminator |
75
+ | `event_path` | string | Inbound dispatch path (e.g. `/agent/events/{trigger_token}`) |
76
+ | `consecutive_failures` | integer | Failures since last success |
77
+ | `last_run_at` | string \| null (ISO 8601) | |
78
+ | `created_at` | string (ISO 8601) | |
79
+ | `updated_at` | string (ISO 8601) | |
80
+
81
+ **`event-triggers create --json` only** additionally includes:
82
+
83
+ | Field | Type | Description |
84
+ |---|---|---|
85
+ | `secret` | string | Plaintext signing secret — shown once, never retrievable again |
86
+
87
+ **`event-triggers rotate-secret --json`** returns the rotation model (not the full trigger object):
88
+
89
+ | Field | Type | Description |
90
+ |---|---|---|
91
+ | `id` | string (UUID) | Trigger identifier |
92
+ | `secret` | string | New plaintext signing secret — shown once |
93
+
94
+ ```bash
95
+ # Capture id and secret on creation for use in CI
96
+ eval $(teardrop event-triggers create --name ci-hook --prompt "..." --json \
97
+ | jq -r '"TRIGGER_ID=" + .id, "TRIGGER_SECRET=" + .secret')
98
+
99
+ teardrop event-triggers list --json | jq '.[].trigger_token'
100
+ teardrop event-triggers rotate-secret <id> --json | jq -r .secret
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Run History (`schedules runs / event-triggers runs --json`)
106
+
107
+ Both commands return the same paginated envelope:
108
+
109
+ ```json
110
+ { "items": [ <ScheduledRunResult>, ... ], "next_cursor": "<cursor> | null" }
111
+ ```
112
+
113
+ Each `ScheduledRunResult` item:
114
+
115
+ | Field | Type | Description |
116
+ |---|---|---|
117
+ | `id` | string (UUID) | Outcome record ID |
118
+ | `schedule_id` | string (UUID) | Owning schedule or trigger ID |
119
+ | `org_id` | string | |
120
+ | `run_id` | string (UUID) | Core execution thread ID |
121
+ | `status` | `"completed" \| "failed" \| "timeout" \| "skipped"` | |
122
+ | `output_text` | string | Synthesized agent output |
123
+ | `cost_usdc` | integer | Atomic USDC charged ($1.00 = `1000000`) |
124
+ | `error` | string | Sanitized reason on failure; empty on success |
125
+ | `created_at` | string (ISO 8601) | |
126
+
127
+ ```bash
128
+ teardrop schedules runs <id> --json | jq '.items[] | select(.status == "failed") | .error'
129
+ teardrop event-triggers runs <id> --limit 50 --json | jq '.next_cursor'
130
+ ```
@@ -9,6 +9,8 @@ This document covers every flag, env var, and subcommand. For the quick path, st
9
9
  - [Authentication](#authentication)
10
10
  - [Running Agents](#running-agents)
11
11
  - [Chat Sessions](#chat-sessions)
12
+ - [Schedules](#schedules)
13
+ - [Event Triggers](#event-triggers)
12
14
  - [Billing & Credits](#billing--credits)
13
15
  - [Tool Management](#tool-management)
14
16
  - [Marketplace](#marketplace)
@@ -119,6 +121,60 @@ will start a fresh thread.
119
121
 
120
122
  ---
121
123
 
124
+ ## Schedules
125
+
126
+ Recurring interval-based runs:
127
+
128
+ ```bash
129
+ teardrop schedules create \
130
+ --name hourly-briefing \
131
+ --prompt "Summarize open incidents" \
132
+ --interval-seconds 3600
133
+
134
+ teardrop schedules list
135
+ teardrop schedules get <schedule-id>
136
+ teardrop schedules update <schedule-id> --enabled false
137
+ teardrop schedules update <schedule-id> --clear-callback-url
138
+ teardrop schedules runs <schedule-id> --limit 50 --json
139
+ teardrop schedules delete <schedule-id>
140
+ teardrop schedules delete <schedule-id> --yes
141
+ ```
142
+
143
+ Non-JSON list output includes: `ID`, `Name`, `Enabled`, `Interval`, `Consecutive Failures`, `Last Run At`.
144
+
145
+ Run history output includes: `Run ID`, `Status`, `Cost (USDC)`, `Error Message`, `Executed At`.
146
+
147
+ `--clear-callback-url` sends an explicit `null` callback URL while still preserving PATCH semantics for all other omitted fields.
148
+
149
+ ---
150
+
151
+ ## Event Triggers
152
+
153
+ Reactive runs exposed as signed public webhook endpoints:
154
+
155
+ ```bash
156
+ teardrop event-triggers create \
157
+ --name inbound-orders \
158
+ --prompt "Validate and process this order payload"
159
+
160
+ teardrop event-triggers list
161
+ teardrop event-triggers get <trigger-id>
162
+ teardrop event-triggers update <trigger-id> --enabled false
163
+ teardrop event-triggers update <trigger-id> --callback-url https://example.com/hook
164
+ teardrop event-triggers runs <trigger-id> --limit 50 --json
165
+ teardrop event-triggers rotate-secret <trigger-id>
166
+ teardrop event-triggers delete <trigger-id>
167
+ teardrop event-triggers delete <trigger-id> --yes
168
+ ```
169
+
170
+ `create` and `rotate-secret` display the signing secret once. Store it immediately; subsequent `list` and `get` calls do not return the plaintext secret.
171
+
172
+ Non-JSON list output includes: `ID`, `Name`, `Enabled`, `Kind`, `Consecutive Failures`, `Last Run At`.
173
+
174
+ Run history output includes: `Run ID`, `Status`, `Cost (USDC)`, `Error Message`, `Executed At`.
175
+
176
+ ---
177
+
122
178
  ## Billing & Credits
123
179
 
124
180
  ```bash
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "teardrop-cli"
7
- version = "0.2.0"
7
+ version = "0.3.0"
8
8
  description = "Command-line interface for the Teardrop AI agent platform"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -24,7 +24,7 @@ classifiers = [
24
24
  "Topic :: Software Development :: Libraries :: Python Modules",
25
25
  ]
26
26
  dependencies = [
27
- "teardrop-sdk>=0.1.8",
27
+ "teardrop-sdk>=0.2.0",
28
28
  "typer>=0.12",
29
29
  "rich>=13.0",
30
30
  "platformdirs>=4.0",
@@ -47,7 +47,5 @@ def render_tool_template(name: str, *, with_marketplace: bool = False) -> dict:
47
47
  data = {**_BASE_TEMPLATE, "name": name}
48
48
  if with_marketplace:
49
49
  data["publish_as_mcp"] = True
50
- data["marketplace_description"] = (
51
- "One-line marketplace pitch (max 200 characters)."
52
- )
50
+ data["marketplace_description"] = "One-line marketplace pitch (max 200 characters)."
53
51
  return data
@@ -23,9 +23,11 @@ from teardrop_cli._lazy import LazyGroup
23
23
  "quickstart": "teardrop_cli.commands.quickstart:app",
24
24
  "config": "teardrop_cli.commands.config_cmd:app",
25
25
  "run": "teardrop_cli.commands.run:app",
26
+ "schedules": "teardrop_cli.commands.schedules:app",
26
27
  "balance": "teardrop_cli.commands.balance:app",
27
28
  "usage": "teardrop_cli.commands.usage:app",
28
29
  "agent-tools": "teardrop_cli.commands.agent_tools:app",
30
+ "event-triggers": "teardrop_cli.commands.event_triggers:app",
29
31
  "marketplace": "teardrop_cli.commands.marketplace:app",
30
32
  "tools": "teardrop_cli.commands.tools:app",
31
33
  "earnings": "teardrop_cli.commands.earnings:app",
@@ -87,4 +87,4 @@ def _list(as_json: bool, base_url: str | None) -> None:
87
87
  ],
88
88
  rows,
89
89
  title="Agent Tools",
90
- )
90
+ )
@@ -49,7 +49,9 @@ def signup(
49
49
  str | None,
50
50
  typer.Option("--org-name", help="Organization name (1–200 chars)."),
51
51
  ] = None,
52
- as_json: Annotated[bool, typer.Option("--json", help="Output the JWT response as JSON.")] = False,
52
+ as_json: Annotated[
53
+ bool, typer.Option("--json", help="Output the JWT response as JSON.")
54
+ ] = False,
53
55
  base_url: Annotated[
54
56
  str | None, typer.Option("--base-url", help="Override the API base URL.", hidden=True)
55
57
  ] = None,
@@ -373,9 +375,7 @@ def _resolve_siwe_private_key(
373
375
  try:
374
376
  from eth_account import Account
375
377
  except ImportError:
376
- print_error(
377
- "eth-account is required.", hint="pip install 'teardrop-cli[siwe]'"
378
- )
378
+ print_error("eth-account is required.", hint="pip install 'teardrop-cli[siwe]'")
379
379
  raise typer.Exit(1) from None
380
380
  acct = Account.create()
381
381
  from rich.panel import Panel
@@ -536,9 +536,7 @@ def _login_siwe(
536
536
 
537
537
  try:
538
538
  with spinner("Signing in with Ethereum…"):
539
- jwt_token = asyncio.run(
540
- _siwe_auth_async(url, private_key, wallet_address)
541
- )
539
+ jwt_token = asyncio.run(_siwe_auth_async(url, private_key, wallet_address))
542
540
  except Exception as exc:
543
541
  _handle_auth_error(exc)
544
542
  return
@@ -713,4 +711,5 @@ def invite(
713
711
  print_success(f"Invited [bold]{email}[/bold] (role: {role})")
714
712
  if link:
715
713
  from teardrop_cli.formatting import console
714
+
716
715
  console.print(f" Invite link: [bold]{link}[/bold]")
@@ -105,9 +105,7 @@ def show(as_json: bool, base_url: str | None) -> None:
105
105
  ["Daily spend", _fmt_usdc(data.get("daily_spend_usdc"))],
106
106
  ["Account status", "paused" if data.get("is_paused") else "active"],
107
107
  ]
108
- print_table(
109
- [("Field", {"style": "bold cyan"}), "Value"], rows, title="Account Balance"
110
- )
108
+ print_table([("Field", {"style": "bold cyan"}), "Value"], rows, title="Account Balance")
111
109
 
112
110
  if data.get("is_paused"):
113
111
  console.print(
@@ -185,6 +183,7 @@ def _credit_history(limit: int, as_json: bool, base_url: str | None) -> None:
185
183
 
186
184
  if not items:
187
185
  from teardrop_cli.formatting import data_console
186
+
188
187
  data_console.print("[dim]No credit history found.[/dim]")
189
188
  return
190
189
 
@@ -136,9 +136,7 @@ def app(
136
136
  if estimate_cost:
137
137
  from teardrop_cli.commands.run import _estimate_cost
138
138
 
139
- _estimate_cost(
140
- message, context=context, tool_policy=tool_policy, base_url=base_url
141
- )
139
+ _estimate_cost(message, context=context, tool_policy=tool_policy, base_url=base_url)
142
140
  return
143
141
 
144
142
  # --- Capture the server-returned thread id ---
@@ -174,4 +172,4 @@ def app(
174
172
 
175
173
  # Always print the thread id for discoverability (to stderr)
176
174
  if final_thread:
177
- console.print(f"[dim]thread: {final_thread}[/dim]")
175
+ console.print(f"[dim]thread: {final_thread}[/dim]")
@@ -108,6 +108,4 @@ def list_cmd(
108
108
  return
109
109
 
110
110
  rows = [[k, v] for k, v in cfg.items()]
111
- print_table(
112
- [("Key", {"style": "bold cyan"}), "Value"], rows, title="~/.teardrop/config.toml"
113
- )
111
+ print_table([("Key", {"style": "bold cyan"}), "Value"], rows, title="~/.teardrop/config.toml")
@@ -73,11 +73,11 @@ def balance(
73
73
  from teardrop_cli.commands.auth import interactive_reauthenticate
74
74
 
75
75
  if not interactive_reauthenticate(base_url=base_url):
76
- raise typer.Exit(1)
76
+ raise typer.Exit(1) from None
77
77
  with spinner("Fetching balance…"):
78
78
  data = _call_once()
79
79
  elif action == "fail":
80
- raise typer.Exit(1)
80
+ raise typer.Exit(1) from None
81
81
  else:
82
82
  raise
83
83
 
@@ -94,9 +94,7 @@ def balance(
94
94
  ]
95
95
  if data.get("settlement_wallet"):
96
96
  rows.append(["Settlement wallet", data["settlement_wallet"]])
97
- print_table(
98
- [("Field", {"style": "bold cyan"}), "Value"], rows, title="Earnings Balance"
99
- )
97
+ print_table([("Field", {"style": "bold cyan"}), "Value"], rows, title="Earnings Balance")
100
98
 
101
99
 
102
100
  # ---------------------------------------------------------------------------
@@ -232,9 +230,7 @@ def withdraw(
232
230
  print_json(result)
233
231
  return
234
232
 
235
- print_success(
236
- "Withdrawal initiated. Transaction may take 1–5 minutes on-chain."
237
- )
233
+ print_success("Withdrawal initiated. Transaction may take 1–5 minutes on-chain.")
238
234
 
239
235
 
240
236
  async def _quick_balance(client) -> dict | None: