affinity-sdk 2.0.5__tar.gz → 2.0.7__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.
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/CHANGELOG.md +43 -5
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/PKG-INFO +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/company_cmds.py +10 -3
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/list_cmds.py +13 -5
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/person_cmds.py +10 -3
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/entity_search.py +2 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/options.py +24 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/executor.py +10 -4
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/compare.py +66 -3
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/field_resolver.py +28 -26
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/cli/commands.md +3 -3
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/filtering.md +9 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/query-command.md +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/query-language.md +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.claude-plugin/plugin.json +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.claude-plugin/skills/query-language/SKILL.md +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.claude-plugin/skills/query-language/references/filter-operators.md +1 -1
- affinity_sdk-2.0.7/mcp/.mcp-bash/VERSION +1 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/tools_policy.sh +99 -5
- affinity_sdk-2.0.7/mcp/.mcp-bash/vendor.json +1 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.registry/commands.generated.json +10 -6
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/CHANGELOG.md +37 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/COMPATIBILITY +12 -2
- affinity_sdk-2.0.7/mcp/VERSION +1 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/lib/cli-gateway.sh +10 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/mcp-bash.lock +2 -2
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/data-model/data-model.md +2 -2
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/server.d/requirements.json +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/server.d/server.meta.json +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/execute-read-command/tool.meta.json +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/query/tool.meta.json +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/.claude-plugin/plugin.json +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/hooks/pre-xaffinity.sh +2 -2
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/hooks/session-setup.sh +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/SKILL.md +3 -2
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/filtering.md +5 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/query-guide.md +2 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/setup.md +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/pyproject.toml +1 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/cassettes/company-lists-status.cassette.json +87 -87
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/cassettes/hook-blocks-without-key.cassette.json +64 -64
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/cassettes/no-key-skill-path.cassette.json +101 -108
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/cassettes/status-history.cassette.json +117 -124
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_entity_ls_server_filter.py +100 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_list_export_server_filter.py +120 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_executor.py +81 -1
- affinity_sdk-2.0.7/tests/test_cli_repeated_filter.py +90 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_compare.py +2 -1
- affinity_sdk-2.0.7/tests/test_compare_entity_ids.py +102 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_field_resolver.py +35 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_mcp_must_fix.py +25 -0
- affinity_sdk-2.0.5/mcp/.mcp-bash/VERSION +0 -1
- affinity_sdk-2.0.5/mcp/.mcp-bash/vendor.json +0 -1
- affinity_sdk-2.0.5/mcp/VERSION +0 -1
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.claude-plugin/marketplace.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.cursor/rules/test-data-privacy.mdc +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.editorconfig +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.env.example +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.gitattributes +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/CODEOWNERS +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/PULL_REQUEST_TEMPLATE/cli_command.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/PULL_REQUEST_TEMPLATE/release.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/dependabot.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/labels.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/mcp-release-install-footer.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/pull_request_template.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/release-install-footer.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/ci.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/cowork-replay.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/docs.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/labels.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/linkcheck.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/openapi-validation.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/plugin-build.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/plugin-release.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/release-detect.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/release.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.github/workflows/version-check.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.gitignore +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/.pre-commit-config.yaml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/AGENTS.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/CODE_OF_CONDUCT.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/CONTRIBUTING.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/LICENSE +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/README.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/SECURITY.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/VERSIONING.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/_filtering/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/_filtering/dates.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/_filtering/filter_text.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/_filtering/pushdown.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/_filtering/search.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/_filtering/where.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/_internal/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/_internal/keyfile.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/api_versions.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/__main__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/_update_worker.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/async_utils.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/click_compat.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/_entity_field.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/_entity_files_dump.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/_entity_files_read.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/_entity_files_upload.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/_list_entry_fields.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/_org_reads.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/_search_common.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/_v1_parsing.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/completion_cmd.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/config_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/discovery_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/entry_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/field_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/file_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/file_url_cmd.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/interaction_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/note_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/opportunity_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/org_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/org_read_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/query_cmd.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/relationship_strength_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/reminder_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/resolve_url_cmd.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/session_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/task_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/transcript_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/version_cmd.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/webhook_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/commands/whoami_cmd.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/config.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/confirm.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/constants.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/context.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/csv_utils.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/date_utils.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/decorators.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/errors.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/field_utils.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/formatters.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/help_json.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/interaction_utils.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/list_search.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/logging.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/main.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/mcp_limits.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/paths.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/progress.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/aggregates.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/cursor.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/dates.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/exceptions.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/filter_text.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/filters.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/models.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/output.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/parser.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/planner.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/progress.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/pushdown.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/query/schema.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/render.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/resolve.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/resolvers.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/results.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/runner.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/serialization.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/session_cache.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/types.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/cli/update_check.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/client.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/clients/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/clients/http.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/clients/pipeline.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/criteria.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/downloads.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/exceptions.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/field_resolve_utils.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/filters.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/hooks.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/inbound_webhooks.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/discovery.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/entities.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/interactions_v2.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/org.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/pagination.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/rate_limit_snapshot.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/relationships_v2.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/search.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/secondary.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/transcripts.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/models/types.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/policies.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/progress.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/py.typed +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/_batch_interactions.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/_discovery.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/_dropdown_options.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/_field_listing.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/_field_updates.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/_note_html.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/_org_reads.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/_search.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/_single_field.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/_v2_filters.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/companies.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/lists.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/opportunities.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/org.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/persons.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/rate_limits.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/reminders.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/search.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/tasks.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/transcripts.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/v1_only.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/services/webhooks.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/affinity/types.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/codecov.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/cli-development-guide.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/ai-integrations/index.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/changelog.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/cli/index.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/cli/scripting.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/cli-reference.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/examples.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/getting-started.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/glossary.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/affinity-official-mcp-comparison.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/api-versions-and-routing.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/api-versions.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/authentication.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/claude-code-plugins.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/configuration.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/csv-export.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/datetime-handling.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/debugging-hooks.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/errors-and-retries.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/field-types-and-values.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/field-values.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/ids-and-types.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/migrating-to-2.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/models.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/opportunity-associations.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/pagination.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/performance.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/rate-limits.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/sync-vs-async.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/guides/webhooks.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/index.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/mcp/index.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/api-coverage.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/client.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/exceptions.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/filters.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/models.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/companies.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/lists.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/opportunities.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/persons.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/reminders.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/tasks.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/teams-users.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/transcripts.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/v1/auth.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/v1/field-values.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/v1/fields.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/v1/files.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/v1/interactions.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/v1/notes.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/v1/relationships.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/services/webhooks.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/reference/types.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/docs/public/troubleshooting.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/examples/advanced_usage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/examples/async_lifecycle.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/examples/basic_usage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/examples/filter_builder.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/examples/hooks_debugging.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/examples/list_management.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/examples/resolve_helpers.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/examples/task_polling.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.claude-plugin/.gitignore +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.claude-plugin/skills/affinity-mcp-workflows/SKILL.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.claude-plugin/skills/pipeline-history/SKILL.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.claude-plugin/skills/query-language/references/include-expand.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.claude-plugin/skills/query-language/references/output-formats.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.claude-plugin/skills/query-language/references/quantifiers.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.claude-plugin/xaffinity-mcp.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.gitignore +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/bin/mcp-bash +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/handlers/completion.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/handlers/lifecycle.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/handlers/logging.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/handlers/ping.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/handlers/prompts.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/handlers/resources.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/handlers/roots.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/handlers/tools.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/auth.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/capabilities.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/cli/common.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/cli/health.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/completion.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/core.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/elicitation.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/file_read.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/handler_helpers.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/hash.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/ids.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/io.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/json.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/lock.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/logging.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/meta_env.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/paginate.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/path.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/policy.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/progress-passthrough.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/progress.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/prompts.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/registry.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/require.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/resource_content.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/resource_match.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/resource_providers.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/resources.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/roots.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/rpc.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/runtime.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/spec.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/timeout.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/tools.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/ui-templates.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/ui.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/uri.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/lib/validate.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/providers/echo.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/providers/file.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/providers/git.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/providers/https.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/providers/ui.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/sdk/tool-error.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/sdk/tool-sdk.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.mcp-bash/sdk/ui-sdk.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.registry/mcp-commands.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.registry/prompts.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.registry/resource-templates.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.registry/resources.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/.registry/ui-resources.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/Makefile +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/README.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/completions/entity-name.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/completions/list-name.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/completions/status-value.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/docs/DEBUGGING.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/icon.svg +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/lib/cache.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/lib/cli-detect.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/lib/common.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/lib/entity-types.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/lib/field-resolution.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/mcp-publisher.lock +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/mcpb.conf +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/change-status/change-status.completion.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/change-status/change-status.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/change-status/change-status.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/interaction-brief/interaction-brief.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/interaction-brief/interaction-brief.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/log-call/log-call.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/log-call/log-call.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/log-interaction-and-update-workflow/log-interaction-and-update-workflow.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/log-message/log-message.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/log-message/log-message.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/pipeline-review/pipeline-review.completion.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/pipeline-review/pipeline-review.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/pipeline-review/pipeline-review.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/prepare-briefing/prepare-briefing.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/prepare-briefing/prepare-briefing.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/warm-intro/warm-intro.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/prompts/warm-intro/warm-intro.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/providers/xaffinity.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/data-model/data-model.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/field-catalogs/field-catalogs.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/field-catalogs/field-catalogs.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/interaction-enums/interaction-enums.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/interaction-enums/interaction-enums.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/me/me.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/me/me.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/me-person-id/me-person-id.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/me-person-id/me-person-id.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/query-guide/query-guide.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/query-guide/query-guide.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/saved-views/saved-views.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/saved-views/saved-views.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/workflow-config/workflow-config.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/workflow-config/workflow-config.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/workflows-guide/workflows-guide.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/workflows-guide/workflows-guide.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/xaffinity-field-catalogs.completion.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/xaffinity-saved-views.completion.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/resources/xaffinity-workflow-config.completion.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/server.d/env.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/server.d/health-checks.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/server.d/policy.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/server.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/test/README.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/test/run.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/test/test_env_update_check.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/test-progress.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/discover-commands/tool.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/discover-commands/tool.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/execute-read-command/tool.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/execute-write-command/tool.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/execute-write-command/tool.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/get-entity-dossier/tool.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/get-entity-dossier/tool.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/get-file-url/tool.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/get-file-url/tool.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/query/tool.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/read-xaffinity-resource/tool.meta.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/tools/read-xaffinity-resource/tool.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/user-config.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/xaffinity-mcp-env.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mcp/xaffinity-mcp.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/mkdocs.yml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/affinity-sdk/.claude-plugin/plugin.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/SKILL.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/affinity-sdk/.claude-plugin/skills/affinity-python-sdk/references/services.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/hooks/guard-env-read.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/hooks/hooks.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/files-and-writes.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/history-and-activity.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/plugins/xaffinity-cli/skills/xaffinity-cli-usage/references/interactions.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/query/test_cursor.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_company_create_dedup.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_company_ls_filter_rejection.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_formatters.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_output_formats_integration.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_person_create_dedup.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_person_ls_filter_rejection.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_query_filter_rejection.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_query_list_entry_relationships.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_query_list_export_parity.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_query_output_flattening.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_query_output_truncation.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cli/test_query_unreplied.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/conftest.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/.cowork-redact.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/README.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/fixtures/workdir-key/README.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/fixtures/workdir-key/xaffinity-test-key +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/fixtures/workdir-nokey/README.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/image/Dockerfile +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/image/fakeaff/build_fixtures.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/image/fakeaff/fixtures.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/image/fakeaff/server.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/image/xaffinity-wrapper.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/privacy-allow.txt +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/record.sh +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/scenarios/company-lists-status.yaml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/scenarios/hook-blocks-without-key.yaml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/scenarios/no-key-skill-path.yaml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/scenarios/status-history.yaml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/sessions/no-key.yaml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/cowork/sessions/with-key.yaml +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/field_write_mocks.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/fixtures/openapi/mini_openapi.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/fixtures/webhooks/field_value_updated.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/fixtures/webhooks/list_entry_created.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/fixtures/webhooks/organization_created.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/fixtures/webhooks/organization_merged.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/fixtures/webhooks/person_created.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/fixtures/webhooks/unknown_event.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/integration/README.md +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/integration/conftest.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/integration/setup_query_parity_data.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/integration/test_cli_writes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/integration/test_query_parity_integration.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/integration/test_sdk_reads.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/integration/test_sdk_writes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/integration/test_sdk_writes_runner.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/mcp/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/mcp/test_query_cursor.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/skill-evals/xaffinity-cli-usage-evals/evals.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/spec_guard.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_affinity_client_wrapper_additional_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_api_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_api_key_file_formats.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_api_key_resolution.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_api_version.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_api_version_per_operation.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_async_file_download_streaming.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_batch_get.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_api_version.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_column_limiting.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_command_context.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_commands_must_fix.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_company_cmds_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_company_get.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_config_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_context_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_csv_export.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_date_params.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_date_utils.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_datetime_formatting.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_datetime_header_offsets.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_domain_linkification.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_dotenv_resolution.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_dropdown_field_writes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_enriched_field_writes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_entity_field_writes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_entity_files_dump.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_entry_field.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_entry_field_batch_writes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_entry_field_multi_value_limits.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_error_hints.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_error_rendering.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_field_history.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_field_history_bulk.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_field_history_deleted_options.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_field_options_and_transcripts.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_field_utils.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_field_utils_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_field_utils_set_phase.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_field_value_humanization.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_file_url.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_files_ls.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_files_read.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_get_interaction_dates.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_help_json.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_interaction_date_chunking.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_interaction_utils.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_json_safety.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_list_cmds_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_list_expand_interactions.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_list_export_entity_scope.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_list_export_field_refresh.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_list_export_filter_safety.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_list_export_truncation_meta.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_missing_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_multi_value_truncation_warnings.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_no_network_commands.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_notes_writes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_opportunity_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_opportunity_cmds_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_org.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_page_size_validation.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_pager_logic.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_person_cmds_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_person_get.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_plugin_manifest.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_pre_xaffinity_hook.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_progress_manager.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_aggregates.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_cmd.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_cmd_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_dates.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_expand_interactions.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_filters.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_integration.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_must_fix.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_parser.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_planner.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_review_fixes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_safety.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_schema.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_query_server_filter.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_rate_limit_rendering.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_rate_limit_throttle.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_reminders.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_render_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_resolve_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_resolve_url_parsing.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_result_summary.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_safe_field_writes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_search.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_serialization.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_session_cache.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_session_setup_hook.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_set_phase_atomicity.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_types.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_unreplied.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_update_check.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_v1_only_cmds.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_v1_parsing.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_webhooks.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_cli_write_ops.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_client.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_companies_create_dedup.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_companies_filter_rejection.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_duplicates_connections.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_env_helpers.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_exceptions_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_field_service_caching.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_field_types_c4.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_field_value_type.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_field_values_get_value.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_file_batch_get.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_file_download_streaming.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_file_list_batch.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_file_upload_helpers_and_validation.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_files_upload_returning_files.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_files_v2.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_filters.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_generate_mcp_command_registry.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_get_fields_filter_includes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_get_fields_pagination.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_get_first.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_hidden_field_values.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_hooks.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_http_client_additional_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_http_client_remaining_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_inbound_webhooks.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_integration_smoke.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_interaction_date_validation.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_interactions_and_files_regressions.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_isodatetime.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_list_entries_server_filter.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_list_entry_membership_and_opportunities.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_list_term.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_lists_v2_writes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_mcp_bundle_env_and_completions.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_mcp_cli_version_check.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_mcp_entity_dossier.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_mcp_gateway_limits.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_mcp_history_bulk_gateway.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_mcp_limits.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_mcp_query_cli_error.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_mcp_read_truncation.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_mcp_resource_scripts.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_models.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_models_v2_2026_fields.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_multi_value_limits.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_new_features.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_notes_v2.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_notes_v2_writes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_opportunities_filter_rejection.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_org_reads.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_pagination_iterators.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_persons_create_dedup.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_persons_filter_rejection.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_public_api.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_query_pushdown.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_rate_limit_v2.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_raw_pipeline_hook_events.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_readonly_factory.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_reminder_list_batch.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_reminders_v2.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_requirements_additional.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_review_fixes_sdk_cli.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_sdk_interaction_dates.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_sdk_must_fix.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_search.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_search_v2.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_service_get_parameter_combinations.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_batch_get_interaction_dates.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_companies_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_dropdown_options.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_entity_field_updates.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_entity_list_entries.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_field_value_changes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_list_entries_filter_paths.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_lists_additional_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_lists_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_opportunities_additional_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_opportunities_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_opportunities_tasks_additional_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_pages_cursor_guard.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_persons_companies_additional_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_rate_limits_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_v1_only_async.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_services_v1_only_coverage_gaps.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_single_field_v2.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_small_modules_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_spec_guard.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_teams_users_feedback.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_transport_and_readonly_mode.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_v1_association_parsing.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_v1_only_services_additional_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_v1_only_services_more_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_v2_request_bodies.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_validate_openapi_tool.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/test_webhooks_v2.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/unit/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tests/unit/test_exceptions.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/__init__.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/api_coverage.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/api_coverage.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/api_coverage_v1_snapshot.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/check_cli_patterns.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/generate_mcp_command_registry.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/generate_release_notes.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/generate_requirements_mapping.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/openapi_snapshots/2024-01-01.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/openapi_snapshots/2026-07-15.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/openapi_snapshots/2026-09-17.json +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/search_golden.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/sync_mcp_bundle_env.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/sync_mcp_registry.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/sync_mcp_version.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/validate_mcp_registry_metadata.py +0 -0
- {affinity_sdk-2.0.5 → affinity_sdk-2.0.7}/tools/validate_openapi_models.py +0 -0
|
@@ -5,6 +5,42 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [2.0.7] - 2026-11-03
|
|
9
|
+
|
|
10
|
+
**Exception to semantic versioning** (as 2.0.2–2.0.6): two fixes change which rows a filter
|
|
11
|
+
returns. Each is marked **Behavior change**.
|
|
12
|
+
|
|
13
|
+
### Highlights
|
|
14
|
+
|
|
15
|
+
A repeated `--filter` now combines its conditions instead of keeping only the last one, and a
|
|
16
|
+
person or company field filtered by id (`Owner = 26229794`) matches that person instead of
|
|
17
|
+
nothing.
|
|
18
|
+
|
|
19
|
+
### Changed
|
|
20
|
+
|
|
21
|
+
- **Behavior change (correctness fix). CLI: repeated `--filter` values are ANDed** on
|
|
22
|
+
`list export`, `company ls` and `person ls`, and so are repeated `list export --expand-filter`
|
|
23
|
+
values. Only the last one used to apply, and the others were dropped without a warning, so such
|
|
24
|
+
runs returned rows that didn't match the earlier conditions: re-run them. `--filter A --filter B`
|
|
25
|
+
is `(A) & (B)`; for OR, use `|` inside one value. Each repeated value must be a complete
|
|
26
|
+
expression on its own. (The MCP server refused a repeated `--filter`, so MCP calls weren't
|
|
27
|
+
affected.)
|
|
28
|
+
- **Behavior change (correctness fix). CLI and SDK: a person or company field compared with a
|
|
29
|
+
number matches the record's id.** `Owner = 26229794` (and `in`, `has_any`, `has_all`) in
|
|
30
|
+
`--filter`, `query` and `affinity.filters` compared the name with "26229794" and matched nothing,
|
|
31
|
+
without a warning (`!=` matched every row). It now matches that person's id, and names still
|
|
32
|
+
match as before. Other record references, such as lists, match their id too. Re-run filters that
|
|
33
|
+
used ids. A reference with no name (a person without a first and last name, a company with an
|
|
34
|
+
empty name) still can't be matched by id.
|
|
35
|
+
|
|
36
|
+
## [2.0.6] - 2026-10-14
|
|
37
|
+
|
|
38
|
+
### Fixed
|
|
39
|
+
|
|
40
|
+
- `FieldResolver.get`, `get_many` and `get_by_id` accept a plain `ListEntry` (as returned by
|
|
41
|
+
`companies.get_list_entries()` and `persons.get_list_entries()`) in their type hints. They
|
|
42
|
+
already worked on it at runtime; strict type checkers no longer need a cast.
|
|
43
|
+
|
|
8
44
|
## [2.0.5] - 2026-10-14
|
|
9
45
|
|
|
10
46
|
**Exception to semantic versioning** (as 2.0.2–2.0.4): two fixes change what a call returns or
|
|
@@ -20,12 +56,14 @@ what the CLI prints. Each is marked **Behavior change**.
|
|
|
20
56
|
options are unchanged. When a value is plain text the CLI reads the field's metadata (one call)
|
|
21
57
|
to tell a dropdown from a text field (`history-bulk --list-id` already has it). Table and CSV
|
|
22
58
|
output show the text, as before.
|
|
23
|
-
- **Behavior change. SDK: `on_error="skip"` leaves failed records out of
|
|
59
|
+
- **Behavior change (correctness fix). SDK: `on_error="skip"` leaves failed records out of
|
|
24
60
|
`AsyncReminderService.list_batch` and `AsyncFileService.list_batch`.** A failed request used
|
|
25
|
-
to leave its ids in the result with empty
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
failed.
|
|
61
|
+
to leave its ids in the result with empty lists, which looked like "no reminders" / "no files";
|
|
62
|
+
one failed reminders request (50 ids) silently hid them all. A failure on a later page left a
|
|
63
|
+
partial list that looked complete. They are now absent from the result, as with every other
|
|
64
|
+
`on_error="skip"` method: a requested id with no key failed. **If you stored or cached results
|
|
65
|
+
of these calls made with `on_error="skip"` before 2.0.5, some empty or partial lists may be
|
|
66
|
+
failures: re-fetch them.**
|
|
29
67
|
- SDK: `field_value_changes.iter_all()` reads 10,000 changes per call by default (was 100), the
|
|
30
68
|
V1 maximum: a 16,000-change history takes 3 calls instead of 161 (paging ends on an empty
|
|
31
69
|
page). Pass `page_size` for smaller
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: affinity-sdk
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.7
|
|
4
4
|
Summary: A modern, strongly-typed Python SDK for the Affinity CRM API
|
|
5
5
|
Project-URL: Homepage, https://github.com/yaniv-golan/affinity-sdk
|
|
6
6
|
Project-URL: Documentation, https://yaniv-golan.github.io/affinity-sdk/latest/
|
|
@@ -29,7 +29,12 @@ from ..entity_search import COMPANY_KEYS, filtered_ls
|
|
|
29
29
|
from ..errors import CLIError
|
|
30
30
|
from ..list_search import is_filter_cursor
|
|
31
31
|
from ..mcp_limits import apply_mcp_limits
|
|
32
|
-
from ..options import
|
|
32
|
+
from ..options import (
|
|
33
|
+
csv_output_options,
|
|
34
|
+
csv_suboption_callback,
|
|
35
|
+
join_filters_callback,
|
|
36
|
+
output_options,
|
|
37
|
+
)
|
|
33
38
|
from ..progress import ProgressManager, ProgressSettings
|
|
34
39
|
from ..resolve import get_company_fields, resolve_list_selector
|
|
35
40
|
from ..resolvers import ResolvedEntity
|
|
@@ -330,9 +335,11 @@ def _parse_field_types(values: tuple[str, ...]) -> list[FieldType] | None:
|
|
|
330
335
|
"--filter",
|
|
331
336
|
"filter_expr",
|
|
332
337
|
type=str,
|
|
333
|
-
|
|
338
|
+
multiple=True,
|
|
339
|
+
callback=join_filters_callback,
|
|
334
340
|
help="Filter on company fields, applied by Affinity's search: 'field op value'. Ops: = != "
|
|
335
|
-
"=~ =^ =$ > < >= <= starts_word. E.g., 'Stage = \"Seed\"'. Name search: --query."
|
|
341
|
+
"=~ =^ =$ > < >= <= starts_word. E.g., 'Stage = \"Seed\"'. Name search: --query. "
|
|
342
|
+
"Repeatable: repeated values are ANDed.",
|
|
336
343
|
)
|
|
337
344
|
@click.option(
|
|
338
345
|
"--query",
|
|
@@ -44,7 +44,12 @@ from ..decorators import category, destructive
|
|
|
44
44
|
from ..errors import CLIError
|
|
45
45
|
from ..list_search import ListSearch, decode_cursor, encode_cursor, plan_list_search
|
|
46
46
|
from ..mcp_limits import apply_mcp_limits
|
|
47
|
-
from ..options import
|
|
47
|
+
from ..options import (
|
|
48
|
+
csv_output_options,
|
|
49
|
+
csv_suboption_callback,
|
|
50
|
+
join_filters_callback,
|
|
51
|
+
output_options,
|
|
52
|
+
)
|
|
48
53
|
from ..render import format_duration
|
|
49
54
|
from ..resolve import (
|
|
50
55
|
list_all_saved_views,
|
|
@@ -452,9 +457,10 @@ ExpandOnError = Literal["raise", "skip"]
|
|
|
452
457
|
"--filter",
|
|
453
458
|
"filter_expr",
|
|
454
459
|
type=str,
|
|
455
|
-
|
|
460
|
+
multiple=True,
|
|
461
|
+
callback=join_filters_callback,
|
|
456
462
|
help="Filter (field op value): Affinity's search applies what it can, the rest is checked "
|
|
457
|
-
'locally. Quote multi-word: Status="Intro Meeting".',
|
|
463
|
+
'locally. Quote multi-word: Status="Intro Meeting". Repeatable: repeated values are ANDed.',
|
|
458
464
|
)
|
|
459
465
|
@click.option(
|
|
460
466
|
"--page-size",
|
|
@@ -570,8 +576,10 @@ ExpandOnError = Literal["raise", "skip"]
|
|
|
570
576
|
"--expand-filter",
|
|
571
577
|
"expand_filter",
|
|
572
578
|
type=str,
|
|
573
|
-
|
|
574
|
-
|
|
579
|
+
multiple=True,
|
|
580
|
+
callback=join_filters_callback,
|
|
581
|
+
help="Filter expanded entities (e.g., 'field=value' or 'field!=value'). "
|
|
582
|
+
"Repeatable: repeated values are ANDed.",
|
|
575
583
|
)
|
|
576
584
|
@click.option(
|
|
577
585
|
"--expand-opportunities-list",
|
|
@@ -27,7 +27,12 @@ from ..entity_search import PERSON_KEYS, filtered_ls
|
|
|
27
27
|
from ..errors import CLIError
|
|
28
28
|
from ..list_search import is_filter_cursor
|
|
29
29
|
from ..mcp_limits import apply_mcp_limits
|
|
30
|
-
from ..options import
|
|
30
|
+
from ..options import (
|
|
31
|
+
csv_output_options,
|
|
32
|
+
csv_suboption_callback,
|
|
33
|
+
join_filters_callback,
|
|
34
|
+
output_options,
|
|
35
|
+
)
|
|
31
36
|
from ..progress import ProgressManager, ProgressSettings
|
|
32
37
|
from ..resolve import get_person_fields, resolve_list_selector
|
|
33
38
|
from ..resolvers import ResolvedEntity
|
|
@@ -207,9 +212,11 @@ def _parse_field_types(values: tuple[str, ...]) -> list[FieldType] | None:
|
|
|
207
212
|
"--filter",
|
|
208
213
|
"filter_expr",
|
|
209
214
|
type=str,
|
|
210
|
-
|
|
215
|
+
multiple=True,
|
|
216
|
+
callback=join_filters_callback,
|
|
211
217
|
help="Filter on person fields, applied by Affinity's search: 'field op value'. Ops: = != "
|
|
212
|
-
"=~ =^ =$ > < >= <= starts_word. E.g., 'Deals > 5'. Name/email search: --query."
|
|
218
|
+
"=~ =^ =$ > < >= <= starts_word. E.g., 'Deals > 5'. Name/email search: --query. "
|
|
219
|
+
"Repeatable: repeated values are ANDed.",
|
|
213
220
|
)
|
|
214
221
|
@click.option(
|
|
215
222
|
"--query",
|
|
@@ -94,7 +94,8 @@ def _paths(where: WhereClause) -> set[str]:
|
|
|
94
94
|
|
|
95
95
|
def entity_filter_dict(entity: Any) -> dict[str, Any]:
|
|
96
96
|
"""What a ``--filter`` on companies or persons sees: field values by name (dropdowns as
|
|
97
|
-
text, persons and companies as names) plus the record's own
|
|
97
|
+
text, persons and companies as names that also match their id) plus the record's own
|
|
98
|
+
attributes."""
|
|
98
99
|
result: dict[str, Any] = {}
|
|
99
100
|
by_id: dict[str, Any] = {}
|
|
100
101
|
for item in getattr(entity, "fields_raw", None) or []:
|
|
@@ -4,6 +4,8 @@ import functools
|
|
|
4
4
|
from collections.abc import Callable
|
|
5
5
|
from typing import Any, TypeVar, cast
|
|
6
6
|
|
|
7
|
+
from affinity.filters import parse
|
|
8
|
+
|
|
7
9
|
from .click_compat import click
|
|
8
10
|
from .context import CLIContext, OutputFormat
|
|
9
11
|
from .errors import CLIError
|
|
@@ -143,6 +145,28 @@ def _emit_validation_error(ctx: CLIContext, err: CLIError) -> None:
|
|
|
143
145
|
sys.stderr.write(f"Hint: {err.hint}\n")
|
|
144
146
|
|
|
145
147
|
|
|
148
|
+
def join_filters_callback(
|
|
149
|
+
_ctx: click.Context, _param: click.Parameter, value: tuple[str, ...]
|
|
150
|
+
) -> str | None:
|
|
151
|
+
"""Callback for a repeatable filter option (--filter, --expand-filter): AND the values.
|
|
152
|
+
|
|
153
|
+
One value is passed on unchanged. Repeated values are each parsed on their own first, so a
|
|
154
|
+
value can't close the parentheses it is wrapped in, and its error names it.
|
|
155
|
+
"""
|
|
156
|
+
if not value:
|
|
157
|
+
return None
|
|
158
|
+
if len(value) == 1:
|
|
159
|
+
return value[0]
|
|
160
|
+
for i, text in enumerate(value, 1):
|
|
161
|
+
if not text.strip():
|
|
162
|
+
raise click.BadParameter(f"value {i} is empty; each repeated value needs an expression")
|
|
163
|
+
try:
|
|
164
|
+
parse(text)
|
|
165
|
+
except ValueError as e:
|
|
166
|
+
raise click.BadParameter(f"value {i} ({text!r}): {e}") from e
|
|
167
|
+
return " & ".join(f"({text})" for text in value)
|
|
168
|
+
|
|
169
|
+
|
|
146
170
|
def csv_suboption_callback(ctx: click.Context, param: click.Parameter, value: Any) -> Any:
|
|
147
171
|
"""Callback for CSV-related sub-options (--csv-bom, --csv-header, --csv-mode).
|
|
148
172
|
|
|
@@ -16,6 +16,7 @@ from collections.abc import AsyncIterator, Awaitable, Callable, Mapping
|
|
|
16
16
|
from dataclasses import dataclass, field
|
|
17
17
|
from typing import TYPE_CHECKING, Any, Protocol, TypeVar
|
|
18
18
|
|
|
19
|
+
from ...compare import entity_name
|
|
19
20
|
from ...exceptions import (
|
|
20
21
|
AuthorizationError,
|
|
21
22
|
MergedEntityError,
|
|
@@ -262,19 +263,24 @@ def _normalize_list_entry_fields(
|
|
|
262
263
|
# Person reference in multi-select
|
|
263
264
|
name = _extract_person_display_name(item)
|
|
264
265
|
if name:
|
|
265
|
-
extracted.append(name)
|
|
266
|
+
extracted.append(entity_name(name, item.get("id")))
|
|
266
267
|
elif isinstance(item, dict) and "name" in item:
|
|
267
268
|
# Company reference in multi-select
|
|
268
|
-
extracted.append(item["name"])
|
|
269
|
+
extracted.append(entity_name(item["name"], item.get("id")))
|
|
269
270
|
else:
|
|
270
271
|
extracted.append(item)
|
|
271
272
|
normalized_fields[field_name] = extracted
|
|
272
273
|
# Handle person reference: {"firstName": "Jane", "lastName": "Doe"}
|
|
274
|
+
# (names carry the record id: a filter on the id matches too)
|
|
273
275
|
elif isinstance(data, dict) and ("firstName" in data or "lastName" in data):
|
|
274
|
-
normalized_fields[field_name] =
|
|
276
|
+
normalized_fields[field_name] = entity_name(
|
|
277
|
+
_extract_person_display_name(data), data.get("id")
|
|
278
|
+
)
|
|
275
279
|
# Handle company reference: {"name": "Acme", "domain": "acme.com"}
|
|
276
280
|
elif isinstance(data, dict) and "name" in data:
|
|
277
|
-
normalized_fields[field_name] =
|
|
281
|
+
normalized_fields[field_name] = entity_name(
|
|
282
|
+
data["name"], data.get("id")
|
|
283
|
+
)
|
|
278
284
|
else:
|
|
279
285
|
normalized_fields[field_name] = data
|
|
280
286
|
else:
|
|
@@ -16,6 +16,51 @@ from typing import Any
|
|
|
16
16
|
from ._filtering.dates import as_utc, parse_date_value, parse_iso_datetime
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
class EntityName(str):
|
|
20
|
+
"""A person's or company's name (or another record reference's) that also carries the
|
|
21
|
+
record's id, so a filter can match either: ``Owner = "Jane Doe"`` or ``Owner = 123``.
|
|
22
|
+
|
|
23
|
+
It is a ``str`` everywhere else (output, sorting, text operators)."""
|
|
24
|
+
|
|
25
|
+
__slots__ = ("entity_id",)
|
|
26
|
+
entity_id: int | None
|
|
27
|
+
|
|
28
|
+
def __new__(cls, value: str, entity_id: int | None = None) -> EntityName:
|
|
29
|
+
self = super().__new__(cls, value)
|
|
30
|
+
self.entity_id = entity_id
|
|
31
|
+
return self
|
|
32
|
+
|
|
33
|
+
def __reduce__(self) -> tuple[Any, ...]:
|
|
34
|
+
# Keeps the id through copy, deepcopy and every pickle protocol
|
|
35
|
+
return (type(self), (str(self), self.entity_id))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def entity_name(value: Any, entity_id: Any) -> Any:
|
|
39
|
+
"""``value`` as an :class:`EntityName` when it is a non-empty name and ``entity_id`` an
|
|
40
|
+
integer id; anything else (no name, no id) is returned unchanged."""
|
|
41
|
+
if (
|
|
42
|
+
isinstance(value, str)
|
|
43
|
+
and value
|
|
44
|
+
and isinstance(entity_id, int)
|
|
45
|
+
and not isinstance(entity_id, bool)
|
|
46
|
+
):
|
|
47
|
+
return EntityName(value, entity_id)
|
|
48
|
+
return value
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _as_entity_id(value: Any) -> int | None:
|
|
52
|
+
"""A filter value read as a record id: an int, or a string of ASCII digits."""
|
|
53
|
+
if isinstance(value, bool):
|
|
54
|
+
return None
|
|
55
|
+
if isinstance(value, int):
|
|
56
|
+
return value
|
|
57
|
+
if isinstance(value, str):
|
|
58
|
+
text = value.strip()
|
|
59
|
+
if text and text.isascii() and text.isdigit() and len(text) <= 20:
|
|
60
|
+
return int(text)
|
|
61
|
+
return None
|
|
62
|
+
|
|
63
|
+
|
|
19
64
|
def normalize_value(value: Any) -> Any:
|
|
20
65
|
"""Normalize a value for comparison.
|
|
21
66
|
|
|
@@ -23,6 +68,7 @@ def normalize_value(value: Any) -> Any:
|
|
|
23
68
|
- Dropdowns become their text: {"text": "Active"} -> "Active"
|
|
24
69
|
- Persons become their name: {"firstName": "Jane", "lastName": "Doe"} -> "Jane Doe"
|
|
25
70
|
- Companies become their name: {"name": "Acme", "domain": ...} -> "Acme"
|
|
71
|
+
(as :class:`EntityName`, carrying the record id, so a number matches the id)
|
|
26
72
|
- Multi-value arrays become lists of those: [{"text": "A"}, {"text": "B"}] -> ["A", "B"]
|
|
27
73
|
- Scalars pass through unchanged
|
|
28
74
|
|
|
@@ -46,9 +92,9 @@ def _normalize_item(item: dict[str, Any]) -> Any:
|
|
|
46
92
|
parts = [
|
|
47
93
|
p.strip() for p in (item.get("firstName"), item.get("lastName")) if isinstance(p, str)
|
|
48
94
|
]
|
|
49
|
-
return " ".join(p for p in parts if p) or None
|
|
95
|
+
return entity_name(" ".join(p for p in parts if p) or None, item.get("id"))
|
|
50
96
|
if "name" in item:
|
|
51
|
-
return item["name"]
|
|
97
|
+
return entity_name(item["name"], item.get("id"))
|
|
52
98
|
return item
|
|
53
99
|
|
|
54
100
|
|
|
@@ -163,6 +209,8 @@ def _eq(a: Any, b: Any) -> bool:
|
|
|
163
209
|
if isinstance(a, list):
|
|
164
210
|
# If comparing list to list, check set equality (order-insensitive)
|
|
165
211
|
if isinstance(b, list):
|
|
212
|
+
if any(isinstance(x, EntityName) for x in a):
|
|
213
|
+
return _same_members(a, b)
|
|
166
214
|
try:
|
|
167
215
|
return set(a) == set(b)
|
|
168
216
|
except TypeError:
|
|
@@ -178,7 +226,8 @@ def _eq(a: Any, b: Any) -> bool:
|
|
|
178
226
|
|
|
179
227
|
def _scalar_eq(a: Any, b: Any) -> bool:
|
|
180
228
|
"""Scalar equality as ``eq`` uses it, and ``in`` / ``has_any`` / ``has_all`` per element:
|
|
181
|
-
direct, then ``"true"``/``"false"`` against a
|
|
229
|
+
direct, then an :class:`EntityName` against its id, then ``"true"``/``"false"`` against a
|
|
230
|
+
bool, then by string (``5`` matches ``"5"``). ``a`` is the field value."""
|
|
182
231
|
if a is None or b is None:
|
|
183
232
|
return a is b
|
|
184
233
|
|
|
@@ -186,6 +235,10 @@ def _scalar_eq(a: Any, b: Any) -> bool:
|
|
|
186
235
|
if a == b:
|
|
187
236
|
return True
|
|
188
237
|
|
|
238
|
+
# A person or company also matches its id (Owner = 123)
|
|
239
|
+
if isinstance(a, EntityName) and a.entity_id is not None and _as_entity_id(b) == a.entity_id:
|
|
240
|
+
return True
|
|
241
|
+
|
|
189
242
|
# Handle boolean coercion: filter string "true"/"false" should match Python bool
|
|
190
243
|
# Filter parser outputs lowercase "true"/"false", Python str(True) is "True"
|
|
191
244
|
if isinstance(a, bool) and isinstance(b, str):
|
|
@@ -198,6 +251,14 @@ def _scalar_eq(a: Any, b: Any) -> bool:
|
|
|
198
251
|
return str(a) == str(b)
|
|
199
252
|
|
|
200
253
|
|
|
254
|
+
def _same_members(a: list[Any], b: list[Any]) -> bool:
|
|
255
|
+
"""Set equality through :func:`_scalar_eq` (field elements first), for lists of record
|
|
256
|
+
references: every target matches some element and every element matches some target."""
|
|
257
|
+
return all(any(_scalar_eq(x, y) for x in a) for y in b) and all(
|
|
258
|
+
any(_scalar_eq(x, y) for y in b) for x in a
|
|
259
|
+
)
|
|
260
|
+
|
|
261
|
+
|
|
201
262
|
def _neq(a: Any, b: Any) -> bool:
|
|
202
263
|
"""Not equal operator with array membership support."""
|
|
203
264
|
if a is None:
|
|
@@ -205,6 +266,8 @@ def _neq(a: Any, b: Any) -> bool:
|
|
|
205
266
|
|
|
206
267
|
if isinstance(a, list):
|
|
207
268
|
if isinstance(b, list):
|
|
269
|
+
if any(isinstance(x, EntityName) for x in a):
|
|
270
|
+
return not _same_members(a, b)
|
|
208
271
|
try:
|
|
209
272
|
return set(a) != set(b)
|
|
210
273
|
except TypeError:
|
|
@@ -12,6 +12,7 @@ from .field_resolve_utils import (
|
|
|
12
12
|
resolve_location,
|
|
13
13
|
resolve_person,
|
|
14
14
|
)
|
|
15
|
+
from .models.entities import FieldValues
|
|
15
16
|
from .models.types import FieldValueType, ResolveMode
|
|
16
17
|
|
|
17
18
|
__all__ = ["AmbiguousFieldError", "FieldResolver"]
|
|
@@ -20,6 +21,7 @@ if TYPE_CHECKING:
|
|
|
20
21
|
from .models.entities import (
|
|
21
22
|
Company,
|
|
22
23
|
FieldMetadata,
|
|
24
|
+
ListEntry,
|
|
23
25
|
ListEntryWithEntity,
|
|
24
26
|
Opportunity,
|
|
25
27
|
Person,
|
|
@@ -27,6 +29,25 @@ if TYPE_CHECKING:
|
|
|
27
29
|
from .models.types import AnyFieldId
|
|
28
30
|
|
|
29
31
|
|
|
32
|
+
def _field_values(
|
|
33
|
+
entity: Company | Person | Opportunity | ListEntry | ListEntryWithEntity,
|
|
34
|
+
) -> FieldValues:
|
|
35
|
+
"""
|
|
36
|
+
The field values to read: the entity's own, or, for a list entry fetched without its
|
|
37
|
+
list fields, those of the embedded entity when they were requested. A ``ListEntry``
|
|
38
|
+
from ``get_list_entries()`` has no embedded entity (``entity`` is None), so it reads
|
|
39
|
+
its own fields.
|
|
40
|
+
"""
|
|
41
|
+
inner_fields = getattr(getattr(entity, "entity", None), "fields", None)
|
|
42
|
+
if (
|
|
43
|
+
not entity.fields.requested
|
|
44
|
+
and isinstance(inner_fields, FieldValues)
|
|
45
|
+
and inner_fields.requested
|
|
46
|
+
):
|
|
47
|
+
return inner_fields
|
|
48
|
+
return entity.fields
|
|
49
|
+
|
|
50
|
+
|
|
30
51
|
class AmbiguousFieldError(Exception):
|
|
31
52
|
"""Raised when find_field() matches multiple fields and disambiguation is needed."""
|
|
32
53
|
|
|
@@ -97,7 +118,7 @@ class FieldResolver:
|
|
|
97
118
|
|
|
98
119
|
def get(
|
|
99
120
|
self,
|
|
100
|
-
entity: Company | Person | Opportunity | ListEntryWithEntity,
|
|
121
|
+
entity: Company | Person | Opportunity | ListEntry | ListEntryWithEntity,
|
|
101
122
|
field_name: str,
|
|
102
123
|
*,
|
|
103
124
|
resolve: ResolveMode = ResolveMode.RAW,
|
|
@@ -123,17 +144,8 @@ class FieldResolver:
|
|
|
123
144
|
>>> stage = resolver.get(opportunity, "Stage", resolve=ResolveMode.TEXT)
|
|
124
145
|
>>> print(stage) # "Negotiation" instead of 12345
|
|
125
146
|
"""
|
|
126
|
-
|
|
127
|
-
if
|
|
128
|
-
hasattr(entity, "entity")
|
|
129
|
-
and entity.entity is not None
|
|
130
|
-
and hasattr(entity.entity, "fields")
|
|
131
|
-
and not entity.fields.requested
|
|
132
|
-
and entity.entity.fields.requested
|
|
133
|
-
):
|
|
134
|
-
entity = entity.entity
|
|
135
|
-
|
|
136
|
-
if not entity.fields.requested:
|
|
147
|
+
fields = _field_values(entity)
|
|
148
|
+
if not fields.requested:
|
|
137
149
|
warnings.warn(
|
|
138
150
|
"Fields were not requested for this entity. "
|
|
139
151
|
"Pass field_ids or field_types when fetching to populate field values.",
|
|
@@ -146,7 +158,7 @@ class FieldResolver:
|
|
|
146
158
|
if field is None:
|
|
147
159
|
return None
|
|
148
160
|
|
|
149
|
-
value =
|
|
161
|
+
value = fields.get_value(str(field.id))
|
|
150
162
|
|
|
151
163
|
if resolve == ResolveMode.TEXT and value is not None:
|
|
152
164
|
value = self._resolve_value(value, field.value_type)
|
|
@@ -155,7 +167,7 @@ class FieldResolver:
|
|
|
155
167
|
|
|
156
168
|
def get_many(
|
|
157
169
|
self,
|
|
158
|
-
entity: Company | Person | Opportunity | ListEntryWithEntity,
|
|
170
|
+
entity: Company | Person | Opportunity | ListEntry | ListEntryWithEntity,
|
|
159
171
|
field_names: Sequence[str],
|
|
160
172
|
*,
|
|
161
173
|
resolve: ResolveMode = ResolveMode.RAW,
|
|
@@ -284,7 +296,7 @@ class FieldResolver:
|
|
|
284
296
|
|
|
285
297
|
def get_by_id(
|
|
286
298
|
self,
|
|
287
|
-
entity: Company | Person | Opportunity | ListEntryWithEntity,
|
|
299
|
+
entity: Company | Person | Opportunity | ListEntry | ListEntryWithEntity,
|
|
288
300
|
field_id: str | AnyFieldId,
|
|
289
301
|
*,
|
|
290
302
|
resolve: ResolveMode = ResolveMode.RAW,
|
|
@@ -300,18 +312,8 @@ class FieldResolver:
|
|
|
300
312
|
Returns:
|
|
301
313
|
The extracted field value, or None if not found.
|
|
302
314
|
"""
|
|
303
|
-
# Delegate to inner entity for ListEntryWithEntity
|
|
304
|
-
if (
|
|
305
|
-
hasattr(entity, "entity")
|
|
306
|
-
and entity.entity is not None
|
|
307
|
-
and hasattr(entity.entity, "fields")
|
|
308
|
-
and not entity.fields.requested
|
|
309
|
-
and entity.entity.fields.requested
|
|
310
|
-
):
|
|
311
|
-
entity = entity.entity
|
|
312
|
-
|
|
313
315
|
field_id_str = str(field_id)
|
|
314
|
-
value = entity.
|
|
316
|
+
value = _field_values(entity).get_value(field_id_str)
|
|
315
317
|
if resolve == ResolveMode.TEXT and value is not None:
|
|
316
318
|
field = self._by_id.get(field_id_str)
|
|
317
319
|
value_type = field.value_type if field else None
|
|
@@ -273,7 +273,7 @@ Options:
|
|
|
273
273
|
- `--query <term>` / `-q <term>`: free-text search (name or email)
|
|
274
274
|
- `--field <id-or-name>` (repeatable): field ID or name to include
|
|
275
275
|
- `--field-type <type>` (repeatable): field type to include (global, enriched, relationship-intelligence)
|
|
276
|
-
- `--filter <expression
|
|
276
|
+
- `--filter <expression>` (repeatable, values ANDed): filter expression; must include a condition on a person field (Affinity's search applies it)
|
|
277
277
|
- `--page-size`, `--cursor`, `--max-results`, `--all`: pagination options
|
|
278
278
|
- `--csv`: output as CSV (to stdout)
|
|
279
279
|
- `--csv-bom`: add UTF-8 BOM for Excel compatibility
|
|
@@ -456,7 +456,7 @@ Options:
|
|
|
456
456
|
- `--query <term>` / `-q <term>`: free-text search (name or domain)
|
|
457
457
|
- `--field <id-or-name>` (repeatable): field ID or name to include
|
|
458
458
|
- `--field-type <type>` (repeatable): field type to include (global, enriched, relationship-intelligence)
|
|
459
|
-
- `--filter <expression
|
|
459
|
+
- `--filter <expression>` (repeatable, values ANDed): filter expression; must include a condition on a company field (Affinity's search applies it)
|
|
460
460
|
- `--page-size`, `--cursor`, `--max-results`, `--all`: pagination options
|
|
461
461
|
- `--csv`: output as CSV (to stdout)
|
|
462
462
|
- `--csv-bom`: add UTF-8 BOM for Excel compatibility
|
|
@@ -838,7 +838,7 @@ Options:
|
|
|
838
838
|
- `--csv-bom`: add UTF-8 BOM for Excel compatibility
|
|
839
839
|
- `--field <id-or-name>` (repeatable): include specific fields
|
|
840
840
|
- `--saved-view <name>`: use a saved view's field selection (server-side filtering)
|
|
841
|
-
- `--filter <expression
|
|
841
|
+
- `--filter <expression>` (repeatable, values ANDed): filter expression; Affinity's search applies what it can, the rest runs locally (see below)
|
|
842
842
|
- `--company-id <id>` (repeatable): entity-scoped export — return only rows where the entry is for this company
|
|
843
843
|
- `--person-id <id>` (repeatable): entity-scoped export — return only rows where the entry is for this person
|
|
844
844
|
- `--first-page-only`: fetch a single page of results; output includes `meta.truncated=true` and `meta.truncationReason="firstPageOnly"` when there are more pages
|
|
@@ -120,6 +120,10 @@ multi_region = entries.list(
|
|
|
120
120
|
For CLI or advanced SDK use, you can use raw filter strings: the `--filter` text of
|
|
121
121
|
`list export`, `company ls` and `person ls`, and `affinity.filters.parse()` in the SDK.
|
|
122
122
|
|
|
123
|
+
`--filter` (and `--expand-filter`) can be repeated: the values are ANDed, so
|
|
124
|
+
`--filter 'Status = "Active"' --filter 'Region = "US"'` is `(Status = "Active") & (Region = "US")`.
|
|
125
|
+
Each value must be a complete expression; for OR, use `|` inside one value.
|
|
126
|
+
|
|
123
127
|
### Standard Operators
|
|
124
128
|
|
|
125
129
|
These operators work in every `--filter` and in `affinity.filters`:
|
|
@@ -184,7 +188,8 @@ Human/LLM-friendly aliases for official operators:
|
|
|
184
188
|
- **`starts_word`**: a word in the value starts with the text, case-insensitive, the way
|
|
185
189
|
Affinity's search matches names. `"Jan"` matches "Jane Doe" and "Mary-Jane"; `"ane"`
|
|
186
190
|
doesn't. JSON spelling in `query`: `{"path": "fields.Owner", "op": "starts_word", "value": "Jan"}`.
|
|
187
|
-
- **Person and company fields** are compared by name ("Jane Doe", "Acme")
|
|
191
|
+
- **Person and company fields** are compared by name ("Jane Doe", "Acme"), or by id when the value is a number
|
|
192
|
+
(`Owner = 26229794`: that person's id; a value with no name can't match by id). In `--filter`
|
|
188
193
|
and `query`, `contains` (and `contains_any` / `contains_all`) on a person or company
|
|
189
194
|
field is refused: use `starts_word`.
|
|
190
195
|
- **Empty multi-value fields**: a multi-value field with no items counts as empty.
|
|
@@ -228,6 +233,9 @@ xaffinity list export Pipeline --filter 'Region = "US" | Region = "Canada"'
|
|
|
228
233
|
# A person field by name
|
|
229
234
|
xaffinity list export Pipeline --filter 'Owner starts_word "Jan"'
|
|
230
235
|
|
|
236
|
+
# A person field by id
|
|
237
|
+
xaffinity list export Pipeline --filter 'Owner = 26229794' --all
|
|
238
|
+
|
|
231
239
|
# Null check
|
|
232
240
|
xaffinity list export Pipeline --filter 'Owner != *'
|
|
233
241
|
|
|
@@ -185,7 +185,7 @@ Example: {"from": "persons", "include": ["interactions"]}
|
|
|
185
185
|
| `has_any` | Array contains any of the values | `["LB", "MA"]` |
|
|
186
186
|
| `has_all` | Array contains all of the values | `["LB", "MA"]` |
|
|
187
187
|
|
|
188
|
-
`starts_word` matches the way Affinity's search matches names: `"Jan"` matches "Jane Doe" and "Mary-Jane"; `"ane"` doesn't. Person and company field values are compared by name ("Jane Doe", "Acme"), and `contains` / `contains_any` / `contains_all` on a person or company field is refused: use `starts_word`. An empty multi-value field (no items) counts as empty: `is_null` matches it, `is_not_null` doesn't.
|
|
188
|
+
`starts_word` matches the way Affinity's search matches names: `"Jan"` matches "Jane Doe" and "Mary-Jane"; `"ane"` doesn't. Person and company field values are compared by name ("Jane Doe", "Acme"), or by id when the value is a number (`{"path": "fields.Owner", "op": "eq", "value": 26229794}`), and `contains` / `contains_any` / `contains_all` on a person or company field is refused: use `starts_word`. An empty multi-value field (no items) counts as empty: `is_null` matches it, `is_not_null` doesn't.
|
|
189
189
|
|
|
190
190
|
The `--filter` text of `list export`, `company ls` and `person ls` is the same filter language: every condition means the same in both spellings.
|
|
191
191
|
|
|
@@ -146,7 +146,7 @@ Example: {"from": "persons", "include": ["interactions"]}
|
|
|
146
146
|
| `starts_with` | Starts with prefix (case-insensitive) | string |
|
|
147
147
|
| `starts_word` | A word in the value starts with the text (case-insensitive) | string |
|
|
148
148
|
|
|
149
|
-
`starts_word` matches the way Affinity's search matches names: `"Jan"` matches "Jane Doe" and "Mary-Jane"; `"ane"` doesn't. Person and company field values are compared by name ("Jane Doe", "Acme"); `contains`, `contains_any` and `contains_all` on a person or company field are refused (use `starts_word`).
|
|
149
|
+
`starts_word` matches the way Affinity's search matches names: `"Jan"` matches "Jane Doe" and "Mary-Jane"; `"ane"` doesn't. Person and company field values are compared by name ("Jane Doe", "Acme"), or by id when the value is a number (`{"path": "fields.Owner", "op": "eq", "value": 26229794}`); `contains`, `contains_any` and `contains_all` on a person or company field are refused (use `starts_word`).
|
|
150
150
|
|
|
151
151
|
#### Collection
|
|
152
152
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "affinity-crm-mcp-unofficial",
|
|
3
3
|
"description": "Affinity CRM workflows for Claude \u2014 meeting prep, pipeline review, warm intros, interaction logging, and relationship intelligence",
|
|
4
|
-
"version": "2.0.
|
|
4
|
+
"version": "2.0.8",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Yaniv Golan",
|
|
7
7
|
"email": "yaniv@golan.name"
|
|
@@ -106,7 +106,7 @@ Structured query language for the `query` MCP tool. For simple lookups, prefer `
|
|
|
106
106
|
Common operators: `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `starts_with`, `starts_word`, `in`, `between`, `is_null`, `is_not_null`, `has_any`, `has_all`
|
|
107
107
|
|
|
108
108
|
- `starts_word`: a word in the value starts with the text, case-insensitive, the way Affinity's search matches names (`"Jan"` matches "Jane Doe" and "Mary-Jane"; `"ane"` doesn't).
|
|
109
|
-
- Person and company field values are compared by name ("Jane Doe", "Acme"). `contains` / `contains_any` / `contains_all` on them is refused: use `starts_word`.
|
|
109
|
+
- Person and company field values are compared by name ("Jane Doe", "Acme"), or by id when the value is a number. `contains` / `contains_any` / `contains_all` on them is refused: use `starts_word`.
|
|
110
110
|
- An empty multi-value field counts as empty: `is_null` matches it, `is_not_null` doesn't.
|
|
111
111
|
- Name any field by id with `fields.<field id>` (e.g. `fields.affinity-data-year-founded`). When two list fields share a name (e.g. Affinity's and Dealroom's "Year Founded"), `fields.<name>` is refused with an error listing the ids; use the id. Such fields come back keyed by id.
|
|
112
112
|
|
|
@@ -23,7 +23,7 @@ Complete reference for all filter operators in the Affinity query language.
|
|
|
23
23
|
|
|
24
24
|
`starts_word` matches the way Affinity's search matches names: `"Jan"` matches "Jane Doe" and "Mary-Jane"; `"ane"` doesn't.
|
|
25
25
|
|
|
26
|
-
Person and company field values are compared by name ("Jane Doe", "Acme"). `contains`, `contains_any` and `contains_all` on a person or company field are refused: use `starts_word`.
|
|
26
|
+
Person and company field values are compared by name ("Jane Doe", "Acme"), or by id when the value is a number. `contains`, `contains_any` and `contains_all` on a person or company field are refused: use `starts_word`.
|
|
27
27
|
|
|
28
28
|
## Collection Operators
|
|
29
29
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1.9.6
|