qodev-apollo-cli 1.2.1__tar.gz → 1.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.
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/.gitignore +5 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/CHANGELOG.md +10 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/PKG-INFO +2 -2
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/pyproject.toml +2 -2
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/deals.py +44 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/tests/test_commands.py +54 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/uv.lock +1 -1
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/.github/workflows/ci.yml +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/.github/workflows/publish.yml +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/LICENSE +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/README.md +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/__init__.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/__main__.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/app.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/__init__.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/accounts.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/calls.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/contacts.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/conversations.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/custom_fields.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/emails.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/enrich.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/install.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/jobs.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/news.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/notes.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/people.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/pipelines.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/tasks.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/commands/usage.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/context.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/formatters/__init__.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/formatters/accounts.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/formatters/contacts.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/formatters/conversations.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/formatters/deals.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/formatters/generic.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/formatters/people.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/help_reference.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/linkedin.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/output.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/skills/SKILL.md +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/skills/__init__.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/skills/references/__init__.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/skills/references/account-workflows.md +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/skills/references/contact-workflows.md +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/skills/references/deal-workflows.md +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/util.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/tests/conftest.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/tests/test_context.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/tests/test_conversations_formatter.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/tests/test_install.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/tests/test_linkedin.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/tests/test_output.py +0 -0
- {qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/tests/test_util.py +0 -0
|
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [1.3.0] - 2026-07-09
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- `deals create` command — create a deal/opportunity from the CLI: `deals create --name "…" [--owner-id] [--account-id] [--amount] [--stage-id | --stage-name] [--closed-date]`. `--name` is the only required flag; `--stage-name` resolves to an ID via the stage list (same helper as `deals search`), and passing both `--stage-id` and `--stage-name` is a validation error. Requires a master Apollo API key (non-master keys get a 403).
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Require `qodev-apollo-api>=0.4.0` (adds `create_deal`, and ships the fixed `update_opportunity_roles` payload so `deals set-role` now works, plus `search_accounts` filter validation).
|
|
18
|
+
|
|
9
19
|
## [1.2.1] - 2026-07-08
|
|
10
20
|
|
|
11
21
|
Follow-ups from code review of the v1.2.0 changes.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qodev-apollo-cli
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: Agent-friendly CLI for the Apollo API
|
|
5
5
|
Project-URL: Homepage, https://github.com/qodevai/apollo-cli
|
|
6
6
|
Project-URL: Repository, https://github.com/qodevai/apollo-cli
|
|
@@ -19,7 +19,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
19
19
|
Classifier: Typing :: Typed
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
Requires-Dist: cyclopts>=3.0
|
|
22
|
-
Requires-Dist: qodev-apollo-api>=0.
|
|
22
|
+
Requires-Dist: qodev-apollo-api>=0.4.0
|
|
23
23
|
Requires-Dist: rich>=13.0
|
|
24
24
|
Provides-Extra: dev
|
|
25
25
|
Requires-Dist: mypy>=1.13.0; extra == 'dev'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "qodev-apollo-cli"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.3.0"
|
|
4
4
|
description = "Agent-friendly CLI for the Apollo API"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -20,7 +20,7 @@ classifiers = [
|
|
|
20
20
|
dependencies = [
|
|
21
21
|
"cyclopts>=3.0",
|
|
22
22
|
"rich>=13.0",
|
|
23
|
-
"qodev-apollo-api>=0.
|
|
23
|
+
"qodev-apollo-api>=0.4.0",
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
[project.optional-dependencies]
|
|
@@ -66,6 +66,50 @@ async def get(
|
|
|
66
66
|
output(deal, ctx=ctx, format_fn=format_deal_detail)
|
|
67
67
|
|
|
68
68
|
|
|
69
|
+
@deals_app.command
|
|
70
|
+
async def create(
|
|
71
|
+
*,
|
|
72
|
+
name: Annotated[str, Parameter(name="--name", help="Deal name (required)")],
|
|
73
|
+
owner_id: Annotated[str | None, Parameter(name="--owner-id", help="Deal owner (team member) ID")] = None,
|
|
74
|
+
account_id: Annotated[str | None, Parameter(name="--account-id", help="Target account/company ID")] = None,
|
|
75
|
+
amount: Annotated[float | None, Parameter(name="--amount", help="Deal value (no currency symbol)")] = None,
|
|
76
|
+
stage_id: Annotated[str | None, Parameter(name="--stage-id", help="Deal stage ID")] = None,
|
|
77
|
+
stage_name: Annotated[
|
|
78
|
+
str | None,
|
|
79
|
+
Parameter(name="--stage-name", help="Deal stage name (resolved to an ID; avoids a `pipelines stages` lookup)"),
|
|
80
|
+
] = None,
|
|
81
|
+
closed_date: Annotated[str | None, Parameter(name="--closed-date", help="Expected close date (YYYY-MM-DD)")] = None,
|
|
82
|
+
) -> None:
|
|
83
|
+
"""Create a new deal/opportunity.
|
|
84
|
+
|
|
85
|
+
Requires a master Apollo API key (non-master keys get a 403). ``--name`` is the
|
|
86
|
+
only required field. Use ``--stage-name`` to set the stage by name instead of ID.
|
|
87
|
+
"""
|
|
88
|
+
if stage_id and stage_name:
|
|
89
|
+
error("Pass either --stage-id or --stage-name, not both.", ctx=ctx, code="conflicting_args", exit_code=2)
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
fields: dict[str, Any] = {}
|
|
93
|
+
if owner_id:
|
|
94
|
+
fields["owner_id"] = owner_id
|
|
95
|
+
if account_id:
|
|
96
|
+
fields["account_id"] = account_id
|
|
97
|
+
if amount is not None:
|
|
98
|
+
fields["amount"] = amount
|
|
99
|
+
if closed_date:
|
|
100
|
+
fields["closed_date"] = closed_date
|
|
101
|
+
|
|
102
|
+
async with ctx.client() as client:
|
|
103
|
+
if stage_name:
|
|
104
|
+
all_stages = await client.list_all_stages()
|
|
105
|
+
stage_id = resolve_stage_id(stage_name, all_stages.items, kind="deal stage")
|
|
106
|
+
if stage_id:
|
|
107
|
+
fields["opportunity_stage_id"] = stage_id
|
|
108
|
+
deal = await client.create_deal(name, **fields)
|
|
109
|
+
|
|
110
|
+
output(deal, ctx=ctx, format_fn=format_deal_detail)
|
|
111
|
+
|
|
112
|
+
|
|
69
113
|
ROLE_TYPE_COLUMNS = [("ID", "id"), ("Name", "name"), ("Display Order", "display_order")]
|
|
70
114
|
|
|
71
115
|
|
|
@@ -502,6 +502,60 @@ class TestDealRoleCommands:
|
|
|
502
502
|
assert all("opportunity_contact_role_type_id" not in r for r in roles)
|
|
503
503
|
|
|
504
504
|
|
|
505
|
+
class TestDealCreate:
|
|
506
|
+
@pytest.mark.asyncio
|
|
507
|
+
async def test_create_passes_name_and_optional_fields(self, sample_deal: dict, capsys) -> None:
|
|
508
|
+
"""deals create forwards --name plus only the optional fields that were provided."""
|
|
509
|
+
mock_client = MagicMock()
|
|
510
|
+
mock_client.create_deal = AsyncMock(return_value=sample_deal)
|
|
511
|
+
|
|
512
|
+
_ctx.ctx.configure(json_mode=True, api_key="test-key", limit=25, page=1)
|
|
513
|
+
|
|
514
|
+
with patch.object(_ctx.ctx, "client", return_value=MockAsyncContextManager(mock_client)):
|
|
515
|
+
from apollo_cli.commands.deals import create
|
|
516
|
+
|
|
517
|
+
await create(name="Big One", owner_id="o1", amount=5000, stage_id="st1")
|
|
518
|
+
|
|
519
|
+
name_arg = mock_client.create_deal.call_args.args[0]
|
|
520
|
+
fields = mock_client.create_deal.call_args.kwargs
|
|
521
|
+
assert name_arg == "Big One"
|
|
522
|
+
assert fields == {"owner_id": "o1", "amount": 5000, "opportunity_stage_id": "st1"}
|
|
523
|
+
|
|
524
|
+
@pytest.mark.asyncio
|
|
525
|
+
async def test_create_resolves_stage_name(self, sample_deal: dict, capsys) -> None:
|
|
526
|
+
"""deals create --stage-name resolves to opportunity_stage_id."""
|
|
527
|
+
mock_client = MagicMock()
|
|
528
|
+
mock_client.list_all_stages = AsyncMock(
|
|
529
|
+
return_value=MockSearchResult(items=[{"id": "st-neg", "name": "Negotiation"}], total=1, page=1)
|
|
530
|
+
)
|
|
531
|
+
mock_client.create_deal = AsyncMock(return_value=sample_deal)
|
|
532
|
+
|
|
533
|
+
_ctx.ctx.configure(json_mode=True, api_key="test-key", limit=25, page=1)
|
|
534
|
+
|
|
535
|
+
with patch.object(_ctx.ctx, "client", return_value=MockAsyncContextManager(mock_client)):
|
|
536
|
+
from apollo_cli.commands.deals import create
|
|
537
|
+
|
|
538
|
+
await create(name="Deal", stage_name="negotiation")
|
|
539
|
+
|
|
540
|
+
assert mock_client.create_deal.call_args.kwargs["opportunity_stage_id"] == "st-neg"
|
|
541
|
+
|
|
542
|
+
@pytest.mark.asyncio
|
|
543
|
+
async def test_create_rejects_both_stage_id_and_name(self, capsys) -> None:
|
|
544
|
+
"""Passing both --stage-id and --stage-name is a validation error; no API call is made."""
|
|
545
|
+
mock_client = MagicMock()
|
|
546
|
+
mock_client.create_deal = AsyncMock()
|
|
547
|
+
|
|
548
|
+
_ctx.ctx.configure(json_mode=True, api_key="test-key", limit=25, page=1)
|
|
549
|
+
|
|
550
|
+
with patch.object(_ctx.ctx, "client", return_value=MockAsyncContextManager(mock_client)):
|
|
551
|
+
from apollo_cli.commands.deals import create
|
|
552
|
+
|
|
553
|
+
with pytest.raises(SystemExit):
|
|
554
|
+
await create(name="Deal", stage_id="st1", stage_name="Negotiation")
|
|
555
|
+
|
|
556
|
+
mock_client.create_deal.assert_not_called()
|
|
557
|
+
|
|
558
|
+
|
|
505
559
|
class TestCustomFieldsCommand:
|
|
506
560
|
@pytest.mark.asyncio
|
|
507
561
|
async def test_custom_fields_list_filters_by_modality(self, capsys) -> None:
|
|
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
|
|
File without changes
|
{qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/formatters/conversations.py
RENAMED
|
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
|
{qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/skills/references/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{qodev_apollo_cli-1.2.1 → qodev_apollo_cli-1.3.0}/src/apollo_cli/skills/references/deal-workflows.md
RENAMED
|
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
|