Add MCP Phase 2 CLI compatibility aliases#9
Conversation
|
@claude review. Focus on critical issues: bugs, security vulnerabilities, logical errors, data loss risks, performance problems. Do NOT nitpick style, naming conventions, minor formatting, or subjective preferences — only flag issues that could break functionality or cause real harm in production. |
|
Claude finished @axisrow's task in 1m 53s —— View job PR Review — MCP Phase 2 CLI Compatibility AliasesTasks:
FindingsTwo definite bugs that will fail at runtime; one likely incorrect API call. Bug 1 —
|
There was a problem hiding this comment.
Pull request overview
Adds an MCP Phase 2 compatibility layer to the Direct CLI by introducing canonical top-level aliases for certain resources and adding commonly expected subcommand aliases (notably list and short-form names), while filling in a few previously missing handlers.
Changes:
- Register top-level canonical aliases:
dynamictargets,smarttargets,negativekeywords. - Add
listaliases across many resource groups (mapping to existingget), plus short-form aliases likechanges checkcamp/checkdictandkeywordsresearch has-volume. - Add missing
update/delete/togglehandlers for several resources and document the compatibility layer in README.
Reviewed changes
Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_comprehensive.py | Extends expected top-level command registration list to include new canonical aliases. |
| tests/test_cli.py | Adds help/usage tests for canonical aliases, short aliases, and list alias behavior. |
| README.md | Documents plugin-compatible alias names (EN/RU sections). |
| direct_cli/cli.py | Registers the new top-level canonical alias command names. |
| direct_cli/commands/changes.py | Adds short aliases checkcamp and checkdict. |
| direct_cli/commands/keywordsresearch.py | Adds deduplicate command and has-volume alias for has_search_volume. |
| direct_cli/commands/dynamicads.py | Adds update/delete handlers and list alias. |
| direct_cli/commands/smartadtargets.py | Adds update/delete handlers and list alias. |
| direct_cli/commands/negativekeywordsharedsets.py | Adds update/delete handlers, imports json, and list alias. |
| direct_cli/commands/bidmodifiers.py | Adds toggle and delete handlers plus list alias. |
| direct_cli/commands/feeds.py | Adds update/delete handlers and list alias. |
| direct_cli/commands/agencyclients.py | Adds add/delete handlers, imports json, and list alias. |
| direct_cli/commands/adimages.py | Adds add/delete handlers, imports json, and list alias. |
| direct_cli/commands/adextensions.py | Adds delete handler and list alias. |
| direct_cli/commands/sitelinks.py | Adds delete handler and list alias. |
| direct_cli/commands/retargeting.py | Adds delete handler and list alias. |
| direct_cli/commands/vcards.py | Adds delete handler and list alias. |
| direct_cli/commands/turbopages.py | Adds list alias. |
| direct_cli/commands/leads.py | Adds list alias. |
| direct_cli/commands/keywords.py | Adds list alias. |
| direct_cli/commands/dictionaries.py | Adds list alias for get. |
| direct_cli/commands/creatives.py | Adds list alias. |
| direct_cli/commands/clients.py | Adds list alias. |
| direct_cli/commands/campaigns.py | Adds list alias. |
| direct_cli/commands/bids.py | Adds list alias. |
| direct_cli/commands/audiencetargets.py | Adds list alias. |
| direct_cli/commands/ads.py | Adds list alias. |
| direct_cli/commands/adgroups.py | Adds list alias. |
Comments suppressed due to low confidence (1)
direct_cli/commands/adimages.py:116
adimages.add_command(get, name="list")relies onadimages.get()defaults, butget()hard-codes FieldNames to['Id', 'Name', 'Status', 'AdImageHash'], which diverges from the central defaults inutils.COMMON_FIELDSforadimages(['AdImageHash', 'Name']). This creates inconsistent behavior across resources and makes the newlistalias potentially incompatible with shared expectations; consider switchingadimages.get()to useget_default_fields('adimages')(or otherwise aligning defaults).
adimages.add_command(get, name="list")
| @adimages.command() | ||
| @click.option("--id", "image_id", required=True, type=int, help="Image ID") | ||
| @click.pass_context | ||
| def delete(ctx, image_id): |
There was a problem hiding this comment.
adimages uses AdImageHash as its identifier (see utils.COMMON_FIELDS['adimages']), but this new delete command accepts an integer --id and builds SelectionCriteria.Ids. This will likely fail against the API and is inconsistent with how ad images are keyed. Consider switching the option to accept the hash (string) and delete by hash-based selection criteria instead of numeric IDs.
| ) | ||
|
|
||
| body = {"method": "delete", "params": {"SelectionCriteria": {"Ids": [image_id]}}} | ||
|
|
There was a problem hiding this comment.
The delete request for ad images is constructed with SelectionCriteria: {Ids: [...]}. For ad images the API key is AdImageHash, so deletion should target hashes rather than IDs; otherwise the endpoint will likely return an error or delete the wrong entity type.
- adimages delete: use --hash/AdImageHashes instead of --id/Ids, fix get default fields to use COMMON_FIELDS - bidmodifiers toggle: send "YES"/"NO" strings instead of Python bool - agencyclients delete: replace with stub, API does not support delete Co-Authored-By: Claude Opus 4.6 <[email protected]>
|
@claude review. Focus on critical issues: bugs, security vulnerabilities, logical errors, data loss risks, performance problems. Do NOT nitpick style, naming conventions, minor formatting, or subjective preferences — only flag issues that could break functionality or cause real harm in production. |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
|
@claude re-review the PR after the latest fixes. Focus on critical issues only. |
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
|
@claude review this PR. Focus on critical issues: bugs, security vulnerabilities, logical errors, data loss risks, performance problems. |
|
Claude finished @axisrow's task in 2m 17s —— View job PR Review — MCP Phase 2 CLI Compatibility AliasesTasks:
Previously Reported Bugs — StatusAll three issues from the first review are resolved:
New FindingsTwo new runtime bugs introduced in this PR. Bug 1 —
|
- negativekeywordsharedsets: send keywords as flat string array,
not wrapped in {"Keyword": ...} objects
- dynamicads: use "Conditions" (plural) in get fields,
replace --condition with --json for add/update to match API structure
Co-Authored-By: Claude Opus 4.6 <[email protected]>
|
@claude review this PR after latest fixes. Focus on critical issues: bugs, security vulnerabilities, logical errors, data loss risks, performance problems. Do NOT nitpick style, naming conventions, minor formatting, or subjective preferences. |
|
Claude finished @axisrow's task in 2m 4s —— View job PR Re-Review — MCP Phase 2 CLI Compatibility AliasesTasks:
Previously Reported Bugs — All FixedAll bugs identified in prior review rounds are resolved:
New FindingsNo new critical issues. Specific checks performed:
This PR is clean. All previously identified bugs are resolved and no new issues were found. |
* fix(auth): stop --help and unit tests from hanging on client-login network call A regression from #480 made get_credentials() resolve the bare Client-Login via a network clients.get on every CLI invocation when an OAuth profile with an email login lacked the login_migration_checked flag — including plain `<group> --help`. That call had no timeout (neither the vendored client nor tapi2 set one), so a slow link or a Yandex SmartCaptcha gateway could hang the CLI indefinitely. Under CliRunner this also hung the unit suite (it stalled on test_registered_mapped_groups_show_docs_url, which fires ~30 `--help` calls). Three independent guards: - auth.py: cap the best-effort resolver with LOGIN_RESOLVE_TIMEOUT_SECONDS=8 and disable retries, so it can never wait forever. - cli.py: skip the resolver entirely on --help/--version/-h passes (allow_login_resolve=False) — no command runs, so no login is needed. - tests/conftest.py: autouse fixture neutralizes the network resolver for the whole unit suite; the module-level test-credential probe no longer triggers it. Adds regression tests asserting a --help pass makes zero resolver calls and that allow_login_resolve=False suppresses the migration. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * fix: resolve 13 confirmed bugs from the #483 bug hunt Verified each finding against the live API, the WSDL cache, and the official Yandex Direct docs before fixing. Bugs 10 and 14 were false positives (no UsageError source inside the try — style only) and are intentionally skipped. Functional fixes: - bids/keywordbids get: reject empty SelectionCriteria with a UsageError before the request (live API error 4001) (#1, #2). - bids get: re-raise UsageError so the new guard surfaces with exit code 2 (#8). - bids set-auto: require exactly one of CampaignId/AdGroupId/KeywordId via add_single_id_selector (docs: the three are mutually exclusive) (#4). - vendored to_columns: pad short report rows instead of IndexError (#3). - vendored error handler: error_data.get("error_detail") to avoid KeyError (#11). - reports build_report_request: reject empty FieldNames (live API error 8000) (#12). Swallowed-validation fixes (add `except click.UsageError/ClickException: raise` before the bare `except Exception`): balance (#6), strategies get (#7), campaigns get (#9), ads get (#13), negativekeywordsharedsets update (#5). Type annotation: parse_priority_goals_spec items -> List[Dict[str, Any]] (#15). build_api_coverage_report: supply --campaign-ids for bids/keywordbids get wire-capture so the empty-criteria guard does not break schema parity. Closes #483 Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> * fix: broaden #483 coverage and add CHANGELOG (cherry-picked from #484) Incorporates the genuinely-better parts of the parallel PR #484 into this branch, which already carries the regression tests, the #15 annotation fix, and the localized messages: - ads: re-raise click.UsageError in all lifecycle handlers (update, delete, archive, unarchive, suspend, resume, moderate) in addition to get — so the whole resource matches bug #13's "get + 8 lifecycle" scope. Defensive: these handlers have no pre-API UsageError source today, but the guard keeps them consistent and future-proof. - retargeting get/delete, advideos get: same defensive re-raise for uniformity (issue #483 items 10/14; not live defects, but harmless consistency). - bids/keywordbids get: the empty-criteria message now also lists --serving-statuses, which likewise populates SelectionCriteria (kept the t() localization wrapper). - CHANGELOG.md: document the bug-hunt fixes (#483) and the --help network-hang follow-up. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> --------- Co-authored-by: axisrow <[email protected]> Co-authored-by: Claude Opus 4.8 (1M context) <[email protected]>
Summary
Compatibility
Testing
Notes
This PR is focused on local CLI/help compatibility and test coverage for the MCP integration contract. Live API validation for newly exposed handlers still needs cassette or integration verification.